diff -r 02c04d2c8fd8 -r ac1eacb3aa33 src/widgets/AnnotationsList.js --- a/src/widgets/AnnotationsList.js Sun Nov 12 22:07:33 2017 +0100 +++ b/src/widgets/AnnotationsList.js Wed Sep 04 17:32:50 2024 +0200 @@ -1,156 +1,173 @@ -IriSP.Widgets.AnnotationsList = function(player, config) { - IriSP.Widgets.Widget.call(this, player, config); - this.lastIds = []; - var _this = this; - this.throttledRefresh = IriSP._.throttle(function(full) { +import annotationsListStyles from "./AnnotationsList.module.css"; + +import Mustache from "mustache"; +import _ from "lodash"; +import jQuery from "jquery"; + +const AnnotationsList = function (ns) { + return class extends ns.Widgets.Widget { + constructor(player, config) { + super(player, config); + this.lastIds = []; + var _this = this; + this.throttledRefresh = _.throttle(function (full) { _this.refresh(full); - }, 800); - this.searchString = false; - this.lastSearch = false; - this.localSource = undefined; -}; + }, 800); + this.searchString = false; + this.lastSearch = false; + this.localSource = undefined; + } -IriSP.Widgets.AnnotationsList.prototype = new IriSP.Widgets.Widget(); - -IriSP.Widgets.AnnotationsList.prototype.defaults = { - pre_draw_callback: function(){ + static defaults = { + pre_draw_callback: function () { return this.importUsers(); - }, - /* - * URL when the annotations are to be reloaded from an LDT-like segment API - * e.g. - * http://ldt.iri.centrepompidou.fr/ldtplatform/api/ldt/segments/{{media}}/{{begin}}/{{end}}?callback=? - */ - ajax_url : false, - /* - * number of milliseconds before/after the current timecode when calling the - * segment API - */ - ajax_granularity : 600000, - default_thumbnail : "", - custom_external_icon : "", - /* - * URL when the annotation is not in the current project, e.g. - * http://ldt.iri.centrepompidou.fr/ldtplatform/ldt/front/player/{{media}}/{{project}}/{{annotationType}}#id={{annotation}} - */ - foreign_url : "", - annotation_type : false, - refresh_interval : 0, - limit_count : 20, - newest_first : false, - show_title: true, - show_audio: true, - show_creator: true, - show_controls: false, - show_end_time: true, - show_publish: false, - show_twitter: false, - twitter_hashtag: '', - // Callback for Edit action. Leave undefined for default action. - on_edit: undefined, - publish_type: "PublicContribution", - // Used to publish annotations - api_endpoint_template: "", - api_serializer: "ldt_annotate", - api_method: "POST", - editable: false, - // Id that will be used as localStorage key - editable_storage: "", - widget_max_height: 680, - always_visible : false, - start_visible: true, - show_audio : true, - show_filters : false, - keyword_filter: true, - date_filter: true, - user_filter: true, - segment_filter: true, - latest_contributions_filter: false, - current_day_filter: true, - show_header : false, - custom_header : false, - annotations_count_header : true, - annotations_count_header_string: "annotations", - show_creation_date : false, - show_timecode : true, - show_end_time : true, - project_id: "", - /* - * Only annotation in the current segment will be displayed. Designed to work with the Segments Widget. - */ - allow_annotations_deletion: false, - /* - * URL to call when deleting annotation. Expects a mustache template with {{annotation_id}}, ex /api/anotations/{{annotation_id}}/ - */ - api_delete_endpoint : "", - api_delete_method: "DELETE", - api_users_endpoint: "", - api_users_method: "GET", - make_name_string_function: function(params){ + }, + /* + * URL when the annotations are to be reloaded from an LDT-like segment API + * e.g. + * http://ldt.iri.centrepompidou.fr/ldtplatform/api/ldt/segments/{{media}}/{{begin}}/{{end}}?callback=? + */ + ajax_url: false, + /* + * number of milliseconds before/after the current timecode when calling the + * segment API + */ + ajax_granularity: 600000, + default_thumbnail: "", + custom_external_icon: "", + /* + * URL when the annotation is not in the current project, e.g. + * http://ldt.iri.centrepompidou.fr/ldtplatform/ldt/front/player/{{media}}/{{project}}/{{annotationType}}#id={{annotation}} + */ + foreign_url: "", + annotation_type: false, + refresh_interval: 0, + limit_count: 20, + newest_first: false, + show_title: true, + show_audio: true, + show_creator: true, + show_controls: false, + show_end_time: true, + show_publish: false, + show_twitter: false, + twitter_hashtag: "", + // Callback for Edit action. Leave undefined for default action. + on_edit: undefined, + publish_type: "PublicContribution", + // Used to publish annotations + api_endpoint_template: "", + api_serializer: "ldt_annotate", + api_method: "POST", + editable: false, + // Id that will be used as localStorage key + editable_storage: "", + widget_max_height: 680, + always_visible: false, + start_visible: true, + show_audio: true, + show_filters: false, + keyword_filter: true, + date_filter: true, + user_filter: true, + segment_filter: true, + latest_contributions_filter: false, + current_day_filter: true, + show_header: false, + custom_header: false, + annotations_count_header: true, + annotations_count_header_string: "annotations", + show_creation_date: false, + show_timecode: true, + show_end_time: true, + project_id: "", + /* + * Only annotation in the current segment will be displayed. Designed to work with the Segments Widget. + */ + allow_annotations_deletion: false, + /* + * URL to call when deleting annotation. Expects a mustache template with {{annotation_id}}, ex /api/anotations/{{annotation_id}}/ + */ + api_delete_endpoint: "", + api_delete_method: "DELETE", + api_users_endpoint: "", + api_users_method: "GET", + make_name_string_function: function (params) { return params.username ? params.username : "Anonymous"; - }, - filter_by_segments: false, - segment_filter: true, - segments_annotation_type: "chap", - /* - * Set to a username if you only want to display annotations from a given user - */ - show_only_annotation_from_user: false, - /* - * Show a text field that filter annotations by username - */ - tags : true, + }, + filter_by_segments: false, + segment_filter: true, + segments_annotation_type: "chap", + /* + * Set to a username if you only want to display annotations from a given user + */ + show_only_annotation_from_user: false, + /* + * Show a text field that filter annotations by username + */ + tags: true, - polemics : [{ - keyword: "++", - background_color: "#c9ecc6" - },{ - keyword: "--", - background_color: "#f9c5c6" - },{ - keyword: "??", - background_color: "#cec5f9" - },{ - keyword: "==", - background_color: "#f9f4c6" - }] -}; + polemics: [ + { + keyword: "++", + background_color: "#c9ecc6", + }, + { + keyword: "--", + background_color: "#f9c5c6", + }, + { + keyword: "??", + background_color: "#cec5f9", + }, + { + keyword: "==", + background_color: "#f9f4c6", + }, + ], + }; -IriSP.Widgets.AnnotationsList.prototype.importUsers = function(){ - if (!this.source.users_data && this.api_users_endpoint){ + importUsers() { + if (!this.source.users_data && this.api_users_endpoint) { this.usernames = Array(); var _this = this, - _list = this.getWidgetAnnotations(), - usernames_list_string = ""; + _list = this.getWidgetAnnotations(), + usernames_list_string = ""; - _list.forEach(function(_annotation){ - if(_this.usernames.indexOf(_annotation.creator) == -1){ - _this.usernames.push(_annotation.creator); - } + _list.forEach(function (_annotation) { + if (_this.usernames.indexOf(_annotation.creator) == -1) { + _this.usernames.push(_annotation.creator); + } + }); + this.usernames.forEach(function (_username) { + usernames_list_string += _username + ","; + }); + usernames_list_string = usernames_list_string.substring( + 0, + usernames_list_string.length - 1 + ); + _url = Mustache.render(this.api_users_endpoint, { + usernames_list_string: encodeURIComponent(usernames_list_string), + usernames_list_length: this.usernames.length, }); - this.usernames.forEach(function(_username){ - usernames_list_string+=_username+"," - }) - usernames_list_string = usernames_list_string.substring(0, usernames_list_string.length - 1); - _url = Mustache.to_html(this.api_users_endpoint, {usernames_list_string: encodeURIComponent(usernames_list_string), usernames_list_length: this.usernames.length}); - return IriSP.jQuery.ajax({ - async: false, - url: _url, - type: "GET", - success: function(_data) { - _this.source.users_data = _data.objects - }, - error: function(_xhr, _error, _thrown) { - console.log(_xhr) - console.log(_error) - console.log(_thrown) - } - }) + return jQuery.ajax({ + async: false, + url: _url, + type: "GET", + success: function (_data) { + _this.source.users_data = _data.objects; + }, + error: function (_xhr, _error, _thrown) { + console.log(_xhr); + console.log(_error); + console.log(_thrown); + }, + }); + } } -} -IriSP.Widgets.AnnotationsList.prototype.messages = { - en: { + static messages = { + en: { voice_annotation: "Voice Annotation", now_playing: "Now playing...", previous: "Previous", @@ -159,9 +176,12 @@ edit_annotation: "Edit note", delete_annotation: "Delete note", publish_annotation: "Make note public", - import_annotations: "Paste or load notes in this field and press Import.", - confirm_delete_message: "You are about to delete {{ annotation.title }}. Are you sure you want to delete it?", - confirm_publish_message: "You are about to publish {{ annotation.title }}. Are you sure you want to make it public?", + import_annotations: + "Paste or load notes in this field and press Import.", + confirm_delete_message: + "You are about to delete {{ annotation.title }}. Are you sure you want to delete it?", + confirm_publish_message: + "You are about to publish {{ annotation.title }}. Are you sure you want to make it public?", tweet_annotation: "Tweet annotation", external_annotation: "This annotation was submitted to another project", everyone: "Everyone", @@ -174,9 +194,10 @@ annotation_deletion_delete: "You will delete this annotation", annotation_deletion_sending: "Your deletion request is being sent ... ", annotation_deletion_success: "The annotation has been deleted.", - annotation_deletion_error: "There was an error contacting the server. The annotation has not been deleted." - }, - fr: { + annotation_deletion_error: + "There was an error contacting the server. The annotation has not been deleted.", + }, + fr: { voice_annotation: "Annotation Vocale", now_playing: "Lecture en cours...", previous: "Précédent", @@ -185,11 +206,15 @@ edit_annotation: "Éditer la note", delete_annotation: "Supprimer la note", publish_annotation: "Rendre la note publique", - import_annotations: "Copiez ou chargez des notes dans ce champ et appuyez sur Import", - confirm_delete_message: "Vous allez supprimer {{ annotation.title }}. Êtes-vous certain(e) ?", - confirm_publish_message: "Vous allez publier {{ annotation.title }}. Êtes-vous certain(e) ?", + import_annotations: + "Copiez ou chargez des notes dans ce champ et appuyez sur Import", + confirm_delete_message: + "Vous allez supprimer {{ annotation.title }}. Êtes-vous certain(e) ?", + confirm_publish_message: + "Vous allez publier {{ annotation.title }}. Êtes-vous certain(e) ?", tweet_annotation: "Tweeter l'annotation", - external_annotation: "Cette annotation a été postée sur un autre projet", + external_annotation: + "Cette annotation a été postée sur un autre projet", everyone: "Tous", header: "Annotations sur ce contenu", segment_filter: "Tous les segments", @@ -198,1017 +223,1217 @@ confirm: "Confirmer", cancel: "Annuler", annotation_deletion_delete: "Vous allez supprimer cette annotation", - annotation_deletion_sending: "Votre demande de suppression est en cours d'envoi ... ", + annotation_deletion_sending: + "Votre demande de suppression est en cours d'envoi ... ", annotation_deletion_success: "L'annotation a été supprimée.", - annotation_deletion_error: "Une erreur s'est produite en contactant le serveur. L'annotation n'a pas été supprimée." - } -}; + annotation_deletion_error: + "Une erreur s'est produite en contactant le serveur. L'annotation n'a pas été supprimée.", + }, + }; -IriSP.Widgets.AnnotationsList.prototype.template = - '{{#show_header}}

' - + '{{#custom_header}}{{custom_header}}{{/custom_header}}' - + '{{^custom_header}}{{l10n.header}}{{/custom_header}}' - + '

{{/show_header}}' - + '
' - + '
' - + '{{#show_filters}}' - + '
' - + '{{#keyword_filter}}{{/keyword_filter}}' - + '{{#user_filter}}{{/user_filter}}' - + '{{#date_filter}}{{/date_filter}}' - + '{{#segment_filter}}{{/segment_filter}}' - + '{{#latest_contributions_filter}}{{/latest_contributions_filter}}' - + '
' - + '{{/show_filters}}' - + '{{#show_controls}}
{{ l10n.previous }} | {{ l10n.next }}
{{/show_controls}}' - + '{{#show_audio}}
{{/show_audio}}' - + '' - + '
' - + '{{#allow_annotations_deletion}}' - + '
' - + '' - + '{{l10n.annotation_deletion_delete}}' - + '' - + '{{l10n.confirm}} {{l10n.cancel}}' - + '
' - + '
' - + '' - + '{{l10n.annotation_deletion_sending}}' - + '
' - + '
' - + '' - + '{{l10n.annotation_deletion_success}}' - + '
' - + '
' - + '' - + '{{l10n.annotation_deletion_error}}' - + '
' - + '{{/allow_annotations_deletion}}' - + '
'; + static template = + '{{#show_header}}

' + + "{{#custom_header}}{{custom_header}}{{/custom_header}}" + + "{{^custom_header}}{{l10n.header}}{{/custom_header}}" + + "

{{/show_header}}" + + '
' + + '
' + + "{{#show_filters}}" + + '
' + + '{{#keyword_filter}}{{/keyword_filter}}' + + '{{#user_filter}}{{/user_filter}}' + + '{{#date_filter}}{{/date_filter}}' + + '{{#segment_filter}}{{/segment_filter}}' + + '{{#latest_contributions_filter}}{{/latest_contributions_filter}}' + + "
" + + "{{/show_filters}}" + + '{{#show_controls}}
{{ l10n.previous }} | {{ l10n.next }}
{{/show_controls}}' + + '{{#show_audio}}
{{/show_audio}}' + + '" + + "
" + + "{{#allow_annotations_deletion}}" + + '
' + + '' + + "{{l10n.annotation_deletion_delete}}" + + '' + + '{{l10n.confirm}} {{l10n.cancel}}' + + "
" + + '
' + + '' + + "{{l10n.annotation_deletion_sending}}" + + "
" + + '
' + + '' + + "{{l10n.annotation_deletion_success}}" + + "
" + + '
' + + '' + + "{{l10n.annotation_deletion_error}}" + + "
" + + "{{/allow_annotations_deletion}}" + + "
"; -IriSP.Widgets.AnnotationsList.prototype.annotationTemplate = - '
  • ' - + '
    ' - + '' - + '' - + '{{#external}}
    {{/external}}' - + '
    ' - + '
    ' - + '{{#allow_annotations_deletion}}' - + '
    ' - + '{{/allow_annotations_deletion}}' - + '{{#show_timecode}}
    {{begin}}{{#show_end_time}} - {{end}}{{/show_end_time}}
    {{/show_timecode}}' - + '

    ' - + '{{#show_title}}{{{htitle}}}{{/show_title}}' - + '{{#show_creator}}{{ creator }}{{/show_creator}}' - + '

    ' - + '

    {{{hdescription}}}

    ' - + '{{#created}}' - + '
    {{{created}}}
    ' - + '{{/created}}' - + '{{#tags.length}}' - + '' - + '{{/tags.length}}' - + '{{#audio}}
    {{l10n.voice_annotation}}
    {{/audio}}' - + '
    ' - + '{{#show_twitter}}{{/show_twitter}}' - + '{{#show_publish}}
    {{/show_publish}}' - + '{{#editable}}
    ' - + '
    {{/editable}}' - + '
    ' - + '
  • '; + static annotationTemplate = + '
  • ' + + '
    ' + + '' + + '' + + '{{#external}}
    {{/external}}' + + "
    " + + "
    " + + "{{#allow_annotations_deletion}}" + + '
    ' + + "{{/allow_annotations_deletion}}" + + '{{#show_timecode}}
    {{begin}}{{#show_end_time}} - {{end}}{{/show_end_time}}
    {{/show_timecode}}' + + '

    ' + + '{{#show_title}}{{{htitle}}}{{/show_title}}' + + '{{#show_creator}}{{ creator }}{{/show_creator}}' + + "

    " + + '

    {{{hdescription}}}

    ' + + "{{#created}}" + + '
    {{{created}}}
    ' + + "{{/created}}" + + "{{#tags.length}}" + + '" + + "{{/tags.length}}" + + '{{#audio}}
    {{l10n.voice_annotation}}
    {{/audio}}' + + '
    ' + + '{{#show_twitter}}{{/show_twitter}}' + + '{{#show_publish}}
    {{/show_publish}}' + + '{{#editable}}
    ' + + '
    {{/editable}}' + + "
    " + + "
  • "; -// obj.url = this.project_url + "/" + media + "/" + annotations[i].meta.project -// + "/" + annotations[i].meta["id-ref"] + '#id=' + annotations[i].id; + // obj.url = this.project_url + "/" + media + "/" + annotations[i].meta.project + // + "/" + annotations[i].meta["id-ref"] + '#id=' + annotations[i].id; -IriSP.Widgets.AnnotationsList.prototype.ajaxSource = function() { - var _currentTime = this.media.getCurrentTime(), + ajaxSource() { + var _currentTime = this.media.getCurrentTime(), _duration = this.media.duration; - this.lastAjaxQuery = _currentTime; - var _url = Mustache.to_html(this.ajax_url, { - media : this.source.currentMedia.id, - begin : Math.max(0, _currentTime - this.ajax_granularity), - end : Math.min(_duration.milliseconds, _currentTime + this.ajax_granularity) - }); - this.currentSource = this.player.loadMetadata(IriSP._.defaults({ - "url" : _url - }, this.metadata)); -}; + this.lastAjaxQuery = _currentTime; + var _url = Mustache.render(this.ajax_url, { + media: this.source.currentMedia.id, + begin: Math.max(0, _currentTime - this.ajax_granularity), + end: Math.min( + _duration.milliseconds, + _currentTime + this.ajax_granularity + ), + }); + this.currentSource = this.player.loadMetadata( + _.defaults( + { + url: _url, + }, + this.metadata + ) + ); + } -IriSP.Widgets.AnnotationsList.prototype.showScreen = function(_screenName) { - this.$.find('.Ldt-AnnotationsList-Screen' + _screenName).show() - .siblings().hide(); -} + showScreen(_screenName) { + this.$.find(".Ldt-AnnotationsList-Screen" + _screenName) + .show() + .siblings() + .hide(); + } -IriSP.Widgets.AnnotationsList.prototype.ajaxMashup = function() { - var _currentTime = this.media.getCurrentTime(); - var _currentAnnotation = this.source.currentMedia.getAnnotationAtTime(_currentTime); - if (typeof _currentAnnotation !== "undefined" && _currentAnnotation.id !== this.lastMashupAnnotation) { + ajaxMashup() { + var _currentTime = this.media.getCurrentTime(); + var _currentAnnotation = + this.source.currentMedia.getAnnotationAtTime(_currentTime); + if ( + typeof _currentAnnotation !== "undefined" && + _currentAnnotation.id !== this.lastMashupAnnotation + ) { this.lastMashupAnnotation = _currentAnnotation.id; var _currentMedia = _currentAnnotation.getMedia(), - _url = Mustache.to_html(this.ajax_url, { - media : _currentMedia.id, - begin : Math.max(0, _currentAnnotation.annotation.begin.milliseconds - this.ajax_granularity), - end : Math.min(_currentMedia.duration.milliseconds, _currentAnnotation.annotation.end.milliseconds + this.ajax_granularity) - }); - this.currentSource = this.player.loadMetadata(IriSP._.defaults({ - "url" : _url - }, this.metadata)); + _url = Mustache.render(this.ajax_url, { + media: _currentMedia.id, + begin: Math.max( + 0, + _currentAnnotation.annotation.begin.milliseconds - + this.ajax_granularity + ), + end: Math.min( + _currentMedia.duration.milliseconds, + _currentAnnotation.annotation.end.milliseconds + + this.ajax_granularity + ), + }); + this.currentSource = this.player.loadMetadata( + _.defaults( + { + url: _url, + }, + this.metadata + ) + ); + } } -}; -/* - * Import annotations - */ -IriSP.Widgets.AnnotationsList.prototype.importAnnotations = function () { - var widget = this; - var $ = IriSP.jQuery; - var textarea = $("