/* Widget displays info on the current segment, with possibility of config for editing description and tags */
// CurrentSegmentInfobox
import currentSegmentInfoboxStyles from "./CurrentSegmentInfobox.module.css";
import Mustache from "mustache";
import _ from "lodash";
const CurrentSegmentInfobox = function (ns) {
return class extends ns.Widgets.Widget {
constructor(player, config) {
super(player, config);
}
static defaults = {
annotation_type: "chap",
editable_segments: false,
empty_message: false,
project_id: false,
api_serializer: "ldt_annotate",
api_method: "PUT",
api_endpoint_template: "",
new_tag_button: true,
show_headers: false,
custom_edit_text: false,
empty_description_placeholder: false,
};
static template =
'<div class="Ldt-CurrentSegmentInfobox">' +
'<div class="Ldt-CurrentSegmentInfobox-SelectedSegment">' +
'{{#editable_segments}}<div class="Ldt-CurrentSegmentInfobox-EditButton">{{edit}}</div>{{/editable_segments}}' +
'<div class="Ldt-CurrentSegmentInfobox-Element Ldt-CurrentSegmentInfobox-Title">{{title}}</div>' +
'<div class="Ldt-CurrentSegmentInfobox-Element Ldt-CurrentSegmentInfobox-Description">{{description}}</div>' +
'{{^description}}{{^tags.length}}{{#description_placeholder}}<div class="Ldt-CurrentSegmentInfobox-Element Ldt-CurrentSegmentInfobox-Description-placeholder">{{description_placeholder}}</div>{{/description_placeholder}}{{/tags.length}}{{/description}}' +
'<div class="Ldt-CurrentSegmentInfobox-Element Ldt-CurrentSegmentInfobox-Tags">' +
"{{#tags.length}}" +
'<ul class="Ldt-CurrentSegmentInfobox-Tags-Ul">' +
"{{#tags}}" +
"{{#.}}" +
'<li class="Ldt-CurrentSegmentInfobox-Tags-Li">' +
"<span>{{.}}</span>" +
"</li>" +
"{{/.}}" +
"{{/tags}}" +
"</ul>" +
"{{/tags.length}}" +
"</div>" +
"</div>" +
"</div>";
static editTemplate =
'<div class="Ldt-CurrentSegmentInfobox">' +
'<div class="Ldt-CurrentSegmentInfobox-SelectedSegment">' +
'{{#headers}}<div class="Ldt-CurrentSegmentInfobox-FieldsHeader">{{fields_header}}</div>{{/headers}}' +
'<input type="text" class="Ldt-CurrentSegmentInfobox-Element Ldt-CurrentSegmentInfobox-TitleInput Ldt-CurrentSegmentInfobox-Title" value="{{title}}"></input>' +
'<textarea class="Ldt-CurrentSegmentInfobox-Element Ldt-CurrentSegmentInfobox-DescriptionInput Ldt-CurrentSegmentInfobox-Description">{{description}}</textarea>' +
'<div class="Ldt-CurrentSegmentInfobox-Element Ldt-CurrentSegmentInfobox-Tags">' +
'{{#headers}}<div class="Ldt-CurrentSegmentInfobox-TagsHeader">{{tags_header}}</div>{{/headers}}' +
"{{#new_tag_button}}" +
'<div class="Ldt-CurrentSegmentInfobox-CreateTagButton">{{new_tag}}</div>' +
"{{/new_tag_button}}" +
"{{^new_tag_button}}" +
'<input class="Ldt-CurrentSegmentInfobox-CreateTagInput" placeholder="{{new_tag}}"></input>' +
'<div class="Ldt-CurrentSegmentInfobox-CreateTagInput-Add">+</div>' +
"{{/new_tag_button}}" +
'<ul class="Ldt-CurrentSegmentInfobox-Tags-Ul">' +
"{{#tags}}" +
"{{#.}}" +
'<li class="Ldt-CurrentSegmentInfobox-Tags-Li">' +
'<input type="text" class="Ldt-CurrentSegmentInfobox-Tags-Li-Input" value="{{.}}"></input>' +
'<div class="Ldt-CurrentSegmentInfobox-Tags-Li-DeleteTagButton">{{delete_tag}}</div>' +
"</li>" +
"{{/.}}" +
"{{/tags}}" +
"</ul>" +
"</div>" +
'<div class="Ldt-CurrentSegmentInfobox-SubmitButton">{{submit}}</div>' +
'<div class="Ldt-CurrentSegmentInfobox-CancelButton">{{cancel}}</div>' +
"</div>" +
"</div>";
static messages = {
fr: {
submit: "Soumettre",
cancel: "Annuler",
edit: "Editer",
new_tag: "Nouveau tag",
delete_tag: "Supprimer",
fields_header: "Commentaire associé à ce segment",
tags_header: "Mots-clés associés à ce segment",
empty: "Le player vidéo ne lit actuellement aucun segment",
},
en: {
submit: "Submit",
cancel: "Cancel",
edit: "Edit",
new_tag: "New tag",
delete_tag: "Delete tag",
fields_header: "Current segment content",
tags_header: "Current segment tags",
empty: "The player currently doesn't read any segment",
},
};
draw() {
var _this = this;
this.segments = this.getWidgetAnnotations();
this.renderTemplate();
this.currentSegment = false;
this.clearBox();
this.refresh();
this.onMediaEvent("timeupdate", "refresh");
this.onMediaEvent("settimerange", function (_timeRange) {
var _segmentBegin = _timeRange[0],
_segmentEnd = _timeRange[1],
_list = _this.segments.filter(function (_segment) {
return (
_segment.begin.milliseconds == _segmentBegin.milliseconds &&
_segment.end.milliseconds == _segmentEnd.milliseconds
);
});
if (_list.length > 0) {
_this.$.toggleClass("editing", false);
if (_this.currentSegment.id != _list[0].id) {
_this.currentSegment = _list[0];
_data = {
editable_segments: _this.editable_segments,
edit: _this.custom_edit_text
? _this.custom_edit_text
: _this.l10n.edit,
title: _this.currentSegment.title,
description: _this.currentSegment.description,
description_placeholder: _this.empty_description_placeholder,
tags: _this.currentSegment.getTagTexts(),
};
_this.$.html(Mustache.render(_this.template, _data));
if (_this.editable_segments && _this.currentSegment) {
_this.$.find(".Ldt-CurrentSegmentInfobox").click(
_this.functionWrapper("enableEditMode")
);
}
}
}
});
if (this.editable_segments && this.currentSegment) {
this.$.find(".Ldt-CurrentSegmentInfobox").click(
_this.functionWrapper("enableEditMode")
);
}
}
enableEditMode() {
var _this = this;
if (this.currentSegment) {
_data = {
title: this.currentSegment.title,
description: this.currentSegment.description,
tags: this.currentSegment.getTagTexts(),
submit: this.l10n.submit,
cancel: this.l10n.cancel,
headers: this.show_headers,
tags_header: this.custom_tags_header
? this.custom_tags_header
: this.l10n.tags_header,
fields_header: this.custom_fields_header
? this.custom_fields_header
: this.l10n.fields_header,
new_tag: this.l10n.new_tag,
delete_tag: this.l10n.delete_tag,
new_tag_button: this.new_tag_button,
};
this.$.toggleClass("editing", true);
this.$.html(Mustache.render(this.editTemplate, _data));
this.$.find(".Ldt-CurrentSegmentInfobox-CancelButton").click(
this.functionWrapper("disableEditMode")
);
if (this.new_tag_button) {
this.$.find(".Ldt-CurrentSegmentInfobox-CreateTagButton").click(
this.functionWrapper("insertTagInput")
);
} else {
this.$.find(".Ldt-CurrentSegmentInfobox-CreateTagInput").keypress(
this.functionWrapper("insertTagInputKeypress")
);
this.$.find(".Ldt-CurrentSegmentInfobox-CreateTagInput-Add").click(
this.functionWrapper("insertTagInputKeypress")
);
}
this.$.find(".Ldt-CurrentSegmentInfobox-Tags-Li-DeleteTagButton").click(
this.functionWrapper("deleteTagInput")
);
this.$.find(".Ldt-CurrentSegmentInfobox-SubmitButton").click(
this.functionWrapper("onSubmit")
);
}
}
disableEditMode() {
if (this.currentSegment) {
_data = {
editable_segments: this.editable_segments,
edit: this.custom_edit_text ? this.custom_edit_text : this.l10n.edit,
title: this.currentSegment.title,
description: this.currentSegment.description,
description_placeholder: this.empty_description_placeholder,
tags: this.currentSegment.getTagTexts(),
};
this.$.toggleClass("editing", false);
this.$.html(Mustache.render(this.template, _data));
this.$.find(".Ldt-CurrentSegmentInfobox").click(
this.functionWrapper("enableEditMode")
);
}
}
insertTagInput() {
if (
!this.currentSegment.getTagTexts().length &&
!this.$.find(".Ldt-CurrentSegmentInfobox-Tags-Ul").length
) {
this.$.find(".Ldt-CurrentSegmentInfobox-Tags").prepend(
'<ul class="Ldt-CurrentSegmentInfobox-Tags-Ul"></ul>'
);
}
this.$.find(".Ldt-CurrentSegmentInfobox-Tags-Ul").append(
'<li class="Ldt-CurrentSegmentInfobox-Tags-Li">' +
'<input type="text" class="Ldt-CurrentSegmentInfobox-Tags-Li-Input" value=""></input>' +
'<div class="Ldt-CurrentSegmentInfobox-Tags-Li-DeleteTagButton">' +
this.l10n.delete_tag +
"</div>" +
"</li>"
);
this.$.find(".Ldt-CurrentSegmentInfobox-Tags-Li-DeleteTagButton").click(
this.functionWrapper("deleteTagInput")
);
}
insertTagInputKeypress(event) {
var keycode = event.keyCode ? event.keyCode : event.which;
if (keycode == "13" || event.type == "click") {
if (
!this.currentSegment.getTagTexts().length &&
!this.$.find(".Ldt-CurrentSegmentInfobox-Tags-Ul").length
) {
this.$.find(".Ldt-CurrentSegmentInfobox-Tags").prepend(
'<ul class="Ldt-CurrentSegmentInfobox-Tags-Ul"></ul>'
);
}
this.$.find(".Ldt-CurrentSegmentInfobox-Tags-Ul").append(
'<li class="Ldt-CurrentSegmentInfobox-Tags-Li">' +
'<input type="text" class="Ldt-CurrentSegmentInfobox-Tags-Li-Input" value="' +
this.$.find(".Ldt-CurrentSegmentInfobox-CreateTagInput").val() +
'"></input>' +
'<div class="Ldt-CurrentSegmentInfobox-Tags-Li-DeleteTagButton">' +
this.l10n.delete_tag +
"</div>" +
"</li>"
);
this.$.find(".Ldt-CurrentSegmentInfobox-Tags-Li-DeleteTagButton").click(
this.functionWrapper("deleteTagInput")
);
this.$.find(".Ldt-CurrentSegmentInfobox-CreateTagInput").val("");
return false;
}
}
deleteTagInput(clickEvent) {
$(clickEvent.currentTarget).parent().remove();
}
onSubmit() {
new_tags_titles = this.$.find(
".Ldt-CurrentSegmentInfobox-Tags-Li-Input"
).map(function () {
if ($(this).val()) {
return $(this).val();
}
});
new_title = this.$.find(".Ldt-CurrentSegmentInfobox-TitleInput").val();
new_description = this.$.find(
".Ldt-CurrentSegmentInfobox-DescriptionInput"
).val();
var _this = this,
_exportedAnnotations = new ns.Model.List(
this.player.sourceManager
) /* We create an Annotations List to send to the server */,
_export = this.player.sourceManager.newLocalSource({
serializer: ns.serializers[this.api_serializer],
}) /* We create a source object using a specific serializer for export */,
_annotation = new ns.Model.Annotation(
this.currentSegment.id,
_export
); /* We create an annotation in the source with a generated ID (param. false) */
_annotation.setAnnotationType(this.currentSegment.getAnnotationType().id);
_annotation.setMedia(this.currentSegment.getMedia().id);
_annotation.setBegin(this.currentSegment.begin);
_annotation.setEnd(this.currentSegment.end);
_annotation.created = this.currentSegment.created;
_annotation.creator = this.currentSegment.creator;
_annotation.title = new_title; /* Title field */
_annotation.description = new_description; /* Description field */
var _tagIds = _(new_tags_titles).map(function (_title) {
var _tags = _this.source.getTags(true).searchByTitle(_title, true);
if (_tags.length) {
var _tag = _tags[0];
} else {
_tag = new ns.Model.Tag(_title.replace(/\W/g, "_"), _this.source);
_tag.title = _title;
_this.source.getTags().push(_tag);
}
return _tag.id;
}).value();
_annotation.setTags(_tagIds);
_annotation.project_id = this.project_id;
_exportedAnnotations.push(
_annotation
); /* We add the annotation in the list to export */
_export.addList(
"annotation",
_exportedAnnotations
); /* We add the list to the source object */
_url = Mustache.render(this.api_endpoint_template, {
annotation_id: this.currentSegment.id,
});
ns.jQuery.ajax({
url: _url,
type: this.api_method,
contentType: "application/json",
data: _export.serialize() /* Source is serialized */,
success: function (_data) {
_export
.getAnnotations()
.removeElement(
_annotation,
true
); /* We delete the sent annotation to avoid redundancy */
_export.deSerialize(_data); /* Data deserialization */
_this.source.merge(
_export
); /* We merge the deserialized data with the current source data */
_this.segments.forEach(function (_segment) {
if (_segment.id == _annotation.id) {
_this.segments.removeElement(_segment);
}
});
_this.segments.push(_annotation);
_this.currentSegment = _annotation;
_data = {
editable_segments: _this.editable_segments,
edit: _this.custom_edit_text
? _this.custom_edit_text
: _this.l10n.edit,
title: _this.currentSegment.title,
description: _this.currentSegment.description,
description_placeholder: _this.empty_description_placeholder,
tags: _this.currentSegment.getTagTexts(),
};
_this.$.html(Mustache.render(_this.template, _data));
if (_this.editable_segments && _this.currentSegment) {
_this.$.find(".Ldt-CurrentSegmentInfobox").click(
_this.functionWrapper("enableEditMode")
);
}
_this.$.toggleClass("editing", false);
},
error: function (_xhr, _error, _thrown) {
ns.log("Error when sending annotation", _thrown);
_export.getAnnotations().removeElement(_annotation, true);
},
});
}
refresh() {
if (!this.media.getTimeRange()) {
var _currentTime = this.media.getCurrentTime();
var _list = this.segments.filter(function (_segment) {
return _segment.begin <= _currentTime && _segment.end >= _currentTime;
});
if (_list.length > 0) {
if (this.currentSegment.id != _list[0].id) {
this.currentSegment = _list[0];
_data = {
editable_segments: this.editable_segments,
edit: this.custom_edit_text
? this.custom_edit_text
: this.l10n.edit,
title: this.currentSegment.title,
description: this.currentSegment.description,
description_placeholder: this.empty_description_placeholder,
tags: this.currentSegment.getTagTexts(),
};
this.$.html(Mustache.render(this.template, _data));
if (this.editable_segments && this.currentSegment) {
this.$.find(".Ldt-CurrentSegmentInfobox").click(
this.functionWrapper("enableEditMode")
);
}
}
} else {
this.currentSegment = false;
this.clearBox();
}
}
}
clearBox() {
var _empty_message = this.l10n.empty;
if (this.empty_message) {
_empty_message = this.empty_message;
}
this.$.find(".Ldt-CurrentSegmentInfobox").html(
"<div class='Ldt-CurrentSegmentInfobox-Element Ldt-CurrentSegmentInfobox-NoSegment'>" +
_empty_message +
"</div>"
);
}
};
};
export { CurrentSegmentInfobox, currentSegmentInfoboxStyles };