Skip to content

Commit

Permalink
Add (sub)category class (+ superclass) to remove hardcoded categories…
Browse files Browse the repository at this point in the history
… in the (non-view) JavaScript.
  • Loading branch information
Frodo161 committed Oct 1, 2023
1 parent 9ad187d commit 7e77f80
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 73 deletions.
3 changes: 3 additions & 0 deletions app/assets/javascripts/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@
//= require thyme/components/seek_bar
//= require thyme/components/speed_selector
//= require thyme/components/volume_bar
//= require thyme/annotations/category_enum
//= require thyme/annotations/category
//= require thyme/annotations/subcategory
//= require thyme/annotations/annotation
//= require thyme/annotations/annotation_area
//= require thyme/annotations/annotation_manager
Expand Down
51 changes: 6 additions & 45 deletions app/assets/javascripts/thyme/annotations/annotation.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,19 @@ class Annotation {

constructor(json) {
// We only save attributes that are needed in the thyme related JavaScripts in the asset pipeline!
this.category = json.category;
this.category = Category.getByName(json.category);
this.color = json.color;
this.comment = json.comment;
this.id = json.id;
this.seconds = thymeUtility.timestampToSeconds(json.timestamp);
this.subcategory = json.subcategory;
this.subcategory = Subcategory.getByName(json.subcategory);
this.belongsToCurrentUser = json.belongs_to_current_user;
}



/*
* AUXILIARY METHODS
* AUXILIARY METHODS
*/

/*
Expand Down Expand Up @@ -80,48 +80,9 @@ class Annotation {
Returns a string with the correct translation of the category and subcategory of this annotation.
*/
categoryLocale() {
let c, s;
switch (this.category) {
case "note":
c = document.getElementById('annotation-locales').dataset.note;
break;
case "content":
c = document.getElementById('annotation-locales').dataset.content;
break;
case "mistake":
c = document.getElementById('annotation-locales').dataset.mistake;
break;
case "presentation":
c = document.getElementById('annotation-locales').dataset.presentation;
}
if (this.subcategory === null) {
return c;
}
switch (this.subcategory) {
case "definition":
s = document.getElementById('annotation-locales').dataset.definition;
break;
case "argument":
s = document.getElementById('annotation-locales').dataset.argument;
break;
case "strategy":
s = document.getElementById('annotation-locales').dataset.strategy;
}
return c + " (" + s + ")";
}

/* Returns a fixed color depending only on the category of the annotation. */
categoryColor() {
switch (this.category) {
case "note":
return "#44ee11"; //green
case "content":
return "#eeee00"; //yellow
case "mistake":
return "#ff0000"; //red
case "presentation":
return "#ff9933"; //orange
}
const c = this.category;
const s = this.subcategory;
return s == null ? c.locale() : c.locale() + " (" + s.locale() + ")";
}

/*
Expand Down
24 changes: 24 additions & 0 deletions app/assets/javascripts/thyme/annotations/category.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
class Category extends CategoryEnum {

static _categories = [];

static NOTE = new Category('note', '#44ee11'); //green
static CONTENT = new Category('content', '#eeee00'); //yellow
static PRESENTATION = new Category('presentation', '#ff9933'); //orange
static MISTAKE = new Category('mistake', '#ff0000'); //red

constructor(name, color) {
super(name);
this.color = color;
Category._categories.push(this);
}

static getByName(name) {
return super.getByName(name, Category._categories);
}

static all() {
return super.all(Category._categories);
}

}
40 changes: 40 additions & 0 deletions app/assets/javascripts/thyme/annotations/category_enum.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
class CategoryEnum {

constructor(name) {
this.name = name;
}

/*
* Returns the correct locale for the given category.
* This method will only work if the given thyme player
* has a div-tag with the id "annotation-locales" which
* includes the name of the categories as data sets, e.g.
* data-note="<%= t(...) %>".
*/
locale() {
return document.getElementById('annotation-locales').dataset[this.name];
}

/*
* Return the object with the given name in the given array.
*
* Override in subclasses.
*/
static getByName(name, array) {
for (let a of array) {
if (a.name === name) {
return a;
}
}
}

/*
* Returns an array with all objects of this enum.
*
* Override in subclasses.
*/
static all(array) {
return array.slice();
}

}
22 changes: 22 additions & 0 deletions app/assets/javascripts/thyme/annotations/subcategory.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
class Subcategory extends CategoryEnum {

static _subcategories = []; // do not manipulate this array outside of this class!

static DEFINITION = new Subcategory('definition');
static ARGUMENT = new Subcategory('argument');
static STRATEGY = new Subcategory('strategy');

constructor(name) {
super(name);
Subcategory._subcategories.push(this);
}

static getByName(name) {
return super.getByName(name, Subcategory._subcategories);
}

static all() {
return super.all(Subcategory._subcategories);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ class AnnotationCategoryToggle extends Component {

/*
element = A reference on the HTML component (via document.getElementByID()).
category = The name of the category this toggle triggers.
category = The category which this toggle triggers.
heatmap = The heatmap that will be updated depending on the value of the toggle.
*/
constructor(element, category, heatmap) {
Expand All @@ -16,6 +16,9 @@ class AnnotationCategoryToggle extends Component {
const category = this.category;
const check = document.getElementById(this.element.id + '-check');
const heatmap = this.heatmap;
if (heatmap != null) {
heatmap.addCategory(category); // add category when adding the button
}

check.addEventListener('click', function() {
thymeAttributes.annotationManager.updateAnnotations();
Expand Down
13 changes: 5 additions & 8 deletions app/assets/javascripts/thyme/heatmap.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,11 @@ class Heatmap {
static MAX_HEIGHT = 0.25 // this number adjusts the maximum heights of the heatmap peaks

/*
id = The ID of the HTML element to which the heatmap will be appended.
categories = An array which contains all the categories (i.e. the string representing
the categories) that should be displayed in the heatmap.
*/
constructor(id, categories) {
* id = The ID of the HTML element to which the heatmap will be appended.
*/
constructor(id) {
this.heatmap = $('#' + id);
this.categories = categories;
this.categories = [];
}


Expand Down Expand Up @@ -52,7 +49,7 @@ class Heatmap {
for (const a of thymeAttributes.annotations) {
const valid = this.#validCategory(a.category);
if (valid === true) {
colors.push(a.categoryColor());
colors.push(a.category.color);
}
const time = a.seconds;
const position = Math.round(width * (time / video.duration));
Expand Down
39 changes: 20 additions & 19 deletions app/assets/javascripts/thyme/thyme_feedback.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,34 +34,35 @@ $(document).on('turbolinks:load', function() {
seekBar.add();

// heatmap
const heatmap = new Heatmap('heatmap', ['presentation', 'content', 'note']);
const heatmap = new Heatmap('heatmap');

// below-area
const toggleMistakeAnnotations = new AnnotationCategoryToggle(
'toggle-mistake-annotations', 'mistake', null); // <- don't draw mistake annotations in the heatmap
const togglePresentationAnnotations = new AnnotationCategoryToggle(
'toggle-presentation-annotations', 'presentation', heatmap);
const toggleContentAnnotations = new AnnotationCategoryToggle(
'toggle-content-annotations', 'content', heatmap);
const toggleNoteAnnotations = new AnnotationCategoryToggle(
'toggle-note-annotations', 'note', heatmap);
toggleMistakeAnnotations.add();
togglePresentationAnnotations.add();
toggleContentAnnotations.add();
toggleNoteAnnotations.add();
const toggles = [toggleMistakeAnnotations, togglePresentationAnnotations,
toggleContentAnnotations, toggleNoteAnnotations];
const allCategories = Category.all();
const annotationCategoryToggles = new Array(allCategories.length);
let category;

for (let i = 0; i < allCategories.length; i++) {
category = allCategories[i];
annotationCategoryToggles[i] = new AnnotationCategoryToggle(
'toggle-' + category.name + '-annotations', category, heatmap
);
if (category === Category.MISTAKE) {
// exclude mistake annotations from heatmap
annotationCategoryToggles[i].heatmap = null;
}
annotationCategoryToggles[i].add();
}



/*
ANNOTATION FUNCTIONALITY
*/
function colorFunc(annotation) {
return annotation.categoryColor();
return annotation.category.color;
}
function isValid(annotation) {
for (let toggle of toggles) {
for (let toggle of annotationCategoryToggles) {
if (annotation.category === toggle.category && toggle.getValue() === true) {
return true;
}
Expand All @@ -71,10 +72,10 @@ $(document).on('turbolinks:load', function() {
const annotationArea = new AnnotationArea(false, colorFunc, isValid);
thymeAttributes.annotationArea = annotationArea;
function strokeColorFunc(annotation) {
return annotation.category === 'mistake' ? 'darkred' : 'black';
return annotation.category === Category.MISTAKE ? 'darkred' : 'black';
}
function sizeFunc(annotation) {
return annotation.category === 'mistake' ? true : false;
return annotation.category === Category.MISTAKE ? true : false;
}
function onClick(annotation) {
annotationArea.update(annotation);
Expand Down

0 comments on commit 7e77f80

Please sign in to comment.