diff --git a/capsule-prototype/css/common.css b/capsule-prototype/css/common.css index f4cb370e8e61f94ab78196d1428eae580d75985a..959c244a4f1af4d3ae72caeb22aa8b668f71d958 100644 --- a/capsule-prototype/css/common.css +++ b/capsule-prototype/css/common.css @@ -23,3 +23,7 @@ content: "\2713 "; color: black; } + +input.warning, *.warning { + border: 2px solid red; +} diff --git a/capsule-prototype/css/mosaic.css b/capsule-prototype/css/mosaic.css index 4a8a8ccd8f78604ca9177cc0c78559976b3b0992..78f75b3fa87701f978ae3fbf5b4e68a7d34dd6c3 100644 --- a/capsule-prototype/css/mosaic.css +++ b/capsule-prototype/css/mosaic.css @@ -3,6 +3,9 @@ --card-height: 150px; --card-width: 150px; + --card-image-container-width: var(--card-width); + --card-image-container-height: calc(var(--card-height) - 50px); + --filter-width: 80px; --filter-height: 25px; @@ -23,11 +26,11 @@ display: flex; flex-direction: row; flex: 1; - flex-wrap: wrap; } .mosaic_filter_item, .mosaic_label_filter { + min-width: min-content; width: var(--filter-width); height: var(--filter-height); margin: var(--base-spacing); @@ -38,10 +41,7 @@ justify-content: left; padding-left: var(--filter-bg-size); align-items: center; -} - -.mosaic_label_filter_enabled { - background-color: rgba(255, 255, 255, .5); + flex-grow: 1; } .mosaic_category { @@ -58,6 +58,15 @@ flex-direction: column; align-items: center; text-align: center; + background: inherit; +} + +.mosaic_button { + cursor: pointer; +} + +.mosaic_button:hover { + filter: brightness(1.5); } .mosaic_item span { @@ -65,13 +74,24 @@ overflow: hidden; text-overflow: ellipsis; padding: var(--base-spacing); + color: #ebecec; } -.mosaic_item img { +.mosaic_item_thumbnail_container { + width: var(--card-image-container-width); + height: var(--card-image-container-height); + display: flex; + align-items: center; + align-content: center; + justify-content: center; + padding: var(--base-spacing); +} + +.mosaic_item_thumbnail_container_img { width: 80%; height: auto; - max-height: var(--card-height); - padding: var(--base-spacing); + max-height: var(--card-image-container-height); + max-width: var(--card-image-container-width); } .mosaic_filter_item:not(.mosaic_filter_item_all), .mosaic_category > h2 { @@ -90,6 +110,10 @@ background-image: url('images/icn-menu-preview.png'); } +.mosaic_label_filter_enabled { + background-color: rgba(255, 255, 255, .5); +} + .mosaic_filter_disabled { background-image: url('images/icn-menu-filter.png'); } diff --git a/capsule-prototype/index.html b/capsule-prototype/index.html index 8caea838f292055c6eb52b4b1c8e6fc9cab53aad..7ad8498a28c865808909621e4d94c9849c581c55 100644 --- a/capsule-prototype/index.html +++ b/capsule-prototype/index.html @@ -25,9 +25,11 @@ <script language="javascript" type='text/javascript' src='../shared/js/libs/sha1.js'></script> <script language="javascript" type='text/javascript' src='../shared/js/libs/fastdom.js'></script> <script language="javascript" type='text/javascript' src='../shared/js/libs/moment-with-langs.min.js'></script> + <script language="javascript" type="text/javascript" src='../shared/js/shared.js'></script> <script language="javascript" type='text/javascript' src="../shared/php/rekallApp.js.php"></script> + <script language="javascript" type="text/javascript" src="../shared/js/online-rekall/NotificationEntityChanged.js" ></script> <script language="javascript" type='text/javascript' src='../shared/js/rekall/Utils.js'></script> <script language="javascript" type='text/javascript' src='../shared/js/online-rekall/Rekall.js'></script> <script language="javascript" type='text/javascript' src='../shared/js/rekall/Source.js'></script> @@ -38,6 +40,8 @@ <script language="javascript" type='text/javascript' src='../shared/js/online-rekall/Tags.js'></script> <script language="javascript" type='text/javascript' src='../shared/js/online-rekall/Timeline.js'></script> <script language="javascript" type='text/javascript' src="../shared/js/online-rekall/RekallApplication.js"></script> + <script language="javascript" type="text/javascript" src='../shared/js/MosaicPanelWidget.js'></script> + <script language="javascript" type="text/javascript" src='../shared/js/PopupPanelWidget.js'></script> <script language="javascript" type='text/javascript' src='../shared/js/iannix.js'></script> <script language="javascript" type='text/javascript' src='../shared/js/online-script.js'></script> @@ -132,61 +136,6 @@ <div class="editmode" id="popupEditSupprimer">Delete file</div> </td> <td id="popupRight"> - <div id="closePopupEdit">✕</div> - - <div class="popupRightItem" id="popupNom"></div> - <input class="popupInput" id="popupNomInput" type="text" value=""/> - - <div class="popupRightItem" id="popupAuthor" title="Author"></div> - <input class="popupInput" id="popupAuthorInput" type="text"></input> - - <div class="popupRightItem" id="popupTC"> - <div class="popupTCdisplay" id="popupTCin"></div> - <div class="popupTCdisplay" id="popupTCout"></div> - </div> - <div class="popupInput" id="popupTCedit"> - <span class="popupTClabel">start</span> - <input class="popupTCeditfield" id="popupTCinMin" maxlength="2" type="text" value=""/> : <input class="popupTCeditfield" id="popupTCinSec" maxlength="2" type="text" value=""/> - <div class="nowTCbtn" id="nowTCin">now</div> - <br/> - <span class="popupTClabel">end</span> - <input class="popupTCeditfield" id="popupTCoutMin" maxlength="2" type="text" value=""/> : <input class="popupTCeditfield" id="popupTCoutSec" maxlength="2" type="text" value=""/> - <div class="nowTCbtn" id="nowTCout">now</div> / <div class="nowTCbtn" id="eovTCout">end of video</div> - </div> - - <div class="popupRightItem" id="popupLegende" title="Comment"></div> - <textarea class="popupInput" id="popupLegendeInput" type="text"></textarea> - - <div class="popupRightItem" id="popupLink" title="Link"></div> - <textarea class="popupInput" id="popupLinkInput" type="text"></textarea> - - <div class='popupNewTitles'>+ Playback rate</div> - <form id='popupSpeedInput' class='flex-row playback_form popupInput popupInputNoHide'> - <input type='radio' id='annotation_playback_speed_025' value='0.25' name='playback_rate' /> - <label class='left_menu_item' for='annotation_playback_speed_025'>0.25</label> - <input type='radio' id='annotation_playback_speed_05' value='0.5' name='playback_rate' /> - <label class='left_menu_item' for='annotation_playback_speed_05'>0.5</label> - <input type='radio' id='annotation_playback_speed_075' value='0.75' name='playback_rate' /> - <label class='left_menu_item' for='annotation_playback_speed_075'>0.75</label> - <input type='radio' id='annotation_playback_speed_1' value='1' name='playback_rate' /> - <label class='left_menu_item' for='annotation_playback_speed_1'>normal</label> - <input type='radio' id='annotation_playback_speed_125' value='1.25' name='playback_rate' /> - <label class='left_menu_item' for='annotation_playback_speed_125'>1.25</label> - <input type='radio' id='annotation_playback_speed_15' value='1.5' name='playback_rate' /> - <label class='left_menu_item' for='annotation_playback_speed_15'>1.5</label> - <input type='radio' id='annotation_playback_speed_175' value='1.75' name='playback_rate' /> - <label class='left_menu_item' for='annotation_playback_speed_175'>1.75</label> - <input type='radio' id='annotation_playback_speed_2' value='2' name='playback_rate' /> - <label class='left_menu_item' for='annotation_playback_speed_2'>2</label> - </form> - - <div class='popupNewTitles'>+ Tags</div> - <input type='text' id='new_annotation_label' placeholder='Add a new tag' class='editmode' /> - <div id='popupLabelsInput' class='flex-col popupInput popupInputNoHide'> - <!-- templates --> - <input class='annotation_labels_template' type='checkbox' id='' value='' style='display: none;' /> - <label class='annotation_labels_template' for='' style='display: none;'></label> - </div> </td> </tr> </table> diff --git a/capsule-prototype/js/MosaicPanelWidget.js b/capsule-prototype/js/MosaicPanelWidget.js new file mode 100644 index 0000000000000000000000000000000000000000..e117fe72cf393bc844233027b50f6d2eae972002 --- /dev/null +++ b/capsule-prototype/js/MosaicPanelWidget.js @@ -0,0 +1,264 @@ +((app) => { + function MosaicPanelWidget() { + const defaultOptions = { + getTagGradientColor: function (tag) { + let isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0; // Opera 8.0+ (UA detection to detect Blink/v8-powered Opera) + let isFirefox = typeof InstallTrigger !== 'undefined'; // Firefox 1.0+ + let isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0; // At least Safari 3+: "[object HTMLElementConstructor]" + let isChrome = !!window.chrome && !isOpera; // Chrome 1+ + // var isIE = /*@cc_on!@*/false || !!document.documentMode; // At least IE6 + + if (isOpera) { + return "-o-linear-gradient(right bottom, rgba(20,46,51,1) 0%, " + tag.color + " 100%)"; + } + if (isFirefox) { + return "-moz-linear-gradient(right bottom, rgba(20,46,51,1) 0%, " + tag.color + " 100%)"; + } + if ((isSafari) || (isChrome)) { + return "-webkit-linear-gradient(right bottom, rgba(20,46,51,1) 0%, " + tag.color + " 100%)"; + } + }, + getPreviewPath: function (tagOrDoc) { + // eslint-disable-next-line no-undef + return Utils.getPreviewPath(tagOrDoc); + }, + htmlElement: function () { + return $('#mosaic_tab') + }, + isOpen: false, + pubsub: function () { + return app.rekall.Rekall('pubSub'); + }, + rekall: function () { + return app.rekall.Rekall('rekall'); + }, + filters_type_to_hide: [], + filter_label_to_show: [], + _followedItems: [] + }; + + const localOptions = $.extend({}, defaultOptions); + + // eslint-disable-next-line no-unused-vars + localOptions._resetFilters = function (event) { + $('.mosaic_filter_item') + .removeClass('mosaic_filter_disabled'); + $('.mosaic_label_filter_enabled').click(); + localOptions.filters_type_to_hide = []; + localOptions.filter_label_to_show = []; + $('.mosaic_category').show(); + } + + localOptions._destroyFollowedElements = function () { + let elementsToDestroy = localOptions._followedItems; + localOptions._followedItems = []; + elementsToDestroy.forEach(e => e.remove()); + } + + function toggleFilterType(filterName) { + let filters = localOptions.filters_type_to_hide; + if (filters.includes(filterName)) { + filters.splice(filters.indexOf(filterName), 1); + } else { + filters.push(filterName); + } + } + + function toggleLabelToShow(filterName) { + let filters = localOptions.filter_label_to_show; + if (filters.includes(filterName)) { + filters.splice(filters.indexOf(filterName), 1); + } else { + filters.push(filterName); + } + } + + const getUrl = function (tagOrDoc, path) { + if ('undefined' === typeof path) { + let [reg, type] = tagOrDoc.getMetadata("Rekall->Type").split('/'); + if (reg === 'rekall') { + if (type === 'marker') type = 'note'; + } + return tagOrDoc.getDownloadLink() || "../shared/css/images/img-" + type + ".png"; + } else { + return path; + } + } + + const setDivVisibilityForTag = function (div, tag) { + if (!localOptions.filter_label_to_show.length) { + div.show() + return; + } + + if (tag.getLabels().filter(value => localOptions.filter_label_to_show.includes(value.toLowerCase())).length) { + div.show(); + } else { + div.hide() + } + } + + const createHtmlElementForTagOrDoc = function (tagOrDoc) { + let path = localOptions.getPreviewPath(tagOrDoc); + let name = tagOrDoc.getMetadata("Rekall->Name"); + let url = getUrl(tagOrDoc, path); + + let div = $('<div/>').addClass('mosaic_item mosaic_button').on('click', function () { + tagOrDoc.openPopupEdit(); + }); + let divImageContainer = $('<div>').addClass('mosaic_item_thumbnail_container'); + divImageContainer + .append($('<img src="'+url+'" alt="thumbnail image"/>') + .addClass('mosaic_item_thumbnail_container_img') + .attr('onerror', "this.src='../shared/css/images/img-document.png';")); + div.append(divImageContainer); + div.append($('<span/>') + .addClass('caption') + .text(name)); + + let divUpdater = { + div: div, + tag: tagOrDoc + }; + divUpdater.update = function (tag) { + setDivVisibilityForTag(div, tag); + } + divUpdater.remove = function () { + tagOrDoc.removeObserver(divUpdater); + } + divUpdater.computeVisibility = function () { + setDivVisibilityForTag(divUpdater.div, divUpdater.tag); + } + tagOrDoc.addObserver(divUpdater); + localOptions._followedItems.push(divUpdater); + + setDivVisibilityForTag(div, tagOrDoc); + + return div; + } + + const getFilterElement = function (text, color, callback, css_class, isToggled) { + let result = $('<div/>') + .addClass('mosaic_filter_item mosaic_button') + .addClass(css_class) + .on('click', callback) + .css('background-color', color) + .append($('<h2/>').text(text)); + + + if (isToggled) { + result.toggle(); + result.toggleClass('mosaic_filter_disabled'); + } + + return result; + } + + const emptyPanel = function () { + localOptions.htmlElement().html(''); + localOptions._destroyFollowedElements(); + } + + const fillPanel = function () { + let typefilterdiv = $('<div/>').addClass('mosaic_filter'); + let labelsfilterdiv = $('<div/>').addClass('mosaic_filter'); + typefilterdiv.append(getFilterElement( + 'Reset filters', + 'rgb(100,100,100)', + localOptions._resetFilters, + 'mosaic_filter_item_all', + false + )); + localOptions.htmlElement().append(typefilterdiv); + localOptions.htmlElement().append(labelsfilterdiv); + // eslint-disable-next-line no-undef + let labels = new Set(); + for (let [k, v] of Object.entries(localOptions.rekall().sortings.colors.categories)) { + let categoryName = localOptions.rekall().sortings.colors.getCategoryName(k) + let category = $('<div/>').addClass('mosaic_category').css('background', localOptions.getTagGradientColor(v)); + + let grid = $('<div/>').addClass('mosaic_category_grid'); + + category.append($('<h2/>').text(categoryName)); + category.append(grid); + + typefilterdiv.append(getFilterElement( + categoryName, + v.color, function () { + category.toggle(); + $(this).toggleClass('mosaic_filter_disabled'); + localOptions.toggle_filterType(categoryName) + }, + '', + localOptions.filters_type_to_hide.includes(categoryName) + )); + + for (let i in v.tags) { + grid.append(createHtmlElementForTagOrDoc(v.tags[i])); + v.tags[i].getLabels().forEach(l => labels.add(l)); + } + localOptions.htmlElement().append(category); + } + + Array.from(labels) + .sort(function (a, b) { + return a.toLowerCase().localeCompare(b.toLowerCase()); + }) + .forEach(l => { + let button = $('<div/>').html(l); + button.addClass('mosaic_filter_item mosaic_button mosaic_label_filter'); + if ( + localOptions.filter_label_to_show.length + && localOptions.filter_label_to_show.includes(l.toLowerCase()) + ) { + button.toggleClass('mosaic_label_filter_enabled'); + } + + button.click(ev => { + toggleLabelToShow(l.toLowerCase()); + $(ev.target).toggleClass('mosaic_label_filter_enabled'); + ev.target.my_state = !ev.target.my_state; + console.debug('filters: ', localOptions.filter_label_to_show); + localOptions._followedItems.forEach(value => value.computeVisibility()) + }) + labelsfilterdiv.append(button); + }); + } + + localOptions.toggle_filterType = toggleFilterType; + + return { + show: function () { + if (localOptions.isOpen) + return; + + localOptions.rekall().timeline.pause(); + fillPanel(); + localOptions.htmlElement().show(); + localOptions.updateObserver = localOptions.pubsub().subscribe('popupEdit.Closed', this.refresh); + localOptions.isOpen = true; + }, + hide: function () { + if (!localOptions.isOpen) + return; + + localOptions.pubsub().unsubscribe(localOptions.updateObserver); + localOptions.updateObserver = undefined; + localOptions.htmlElement().hide(); + emptyPanel(); + localOptions.isOpen = false; + localOptions._destroyFollowedElements(); + localOptions.filters_type_to_hide = []; + }, + refresh: function () { + emptyPanel(); + fillPanel(); + } + }; + + } + + app.rekall.Rekall('mosaicWidget', MosaicPanelWidget()); + + } +)(window.app = window.app || {}) diff --git a/capsule-prototype/js/PopupPanelWidget.js b/capsule-prototype/js/PopupPanelWidget.js new file mode 100644 index 0000000000000000000000000000000000000000..680065eac293cac7677673b25ef19c5f8ef604dc --- /dev/null +++ b/capsule-prototype/js/PopupPanelWidget.js @@ -0,0 +1,996 @@ +function convertToTime(seconds) { + let minutes = Math.floor(seconds / 60); + let remainingSeconds = Math.floor(seconds - (minutes * 60)); + if (minutes < 10) minutes = "0" + minutes; + if (remainingSeconds < 10) remainingSeconds = "0" + remainingSeconds; + return minutes + ":" + remainingSeconds; +} + +function PanelEdition(data) { + this.tag = data.tag; + this.readonlyDiv = undefined; + this.editDiv = undefined; + this.canEdit = data.canEdit; + this.popupPanelWidget = data.popupPanelWidget; +} +// eslint-disable-next-line no-unused-vars +PanelEdition.prototype.appendInputEditorDiv = function (parentDiv) { +} +PanelEdition.prototype.closeEdition = function () { + this.popupPanelWidget.setCurrentOpenedInput(undefined); + this.editDiv?.hide(); + this.readonlyDiv?.show(); +} +PanelEdition.prototype.openEdition = function () { + this.popupPanelWidget.ensureLastOpenedEditionClosed(); + if (this.canEdit) { + this.popupPanelWidget.setCurrentOpenedInput(this); + this.readonlyDiv.hide(); + if (this.editDiv) { + this.editDiv.show().focus(); + } + } +} + +function AnnotationNamePanelEdition(data) { + PanelEdition.call(this, data); +} +AnnotationNamePanelEdition.prototype = Object.create(PanelEdition.prototype); +AnnotationNamePanelEdition.prototype.appendInputEditorDiv = function (parentDiv) { + let that = this; + this.readonlyDiv = $('<div>'); + this.readonlyDiv + .attr('id', 'popupNom') + .addClass('popupRightItem'); + + if (this.canEdit) { + this.readonlyDiv + .click(function (event) { + event.stopPropagation(); + that.openEdition.call(that); + }); + } + + if (this.tag.getMetadata("Rekall->Name")?.length) { + this.readonlyDiv.html(this.tag.getMetadata("Rekall->Name")); + this.readonlyDiv.css('color', this.tag.color) + } else { + if (this.canEdit) { + this.readonlyDiv.html('+ Add a name').addClass('empty'); + } + } + + parentDiv.append(this.readonlyDiv); + + if (this.canEdit) { + this.editDiv = $('<input>'); + this.editDiv + .attr('id', 'popupNomInput') + .attr('type', 'text') + .attr('value', this.tag.getMetadata("Rekall->Name") ?? '') + .click(function (event) { + event.stopPropagation(); + }) + .keyup(function (event) { + event.stopPropagation(); + if (13 === event.which) { + that.closeEdition(); + } + }) + .hide(); + this.editDiv.val(this.tag.getMetadata("Rekall->Name")); + parentDiv.append(this.editDiv); + } +} +AnnotationNamePanelEdition.prototype.closeEdition = function () { + if (this.canEdit) { + let newValue = this.editDiv.val(); + this.editDiv.val(newValue); + if (this.tag.getMetadata('Rekall->Name') !== newValue) { + this.tag.setMetadata('Rekall->Name', newValue); + window.app.rekall.Rekall('pubSub').publish('tag.metadata.updated', { + metadata: "Rekall->Name", + tag: this.tag + }); + } + + if (newValue.length) { + $('#popupNom').html(newValue).removeClass("empty"); + } else { + $('#popupNom').html('+ Add a name').addClass("empty"); + } + } + PanelEdition.prototype.closeEdition.call(this); +} + +function AnnotationAuthorPanelEdition(data) { + PanelEdition.call(this, data); +} +AnnotationAuthorPanelEdition.prototype = Object.create(PanelEdition.prototype); +AnnotationAuthorPanelEdition.prototype.appendInputEditorDiv = function (parentDiv) { + let that = this; + this.readonlyDiv = $('<div>'); + this.readonlyDiv.addClass('popupRightItem') + .attr('id', 'popupAuthor'); + + if (this.canEdit) { + this.readonlyDiv + .click(function (event) { + event.stopPropagation(); + that.openEdition.call(that); + }); + } + + let popupAuthorName = this.tag.getMetadata("Rekall->Author"); + if (popupAuthorName?.length) { + this.readonlyDiv.html(popupAuthorName); + } else { + if (this.canEdit) { + this.readonlyDiv.html('+ Add an author').addClass('empty'); + } + } + parentDiv.append(this.readonlyDiv); + + + if (this.canEdit) { + this.editDiv = $('<input>'); + this.editDiv + .attr('id', 'popupAuthorInput') + .attr('type', 'text') + .attr('value', popupAuthorName ?? '') + .click(function (event) { + event.stopPropagation(); + }) + .keyup(function (event) { + event.stopPropagation(); + if (13 === event.which) { + that.closeEdition(); + } + }) + .addClass('popupInput') + .hide(); + parentDiv.append(this.editDiv); + } +} +AnnotationAuthorPanelEdition.prototype.closeEdition = function () { + if (this.canEdit) { + let newValue = this.editDiv.val(); + this.editDiv.val(newValue); + if (this.tag.getMetadata('Rekall->Author') !== newValue) { + this.tag.setMetadata('Rekall->Author', newValue); + window.app.rekall.Rekall('pubSub').publish('tag.metadata.updated', { + metadata: "Rekall->Author", + tag: this.tag + }); + } + + if (newValue.length) { + this.readonlyDiv.html(newValue).removeClass("empty"); + } else { + this.readonlyDiv.html('+ Add an author').addClass("empty"); + } + } + PanelEdition.prototype.closeEdition.call(this); +} + +function AnnotationTCPanelEdition(data) { + PanelEdition.call(this, data); +} +AnnotationTCPanelEdition.prototype = Object.create(PanelEdition.prototype); +AnnotationTCPanelEdition.prototype.appendInputEditorDiv = function (parentDiv) { + + // eslint-disable-next-line no-unused-vars + function onlyNumber(event) { + // remove characters that are not number + $(this).val($(this).val().replace(/\D/g, '')); + } + let that = this; + + this.readonlyDiv = $('<div>'); + this.readonlyDiv + .attr('id', 'popupTC') + .addClass('popupRightItem') + .click(function (event) { + event.stopPropagation(); + that.openEdition.call(that); + }) + .css("background", that.tag.color); + + this.popupTcInDiv = $('<div>'); + this.popupTcInDiv + .attr('id', 'popupTCin') + .addClass('popupTCdisplay') + .html(convertToTime(that.tag.getTimeStart())) + this.readonlyDiv.append(this.popupTcInDiv); + + this.popupTcOutDiv = $('<div>'); + this.popupTcOutDiv + .attr('id', 'popupTCout') + .addClass('popupTCdisplay') + .html(convertToTime(that.tag.getTimeEnd())) + this.readonlyDiv.append(this.popupTcOutDiv); + parentDiv.append(this.readonlyDiv); + + if (this.canEdit) { + this.editDiv = $('<div>'); + this.editDiv + .attr('id', 'popupTCedit') + .hide() + this.editDiv.click(function (event) { + event.stopPropagation(); + }) + this.editDiv.append($('<span>').addClass('popupTClabel').html('start')); + this.popupTCeditDivMinStart = $('<input class="popupTCeditfield" id="popupTCinMin" maxLength="2" type="text" value="">'); + this.popupTCeditDivMinStart + .val(Math.floor(that.tag.getTimeStart()/60).toString(10).padStart(2, '0')) + .click(function (event) { + event.stopPropagation(); + }) + .on('input', onlyNumber); + this.editDiv.append(this.popupTCeditDivMinStart); + this.editDiv.append(':'); + this.popupTCeditDivSecStart = $('<input class="popupTCeditfield" id="popupTCinSec" maxLength="2" type="text" value="">'); + this.popupTCeditDivSecStart + .val((that.tag.getTimeStart()%60).toString(10).padStart(2, '0')) + .click(function (event) { + event.stopPropagation(); + }) + .on('input', onlyNumber); + this.editDiv.append(this.popupTCeditDivSecStart); + let popupTCeditStartDivNow = $('<div class="nowTCbtn" id="nowTCin">now</div>'); + popupTCeditStartDivNow.click(function (event) { + event.stopPropagation(); + let timeCurrent = convertToTime(Math.round(window.app.rekall.Rekall().timeline.timeCurrent)); + that.popupTCeditDivMinStart.val(timeCurrent.split(":")[0]); + that.popupTCeditDivSecStart.val(timeCurrent.split(":")[1]); + }); + this.editDiv.append(popupTCeditStartDivNow) + this.editDiv.append($('<br>')); + + this.editDiv.append($('<span>').addClass('popupTClabel').html('end')); + this.popupTCeditDivMinEnd = $('<input>'); + this.popupTCeditDivMinEnd + .attr('id', 'popupTCoutMin') + .attr('maxlength', '2') + .attr('type', 'text') + .addClass('popupTCeditfield') + .val(Math.floor(that.tag.getTimeEnd()/60).toString(10).padStart(2, '0')) + .on('input', onlyNumber); + + this.popupTCeditDivMinEnd.click(function (event) { + event.stopPropagation(); + }); + this.editDiv.append(this.popupTCeditDivMinEnd); + this.editDiv.append(':'); + this.popupTCeditDivSecEnd = $('<input>'); + this.popupTCeditDivSecEnd + .attr('id', 'popupTCoutSec') + .attr('maxlength', '2') + .attr('type', 'text') + .addClass('popupTCeditfield') + .val(Math.floor(that.tag.getTimeEnd()%60).toString(10).padStart(2, '0')) + .click(function (event) { + event.stopPropagation(); + }) + .on('input', onlyNumber); + this.editDiv.append(this.popupTCeditDivSecEnd); + let popupTCeditEndDivNow = $('<div class="nowTCbtn" id="nowTCin">now</div>'); + popupTCeditEndDivNow.click(function (event) { + event.stopPropagation(); + let timeCurrent = convertToTime(Math.round(window.app.rekall.Rekall().timeline.timeCurrent)); + that.popupTCeditDivMinEnd.val(timeCurrent.split(":")[0]); + that.popupTCeditDivSecEnd.val(timeCurrent.split(":")[1]); + }); + this.editDiv.append(popupTCeditEndDivNow); + this.editDiv.append('/'); + let popupTcEditEndDivEndVideo = $('<div class="nowTCbtn" id="eovTCout">end of video</div>'); + popupTcEditEndDivEndVideo.click(function (event) { + event.stopPropagation(); + let endVideo = window.app.rekall.Rekall().videoPlayer.duration(); + let timeEnd = convertToTime(Math.round(endVideo)); + that.popupTCeditDivMinEnd.val(timeEnd.split(":")[0]); + that.popupTCeditDivSecEnd.val(timeEnd.split(":")[1]); + }); + this.editDiv.append(popupTcEditEndDivEndVideo); + parentDiv.append(this.editDiv); + } +} +AnnotationTCPanelEdition.prototype.closeEdition = function () { + if (this.canEdit) { + let isNaN = (maybeNaN) => maybeNaN !== maybeNaN; + let ensureNotNaN = (text, defaultValue = 0) => { + let tempVal = parseInt(text); + if (isNaN(tempVal)) { + return defaultValue; + } + return tempVal; + } + let tcInMin = ensureNotNaN(this.popupTCeditDivMinStart.val()); + let tcInSec = ensureNotNaN(this.popupTCeditDivSecStart.val()); + let tcOutMin = ensureNotNaN(this.popupTCeditDivMinEnd.val()); + let tcOutSec = ensureNotNaN(this.popupTCeditDivSecEnd.val()); + let tcIn = (60 * tcInMin) + tcInSec; + let tcOut = (60 * tcOutMin) + tcOutSec; + + let endVideo = Math.ceil(window.app.rekall.Rekall().videoPlayer.duration()); + + if ((tcInMin >= 120) || (tcInSec >= 60) || (tcOutMin >= 120) || (tcOutSec >= 60) || (tcInMin < 0) || (tcInSec < 0) || (tcOutMin < 0) || (tcOutSec < 0)) { + window.app.rekall.Rekall('pubSub').publish('alert', {message: 'Invalid time code', buttons: "ok"}); + } else if (tcIn > tcOut) { + window.app.rekall.Rekall('pubSub').publish('alert', { + message: "Start time must be set before end time", + buttons: "ok" + }); + } else if (tcOut > endVideo) { + window.app.rekall.Rekall('pubSub').publish('alert', { + message: "End time must not be set after " + convertToTime(endVideo) + " (end of the video)", + buttons: "ok" + }); + } else { + this.tag.setTimeStart(tcIn); + this.tag.setTimeEnd(tcOut); + this.popupTcInDiv.html(tcInMin.toString().padStart(2, '0') + ":" + tcInSec.toString().padStart(2, '0')); + this.popupTcOutDiv.html(tcOutMin.toString().padStart(2, '0') + ":" + tcOutSec.toString().padStart(2, '0')); + this.popupTCeditDivMinStart.val(tcInMin.toString().padStart(2, '0')); + this.popupTCeditDivSecStart.val(tcInSec.toString().padStart(2, '0')); + this.popupTCeditDivMinEnd.val(tcOutMin.toString().padStart(2, '0')); + this.popupTCeditDivSecEnd.val(tcOutSec.toString().padStart(2, '0')); + window.app.rekall.Rekall('pubSub').publish('tag.tc.updated', {tag: this.tag}); + } + } + PanelEdition.prototype.closeEdition.call(this); +} + +function AnnotationCommentPanelEdition(data) { + PanelEdition.call(this, data); +} +AnnotationCommentPanelEdition.prototype = Object.create(PanelEdition.prototype); +AnnotationCommentPanelEdition.prototype.appendInputEditorDiv = function (parentDiv) { + let that = this; + this.readonlyDiv = $('<div>'); + this.readonlyDiv.addClass('popupRightItem') + .attr('id', 'popupLegende') + .attr('title', 'Comment'); + + if (this.canEdit) { + this.readonlyDiv + .click(function (event) { + event.stopPropagation(); + that.openEdition.call(that); + }); + } + + let comments = this.tag.getMetadata("Rekall->Comments"); + if (comments && comments.length) { + this.readonlyDiv.html(comments).removeClass('empty'); + } else { + if (this.canEdit) { + this.readonlyDiv.html('+ Add a comment').addClass('empty'); + } + } + parentDiv.append(this.readonlyDiv); + + if (this.canEdit) { + this.editDiv = $('<textarea>'); + this.editDiv + .attr('id', 'popupLegendeInput') + .attr('type', 'text') + .addClass('popupInput') + .click(function (event) { + event.stopPropagation(); + }); + this.editDiv.val(comments ? comments : ''); + parentDiv.append(this.editDiv); + } +} +AnnotationCommentPanelEdition.prototype.closeEdition = function () { + if (this.canEdit) { + let newValue = this.editDiv.val(); + this.editDiv.val(newValue); + if (this.tag.getMetadata('Rekall->Comments') !== newValue) { + newValue = newValue.replace(/\n/gi, "<br/>"); + this.tag.setMetadata('Rekall->Comments', newValue); + window.app.rekall.Rekall('pubSub').publish('tag.metadata.updated', { + metadata: "Rekall->Comments", + tag: this.tag + }); + } + + if (newValue.length) { + this.readonlyDiv.html(newValue).removeClass("empty"); + } else { + this.readonlyDiv.html('+ Add an author').addClass("empty"); + } + } + PanelEdition.prototype.closeEdition.call(this); +} + +function AnnotationLinkPanelEdition(data) { + PanelEdition.call(this, data); +} +AnnotationLinkPanelEdition.prototype = Object.create(PanelEdition.prototype); +AnnotationLinkPanelEdition.prototype.appendInputEditorDiv = function (parentDiv) { + let that = this; + this.readonlyDiv = $('<div>'); + this.readonlyDiv.addClass('popupRightItem') + .attr('id', 'popupLink') + .attr('title', 'Link'); + + if (this.canEdit) { + this.readonlyDiv + .click(function (event) { + event.stopPropagation(); + that.openEdition.call(that); + }); + } + + let linkValue = this.tag.getMetadata("Rekall->Link"); + if (linkValue && linkValue.length) { + if (this.canEdit) { + this.readonlyDiv.html(linkValue).removeClass('empty'); + } else { + this.readonlyDiv.html("<a href='" + linkValue + "' target='_blank'>" + linkValue + "</a>").removeClass('empty'); + } + } else { + if (this.canEdit) { + this.readonlyDiv.html("+ Add a link").addClass("empty"); + } + } + parentDiv.append(this.readonlyDiv); + + if (this.canEdit) { + this.editDiv = $('<textarea>'); + this.editDiv + .attr('id', 'popupLinkInput') + .attr('type', 'text') + .addClass('popupInput') + .click(function (event) { + event.stopPropagation(); + }) + .keyup(function (event) { + event.stopPropagation(); + if (13 === event.which) { + that.closeEdition(); + } + }) + .val(linkValue) + .hide(); + + parentDiv.append(this.editDiv); + } +} +AnnotationLinkPanelEdition.prototype.closeEdition = function () { + if (this.canEdit) { + let newValue = this.editDiv.val(); + newValue = newValue.trim(); + if (newValue && newValue.length && 0 !== newValue.indexOf("http")) { + newValue = "http://" + newValue; + } + this.editDiv.val(newValue); + + if (this.tag.getMetadata('Rekall->Link') !== newValue) { + this.tag.setMetadata('Rekall->Link', newValue); + window.app.rekall.Rekall('pubSub').publish('tag.metadata.updated', { + metadata: "Rekall->Link", + tag: this.tag + }); + } + + if (newValue.length) { + this.readonlyDiv.html(newValue).removeClass("empty"); + } else { + this.readonlyDiv.html('+ Add a Link').addClass("empty"); + } + } + PanelEdition.prototype.closeEdition.call(this); +} + +function AnnotationSpeedPanelEdition(data) { + PanelEdition.call(this, data); +} +AnnotationSpeedPanelEdition.prototype = Object.create(PanelEdition.prototype); +AnnotationSpeedPanelEdition.prototype.appendInputEditorDiv = function (parentDiv) { + let that = this; + this.readonlyDiv = $('<form>'); + this.readonlyDiv.addClass('popupRightItem') + .attr('id', 'popupSpeedInput') + .addClass('flex-row playback_form popupInput popupInputNoHide'); + + let input = $('<input>'); + input + .attr('id', 'annotation_playback_speed_025') + .attr('type', 'radio') + .attr('name', 'playback_rate') + .attr('disabled', this.canEdit ? null : 'disabled') + .val(0.25); + let inputLabel = $('<label>'); + inputLabel + .attr('for', 'annotation_playback_speed_025') + .html('0.25') + .addClass('left_menu_item'); + this.readonlyDiv.append(input); + this.readonlyDiv.append(inputLabel); + + input = $('<input>'); + input + .attr('id', 'annotation_playback_speed_05') + .attr('type', 'radio') + .attr('name', 'playback_rate') + .prop('disabled', this.canEdit ? null : 'disabled') + .val(0.5); + inputLabel = $('<label>'); + inputLabel + .attr('for', 'annotation_playback_speed_05') + .html('0.5') + .addClass('left_menu_item'); + this.readonlyDiv.append(input); + this.readonlyDiv.append(inputLabel); + + input = $('<input>'); + input + .attr('id', 'annotation_playback_speed_075') + .attr('type', 'radio') + .attr('name', 'playback_rate') + .attr('disabled', this.canEdit ? null : 'disabled') + .val(0.75); + inputLabel = $('<label>'); + inputLabel + .attr('for', 'annotation_playback_speed_075') + .html('0.75') + .addClass('left_menu_item'); + this.readonlyDiv.append(input); + this.readonlyDiv.append(inputLabel); + + input = $('<input>'); + input + .attr('id', 'annotation_playback_speed_1') + .attr('type', 'radio') + .attr('name', 'playback_rate') + .attr('disabled', this.canEdit ? null : 'disabled') + .val(1); + inputLabel = $('<label>'); + inputLabel + .attr('for', 'annotation_playback_speed_1') + .html('normal') + .addClass('left_menu_item'); + this.readonlyDiv.append(input); + this.readonlyDiv.append(inputLabel); + + input = $('<input>'); + input + .attr('id', 'annotation_playback_speed_125') + .attr('type', 'radio') + .attr('name', 'playback_rate') + .attr('disabled', this.canEdit ? null : 'disabled') + .val(1.25); + inputLabel = $('<label>'); + inputLabel + .attr('for', 'annotation_playback_speed_125') + .html('1.25') + .addClass('left_menu_item'); + this.readonlyDiv.append(input); + this.readonlyDiv.append(inputLabel); + + input = $('<input>'); + input + .attr('id', 'annotation_playback_speed_15') + .attr('type', 'radio') + .attr('name', 'playback_rate') + .attr('disabled', this.canEdit ? null : 'disabled') + .val(1.5); + inputLabel = $('<label>'); + inputLabel + .attr('for', 'annotation_playback_speed_15') + .html('1.5') + .addClass('left_menu_item'); + this.readonlyDiv.append(input); + this.readonlyDiv.append(inputLabel); + + input = $('<input>'); + input + .attr('id', 'annotation_playback_speed_175') + .attr('type', 'radio') + .attr('name', 'playback_rate') + .attr('disabled', this.canEdit ? null : 'disabled') + .val(1.75); + inputLabel = $('<label>'); + inputLabel + .attr('for', 'annotation_playback_speed_175') + .html('1.75') + .addClass('left_menu_item'); + this.readonlyDiv.append(input); + this.readonlyDiv.append(inputLabel); + + input = $('<input>'); + input + .attr('id', 'annotation_playback_speed_2') + .attr('type', 'radio') + .attr('name', 'playback_rate') + .attr('disabled', this.canEdit ? null : 'disabled') + .val(2); + inputLabel = $('<label>'); + inputLabel + .attr('for', 'annotation_playback_speed_2') + .html('2') + .addClass('left_menu_item'); + this.readonlyDiv.append(input); + this.readonlyDiv.append(inputLabel); + + let speed = this.tag.getMetadata("Rekall->Speed"); + if (!speed || !speed.trim().length) + speed = 1; + this.readonlyDiv.children('input[value="' + speed + '"]').attr('checked', true); + this.readonlyDiv.children('input[name=playback_rate]').change(function (event) { + event.stopPropagation(); + that.closeEdition.call(that); + }) + + parentDiv.append(this.readonlyDiv); +} +AnnotationSpeedPanelEdition.prototype.closeEdition = function () { + if (this.canEdit) { + let newValue = this.readonlyDiv.children('input:checked').val(); + if (this.tag.getMetadata('Rekall->Speed') !== newValue) { + this.tag.setMetadata('Rekall->Speed', newValue); + window.app.rekall.Rekall('pubSub').publish('tag.metadata.updated', { + metadata: "Rekall->Speed", + tag: this.tag + }); + } + } +} +AnnotationSpeedPanelEdition.prototype.openEdition = function () { + this.popupPanelWidget.ensureLastOpenedEditionClosed(); + if (this.canEdit) { + this.popupPanelWidget.setCurrentOpenedInput(this); + } +} + +function AnnotationTagPanelEdition(data) { + PanelEdition.call(this, data); + this.annotationInputTemplate = $('<input class="" type="checkbox" id="" value="">') + this.annotationLabelTemplate = $('<label class="" for=""></label>') +} +AnnotationTagPanelEdition.prototype = Object.create(PanelEdition.prototype); +AnnotationTagPanelEdition.prototype.appendInputEditorDiv = function (parentDiv) { + let that = this; + + function getProjectLabels(tag) { + return tag.document.getLabels(); + } + + function appendTagInputWithLabel(panel, currentLabel, panelContainsLabel) { + let input = panel.annotationInputTemplate.clone(); + let id = 'annotation_label_' + panel.tag.document.project.labels.indexOf(currentLabel); + input + .attr('id', id) + .attr('value', currentLabel) + .addClass('annotation_labels') + .prop("checked", panelContainsLabel) + .hide(); + + if(panel.canEdit){ + input + .change(function (event) { + event.stopPropagation(); + that.closeEdition.call(that); + that.openEdition.call(that); + }) + } else { + input + .change(function (event) { + event.stopPropagation(); + }) + .attr('disabled', 'disabled'); + } + + let html_label = panel.annotationLabelTemplate.clone(); + html_label + .attr('for', id) + .html(currentLabel) + .addClass('annotation_labels') + .css('color', panel.tag.color) + .css('border', '1px solid ' +panel.tag.color); + + panel.readonlyDiv.append(input); + panel.readonlyDiv.append(html_label); + } + + this.tagPanelLabel = $('<div class="popupNewTitles">+ Tags</div>'); + parentDiv.append(this.tagPanelLabel); + + if(that.canEdit){ + this.tagCreationDiv = $('<input type="text" id="new_annotation_label" placeholder="Add a new tag" pattern="[a-zA-Zéàè0-9 ]+" title="Only alphanum characters" />'); + this.tagCreationDiv.keypress(function (event) { + that.openEdition.call(that); + let keycode = (event.keyCode ? event.keyCode : event.which); + if (13 !== keycode) { + return; + } + + if ($('#new_annotation_label')[0].validity.patternMismatch) { + that.tagCreationDiv.css('border', '2px solid red'); + return; + } + + that.tagCreationDiv.css('border', 'initial'); + let labelToAdd = $(this).val(); + let labels = getProjectLabels(that.tag); + if (labels.indexOf(labelToAdd) === -1) { + that.tag.document.project.labels.push(labelToAdd); + appendTagInputWithLabel(that, labelToAdd); + } + that.readonlyDiv.children("input[value='" + labelToAdd + '\']').attr('checked', 'checked'); + $(this).val(''); + that.closeEdition.call(that); + }); + parentDiv.append(this.tagCreationDiv); + } + + this.readonlyDiv = $('<div>'); + this.readonlyDiv + .addClass('flex-col popupInput popupInputNoHide') + .attr('id', 'popupLabelsInput'); + + let _labels = getProjectLabels(this.tag); + let tagLabels = that.tag.getLabels(); + for (let currentLabel of _labels) { + if (!this.canEdit && !tagLabels.includes(currentLabel)) + continue; + appendTagInputWithLabel(this, currentLabel, tagLabels.includes(currentLabel)); + } + parentDiv.append(this.readonlyDiv); +} +AnnotationTagPanelEdition.prototype.save = function () { + if (this.canEdit) { + let newValue = ''; + this.readonlyDiv + .children('input:checked') + .each(function () { + newValue += $(this).val() + ';' + }); + if (newValue.length) { + newValue = newValue.slice(0, newValue.length - 1); + } + + if (this.tag.getMetadata('Rekall->Labels') !== newValue) { + this.tag.setMetadata('Rekall->Labels', newValue); + window.app.rekall.Rekall('pubSub').publish('tag.metadata.updated', { + metadata: "Rekall->Labels", + tag: this.tag + }); + } + } +} +AnnotationTagPanelEdition.prototype.closeEdition = function () { + if (this !== this.popupPanelWidget.getCurrentOpenedInput()) + this.popupPanelWidget.ensureLastOpenedEditionClosed(); + this.save(); +} +AnnotationTagPanelEdition.prototype.openEdition = function () { + if (this !== this.popupPanelWidget.getCurrentOpenedInput()) { + this.popupPanelWidget.ensureLastOpenedEditionClosed(); + if (this.canEdit) { + this.popupPanelWidget.setCurrentOpenedInput(this); + } + } +} + + +function PopupPanelWidget(data) { + this.canEdit = data?.canEdit ?? function () { + return false; + }; + this.currentOpenedInput = undefined; + this.videoWasPlayingOnContentCreation = false; +} +PopupPanelWidget.prototype.getCurrentOpenedInput = function () { + return this.currentOpenedInput; +} +PopupPanelWidget.prototype.setCurrentOpenedInput = function (input) { + this.currentOpenedInput = input; +} +PopupPanelWidget.prototype.ensureLastOpenedEditionClosed = function () { + if (this.currentOpenedInput) { + this.currentOpenedInput.closeEdition(); + this.currentOpenedInput = undefined; + } +} +PopupPanelWidget.prototype.createPopupContent = function (tag) { + + let that = this; + this.videoWasPlayingOnContentCreation = !window.app.rekall.Rekall().timeline.isPaused(); + if (this.videoWasPlayingOnContentCreation) { + window.app.rekall.Rekall().timeline.pause(); + } + + function createLeftPopup(popupPanelWidget) { + let that = this; + let popupLeftDiv = $('#popupLeft'); + let bgColorLeft = this.getTagGradientColor(); + popupLeftDiv + .empty() + .css("background", bgColorLeft) + .attr('keydoc', this.document.key) + + let highlightDiv = $('<div>') + .attr('id', 'popupSetHighlight') + .text("★ Highlight") + .attr("ishighlight", this.getMetadata("Rekall->Highlight")?.length ? "true" : "false") + .click(function (event) { + event.stopPropagation(); + let isHL = !!that.getMetadata("Rekall->Highlight"); + + if (isHL) { + that.setMetadata("Rekall->Highlight", ""); + $(this).attr("isHighlight", "false").removeClass("selected"); + $("#popupEdit").removeClass("highlightPopup"); + } else { + that.setMetadata("Rekall->Highlight", "true"); + $(this).attr("isHighlight", "true").addClass("selected"); + $("#popupEdit").addClass("highlightPopup"); + } + + window.app.rekall.Rekall('pubSub').publish('tag.metadata.updated', { + metadata: "Rekall->Highlight", + tag: that + }); + }); + + if (this.getMetadata("Rekall->Highlight")?.length) { + highlightDiv + .addClass('selected'); + } + + popupLeftDiv.append(highlightDiv); + + let imageBoxDiv = $('<div>'); + imageBoxDiv.addClass('popupLeftItem') + .attr('id', 'popupImgBox'); + + let image = $('<img src="" alt="">'); + if (this.isMarker()) { + image.attr('src', "../shared/css/images/img-note.png"); + } else { + if (this.thumbnail.url) { + image.attr("src", this.getDownloadLink() || this.thumbnail.url); + } else { + let type = this.getMetadata("Rekall->Type"); + if (type.indexOf("image") > -1) image.attr("src", "../shared/css/images/img-image.png") + else if (type.indexOf("pdf") > -1) image.attr("src", "../shared/css/images/img-pdf.png") + else if (type.indexOf("audio") > -1) image.attr("src", "../shared/css/images/img-music.png") + else if (type.indexOf("vcard") > -1) image.attr("src", "../shared/css/images/img-user.png") + else if (type.indexOf("video") > -1) image.attr("src", "../shared/css/images/img-video.png") + else if (type.indexOf("msword") > -1) image.attr("src", "../shared/css/images/img-word.png") + else if (type.indexOf("link") > -1) image.attr("src", "../shared/css/images/img-link.png") + else $("#popupImg").attr("src", "../shared/css/images/img-document.png"); + } + + image + .attr('id', 'popupImg') + .click(function (event) { + event.stopPropagation(); + if (that.isLink()) { + if (that.getMetadata("Rekall->Link")) window.open(that.getMetadata("Rekall->Link"), '_blank') + } else { + window.open(image.attr('src'), '_blank'); + } + }); + } + + imageBoxDiv.append(image); + + let popupTypeDiv = $('<div>'); + popupTypeDiv + .attr('id', 'popupType') + .addClass('popupLeftItem') + .html(this.getMetadata("Rekall->Type")) + .css('color', this.color); + imageBoxDiv.append(popupTypeDiv); + + if (this.getMetadata("Rekall->Type")?.length + && this.getMetadata("Rekall->Type").split('/')[0] === 'image') { + if (popupPanelWidget.canEdit()) { + let editAnnotationPic = $('<div>'); + editAnnotationPic + .attr('id', 'editAnnotationPic') + .html('edit') + .addClass('popupLeftItem'); + editAnnotationPic.click(function () { + window.app.rekall.Rekall('pubSub').publish('image.annotation.edit.open', that); + }); + imageBoxDiv.append(editAnnotationPic); + } + + let displayOriginalImage = $('<div>'); + displayOriginalImage + .attr('id', 'linkToOriginalImage') + .addClass('popupLeftItem') + .html('Open original image') + .click(function () { + window.open(that.getDownloadLink(true), '_blank'); + }); + imageBoxDiv.append(displayOriginalImage); + } + popupLeftDiv.append(imageBoxDiv); + + if (popupPanelWidget.canEdit()) { + let deleteElement = $('<div>'); + if (this.isMarker()) { + deleteElement.html("Delete Note"); + } else { + deleteElement.html("Delete File"); + } + deleteElement + .click(function () { + window.app.rekall.Rekall('pubSub').publish('', { + message: "Do you really want to delete this file from the project ?", + buttons: "yesnodelete" + }); + }) + .addClass('popupLeftItem') + .attr('id', 'popupEditSupprimer'); + popupLeftDiv.append(deleteElement); + } + } + + function createRightPopup(popupPanelWidget) { + let popupRightTd = $('#popupRight'); + popupRightTd.attr('keyDoc', tag.document.key) + popupRightTd.empty(); + + let commonDataForPanels = { + canEdit: popupPanelWidget.canEdit(), + tag: this, + popupPanelWidget: popupPanelWidget + }; + let closePopupDiv = $('<div id="closePopupEdit">✕</div>'); + closePopupDiv.click(function(){ + popupPanelWidget.close(); + }) + popupRightTd.append(closePopupDiv); + + let projectNameInput = new AnnotationNamePanelEdition(commonDataForPanels) + projectNameInput.appendInputEditorDiv(popupRightTd); + + let projectAuthorInput = new AnnotationAuthorPanelEdition(commonDataForPanels); + projectAuthorInput.appendInputEditorDiv(popupRightTd); + + let tcInput = new AnnotationTCPanelEdition(commonDataForPanels); + tcInput.appendInputEditorDiv(popupRightTd); + + let commentPanel = new AnnotationCommentPanelEdition(commonDataForPanels); + commentPanel.appendInputEditorDiv(popupRightTd); + + let linkPanel = new AnnotationLinkPanelEdition(commonDataForPanels); + linkPanel.appendInputEditorDiv(popupRightTd); + + let speedPanel = new AnnotationSpeedPanelEdition(commonDataForPanels); + speedPanel.appendInputEditorDiv(popupRightTd); + + let tagPanel = new AnnotationTagPanelEdition(commonDataForPanels); + tagPanel.appendInputEditorDiv(popupRightTd); + } + + createRightPopup.call(tag, this); + createLeftPopup.call(tag, this); + $('#popupEdit') + .unbind('click') + .click(function (event) { + event.stopPropagation(); + that.ensureLastOpenedEditionClosed(); + }); +} +PopupPanelWidget.prototype.show = function() { + $("#popupSpace").show(); + $("#popupEdit").show(); +} +PopupPanelWidget.prototype.close = function() { + this.ensureLastOpenedEditionClosed(); + $("#popupSpace").hide(); + $("#popupEdit").hide(); + if(this.videoWasPlayingOnContentCreation) { + window.app.rekall.Rekall().timeline.play(); + } + window.app.rekall.Rekall('pubSub').publish('popupEdit.Closed', {}); +} diff --git a/capsule-prototype/js/online-rekall/NotificationEntityChanged.js b/capsule-prototype/js/online-rekall/NotificationEntityChanged.js new file mode 100644 index 0000000000000000000000000000000000000000..3585de3ab74febd82507b070caab408bd274c6a5 --- /dev/null +++ b/capsule-prototype/js/online-rekall/NotificationEntityChanged.js @@ -0,0 +1,27 @@ +function NotificationEntityChanged(data) { + this.__observers = []; +} + +NotificationEntityChanged.prototype.notifyChange = function() { + let observers = this.__observers; + observers.forEach(o => { if (o.update && typeof o.update === 'function') { o.update(this) } }); +}; + +NotificationEntityChanged.prototype.addObserver = function (observer) { + if (!this.__observers.includes(observer)) { + this.__observers.push(observer) + } +}; + +NotificationEntityChanged.prototype.removeObserver = function (observer) { + if (!this.__observers.includes(observer)) { + this.__observers.slice(this.__observers.indexOf(observer), 1); + } +}; + + +NotificationEntityChanged.prototype.getObserver = function (index) { + if (index > -1 && index < this.__observers.length) { + return this.__observers[index]; + } +}; \ No newline at end of file diff --git a/capsule-prototype/js/online-rekall/Project.js b/capsule-prototype/js/online-rekall/Project.js index c741f51b66d8213e29f117d76d8490f875c034db..1dca2682fe864b71c7fbae8de227d94124b02ab3 100644 --- a/capsule-prototype/js/online-rekall/Project.js +++ b/capsule-prototype/js/online-rekall/Project.js @@ -22,503 +22,270 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ -function Project(url) { - this.sources = new Object(); - this.url = url; - this.firstAnalysis = true; - this.metadata = { - "Title": "", - "Author": "", - "Email": "", - "Date": "", - "Comments": "", - }; - var urlItems = rekall.baseUrl.split("/"); - urlItems = $.grep(urlItems,function(n){ return(n) }); - this.metadata["Title"] = urlItems[urlItems.length-1]; - +function Project(url, rekall) { + this.sources = {}; + this.url = url; + this.firstAnalysis = true; + this.metadata = { + "Title": "", + "Author": "", + "Email": "", + "Date": "", + "Comments": "", + }; + var urlItems = rekall.baseUrl.split("/"); + urlItems = $.grep(urlItems, function (n) { + return (n) + }); + this.metadata["Title"] = urlItems[urlItems.length - 1]; + this.rekall = rekall; + this.labels = []; } -Project.prototype.addDocument = function(key, document) { - if(this.sources[key] == undefined) - this.sources[key] = new Source(); - this.sources[key].addDocument(document); -} -Project.prototype.getDocument = function(path) { - var retour = undefined; - for (var key in this.sources) { - if(retour == undefined) - retour = this.sources[key].getDocument(path); - } - return retour; +Project.prototype.addDocument = function (key, document) { + if (this.sources[key] == undefined) + this.sources[key] = new Source(); + this.sources[key].addDocument(document); } -Project.prototype.loadXML = function(xml) { - this.sources["Files"] = new Source(); +Project.prototype.getDocument = function (path) { + var retour = undefined; + for (var key in this.sources) { + if (retour == undefined) + retour = this.sources[key].getDocument(path); + } + return retour; +} - var thiss = this; - var counts = {documents: 0, tags: 0, metadatas: 0}; - xml.find('document').each(function() { - if(($(this).attr("remove") != undefined) && ($(this).attr("key") != undefined) && ($(this).attr("remove") == "true")) { - var rekallDoc = thiss.sources["Files"].documents[$(this).attr("key")]; - if(rekallDoc != undefined) { - for (var tagIndex in rekallDoc.tags) - rekallDoc.tags[tagIndex].visuel.rect.remove(); - delete rekall.project.sources["Files"].documents[rekallDoc.key]; - } - } - else { - var rekallDoc = new Document(); - counts.documents++; - counts.tags++; - $(this).find('meta').each(function() { - var rekallDocMeta = new Metadata(); - rekallDocMeta.content = $(this).attr('cnt'); - rekallDocMeta.metadataKey = $(this).attr('ctg'); - rekallDoc.setMetadata(rekallDocMeta); - counts.metadatas++; - }); - if($(this).attr("key") != undefined) - rekallDoc.key = $(this).attr("key"); - thiss.addDocument("Files", rekallDoc); - } - }); - xml.find('edition').each(function() { - var key = $(this).attr('key'); - if(thiss.sources["Files"].documents[key] != undefined) { - var version = $(this).attr('version'); - var metadataKey = $(this).attr('metadataKey'); - var metadataValue = $(this).attr('metadataValue'); - thiss.sources["Files"].documents[key].setMetadata(metadataKey, metadataValue, version); - } - }); - xml.find('tag').each(function() { - var key = $(this).attr('key'); - if(thiss.sources["Files"].documents[key] != undefined) { - var version = $(this).attr('version'); - var timeStart = parseFloat($(this).attr('timeStart')) + 0.; - var timeEnd = parseFloat($(this).attr('timeEnd')) + 0.; - for (var index in thiss.sources["Files"].documents[key].tags) { - thiss.sources["Files"].documents[key].tags[index].setTimeStart(timeStart); - thiss.sources["Files"].documents[key].tags[index].setTimeEnd(timeEnd); - } - } - }); - xml.find('projectMeta').each(function() { - thiss.metadata[$(this).attr('ctg')] = $(this).attr('cnt'); - }); - var videoUrl = undefined, videoTech = undefined; - xml.find('video').each(function() { - videoUrl = $(this).attr('url'); - videoTech = $(this).attr('tech'); - }); - - if((videoUrl != "") && (videoUrl != undefined)) { - var techOrder = ["vimeo", "youtube", "html5"]; - if(videoUrl.indexOf("youtube") >= 0) videoTech = "youtube"; - if(videoUrl.indexOf("youtu.be") >= 0) videoTech = "youtube"; - if(videoUrl.indexOf("vimeo") >= 0) videoTech = "vimeo"; - if(videoUrl.indexOf("dailymotion") >= 0) videoTech = "dailymotion"; - if(videoUrl.indexOf("dai.ly") >= 0) videoTech = "dailymotion"; - if((videoTech != "") && (videoTech != undefined)) - techOrder = [videoTech, "html5"]; +Project.prototype.loadXML = function (xml) { + this.sources["Files"] = new Source(); - //Video - if(rekall.videoPlayer == undefined) { - videojs("video", { - "techOrder": techOrder, - "controls": true, - "autoplay": false, - "loop": "false", - "preload": "auto", - "sources": [ - { - "type": "video/" + videoTech, - "src": videoUrl - } - ] - }, function() { - rekall.videoPlayer = this; - $(".vjs-fullscreen-control").hide(); - - rekall.videoPlayer.on("durationchange", function(e) { - rekall.videoPlayer.markers.removeAll == undefined; + let thiss = this; + let counts = {documents: 0, tags: 0, metadatas: 0}; + xml.find('document').each(function () { + if (($(this).attr("remove") != undefined) && ($(this).attr("key") != undefined) && ($(this).attr("remove") == "true")) { + var rekallDoc = thiss.sources["Files"].documents[$(this).attr("key")]; + if (rekallDoc != undefined) { + for (var tagIndex in rekallDoc.tags) + rekallDoc.tags[tagIndex].visuel.rect.remove(); + delete this.rekall.project.sources["Files"].documents[rekallDoc.key]; + } + } else { + let rekallDoc = new Document({project: thiss}); + counts.documents++; + counts.tags++; + $(this).find('meta').each(function () { + let rekallDocMeta = new Metadata(); + rekallDocMeta.content = $(this).attr('cnt'); + rekallDocMeta.metadataKey = $(this).attr('ctg'); + rekallDoc.setMetadata(rekallDocMeta); + counts.metadatas++; + }); + if ($(this).attr("key") != undefined) + rekallDoc.key = $(this).attr("key"); + thiss.addDocument("Files", rekallDoc); + } + }); + xml.find('edition').each(function () { + let key = $(this).attr('key'); + if (thiss.sources["Files"].documents[key] != undefined) { + var version = $(this).attr('version'); + var metadataKey = $(this).attr('metadataKey'); + var metadataValue = $(this).attr('metadataValue'); + thiss.sources["Files"].documents[key].setMetadata(metadataKey, metadataValue, version); + } + }); + xml.find('tag').each(function () { + let key = $(this).attr('key'); + if (thiss.sources["Files"].documents[key] != undefined) { + let version = $(this).attr('version'); + let timeStart = parseFloat($(this).attr('timeStart')) + 0.; + let timeEnd = parseFloat($(this).attr('timeEnd')) + 0.; + for (var index in thiss.sources["Files"].documents[key].tags) { + thiss.sources["Files"].documents[key].tags[index].setTimeStart(timeStart); + thiss.sources["Files"].documents[key].tags[index].setTimeEnd(timeEnd); + } + } + }); + xml.find('projectMeta').each(function () { + thiss.metadata[$(this).attr('ctg')] = $(this).attr('cnt'); + }); + let videoUrl = undefined, videoTech = undefined; + xml.find('video').each(function () { + videoUrl = $(this).attr('url'); + videoTech = $(this).attr('tech'); + }); - if(counts.documents>0){ - rekall.project.analyse(); - rekall.videoPlayer.markers.initialize(); - } - }); - rekall.videoPlayer.on("ended", function(e) { - }); - rekall.videoPlayer.on("error", function(e) { - }); - rekall.videoPlayer.on("firstplay", function(e) { - }); - rekall.videoPlayer.on("fullscreenchange", function(e) { - }); - rekall.videoPlayer.on("loadedalldata", function(e) { - }); - rekall.videoPlayer.on("loadeddata", function(e) { - }); - rekall.videoPlayer.on("loadedmetadata", function(e) { - console.log(counts.documents + " documents analysés, " + counts.metadatas + " métadonnées extraites et " + counts.tags + " tags affichés !"); - if(counts.documents>0){ - rekall.project.analyse(); - } - }); - rekall.videoPlayer.on("loadstart", function(e) { - }); - rekall.videoPlayer.on("pause", function(e) { - }); - rekall.videoPlayer.on("play", function(e) { - }); - rekall.videoPlayer.on("progress", function(e) { - }); - rekall.videoPlayer.on("seeked", function(e) { - }); - rekall.videoPlayer.on("seeking", function(e) { - }); - rekall.videoPlayer.on("timeupdate", function(e) { - rekall.timeline.update(rekall.videoPlayer.currentTime()); - }); - rekall.videoPlayer.on("volumechange", function(e) { - }); - rekall.videoPlayer.on("waiting", function(e) { - }); - rekall.videoPlayer.on("resize", function(e) { - }); - $(window).trigger("resize"); - - }); - } - else { - console.log(counts.documents + " documents analysés, " + counts.metadatas + " métadonnées extraites et " + counts.tags + " tags affichés !"); - rekall.project.analyse(); - } - } -} + if (this.rekall.ensureVideoPlayerCreated(videoUrl, videoTech)) { + $(window).trigger("resize"); + } -Project.prototype.timelineUpdate = function() { - + this.analyse(); } -Project.prototype.analyse = function() { - $('#flattentimeline').html("<div id='flattentimeline_highlight'></div>"); - - var parsed_labels = $('input.annotation_labels').toArray().map(i => i.value); +Project.prototype.timelineUpdate = function () { - //Analyse - Tags.flattenTimelineTags = []; - var filtredTags = new Array(); - rekall.sortings["horizontal"].analyseStart(); - rekall.sortings["colors"] .analyseStart(); - for (var keySource in this.sources) { - for (var keyDocument in this.sources[keySource].documents) { - for (var key in this.sources[keySource].documents[keyDocument].tags) { - var tag = this.sources[keySource].documents[keyDocument].tags[key]; - rekall.sortings["horizontal"].analyseAdd(tag); - rekall.sortings["colors"] .analyseAdd(tag); - Tags.flattenTimelineTags.push(tag); - var labels = tag.getMetadata('Rekall->Labels'); - if (labels && labels != '') { - var input_template = $('input.annotation_labels_template').first(); - var html_label_template = $('label.annotation_labels_template').first(); - var _labels = labels.split(';'); - for (var i in _labels) { - var label = _labels[i]; - if (label == '') continue; - if (parsed_labels.indexOf(label) != -1) - continue; - parsed_labels.push(label); - var inp = input_template.clone(); - var id = 'annotation_label_' + parsed_labels.indexOf(label); - inp.attr('id', id); - inp.attr('value', label); +} - var html_label = html_label_template.clone(); - html_label.attr('for', id); - html_label.html(label); +Project.prototype.analyse = function () { + $('#flattentimeline').html("<div id='flattentimeline_highlight'></div>"); - html_label.show(); - html_label.addClass('annotation_labels').removeClass('annotation_labels_template'); - inp.addClass('annotation_labels').removeClass('annotation_labels_template'); + // let parsed_labels = $('input.annotation_labels').toArray().map(i => i.value); + let parsed_labels = this.labels; - $('#popupLabelsInput').append(inp); - $('#popupLabelsInput').append(html_label); - } + //Analyse + Tags.reset(); + this.rekall.sortings["horizontal"].analyseStart(); + this.rekall.sortings["colors"].analyseStart(); + for (let keySource in this.sources) { + for (let keyDocument in this.sources[keySource].documents) { + for (let key in this.sources[keySource].documents[keyDocument].tags) { + let tag = this.sources[keySource].documents[keyDocument].tags[key]; + this.rekall.sortings["horizontal"].analyseAdd(tag); + this.rekall.sortings["colors"].analyseAdd(tag); + Tags.push(tag); + tag.getLabels().forEach(l => { + if (parsed_labels.indexOf(l) === -1) { + parsed_labels.push(l); + } + }) + } } - } - } - } - rekall.sortings["horizontal"].analyseEnd(); - rekall.sortings["colors"] .analyseEnd(); - Tags.flattenTimelineTags.sort(function(a, b) { - if(a.timeStart < b.timeStart) return -1; - if(a.timeStart > b.timeStart) return 1; - return 0; - }); + } + this.rekall.sortings["horizontal"].analyseEnd(); + this.rekall.sortings["colors"].analyseEnd(); + Tags.sort(); - //Affichage - var categories = rekall.sortings["horizontal"].categories; - if(rekall.sortings["horizontal"].metadataKey == "Time") - categories = {time: {tags: Tags.flattenTimelineTags}}; - - //Affectation des couleurs - for (var key in rekall.sortings["colors"].categories) { - var colorSortingCategory = rekall.sortings["colors"].categories[key]; - for (var key in colorSortingCategory.tags) { - var tag = colorSortingCategory.tags[key]; - tag.update(colorSortingCategory.color); - tag.isSelectable = colorSortingCategory.checked; - } - } - + //Affichage + let categories = rekall.sortings["horizontal"].categories; + if (this.rekall.sortings["horizontal"].metadataKey == "Time") + categories = {time: {tags: Tags.getFlattenTimeLineTags()}}; - //Tags / catégories - var markers = [], captions = []; - for (var key in categories) { - $.each(categories[key].tags, function(index, tag) { - //Elements sur la timeline - markers.push({ - time: tag.getTimeStart()+0.1, - text: tag.getMetadata("Rekall->Name"), - overlayText: tag.getMetadata("Rekall->Comments"), - css: { - "background-color": tag.color, - "width": "2px", - }, - markerTipCss: { - "font-familly": "OpenSans", - "color": tag.color, - }, - onMarkerClick: function() { - tag.openPopupEdit(); - } - }); - - //Captions en popup - if(tag.isMarker()) { - captions.push({ - startTime: tag.getTimeStart() * 1000, - endTime: (tag.timeStart + max(2, tag.timeEnd - tag.timeStart)) * 1000, - position: "HB", - data: tag.getMetadata("Rekall->Name"), - alignment: "C", - css: { - "background-color": "black", - "font-familly": "OpenSans", - "color": tag.color, - }, - onCaptionChange: function() { - tag.openPopupEdit(); - } - }); - } - - //Analyse de vignettes - if(true) { - var thumbUrl = Utils.getPreviewPath(tag); - tag.thumbnail = {url: thumbUrl, tag: tag}; - } - - - if((tag.getMetadata("Rekall->Highlight") != undefined) && (tag.getMetadata("Rekall->Highlight") != "")) { - - //Dom - $('#flattentimeline').append(function() { - var styleColor = "background-color: " + tag.color + ";"; - var textColor = "color: " + tag.color + ";"; - var textColor2 = "color: rgba(255,255,255,1)"; - var textColor3 = "color: rgba(255,255,255,.75)"; - - var colorTransp = ""; + //Affectation des couleurs + for (let key in this.rekall.sortings["colors"].categories) { + let colorSortingCategory = this.rekall.sortings["colors"].categories[key]; + for (let tagKey in colorSortingCategory.tags) { + let tag = colorSortingCategory.tags[tagKey]; + tag.update(colorSortingCategory.color); + tag.isSelectable = colorSortingCategory.checked; + } + } - var styleColor2 = styleColor; - var styleImage = ""; - if(tag.thumbnail.url != undefined) { - styleImage = "background-image: -webkit-linear-gradient(right bottom, rgba(20,46,51,.60) 0%,rgba(20,46,51,.90) 100%), url(" + tag.thumbnail.url + "); background-image: -moz-linear-gradient(right bottom, rgba(20,46,51,.60) 0%,rgba(20,46,51,.90) 100%), url(" + tag.thumbnail.url + "); background-image: -o-linear-gradient(right bottom, rgba(20,46,51,.60) 0%,rgba(20,46,51,.90) 100%), url(" + tag.thumbnail.url + ");"; - } else styleImage = "background-color: " + tag.color + "; background-image: -webkit-linear-gradient(right bottom, rgba(20,46,51,.5) 0%,rgba(20,46,51,.8) 100%); background-image: -moz-linear-gradient(right bottom, rgba(20,46,51,.5) 0%,rgba(20,46,51,.8) 100%); background-image: -o-linear-gradient(right bottom, rgba(20,46,51,.5) 0%,rgba(20,46,51,.8) 100%);" ; + //Tags / catégories + let markers = [], captions = []; + for (let key in categories) { + $.each(categories[key].tags, function (index, tag) { + //Elements sur la timeline + markers.push({ + time: tag.getTimeStart() + 0.1, + text: tag.getMetadata("Rekall->Name"), + overlayText: tag.getMetadata("Rekall->Comments"), + css: { + "background-color": tag.color, + "width": "2px", + }, + markerTipCss: { + "font-familly": "OpenSans", + "color": tag.color, + }, + onMarkerClick: function () { + tag.openPopupEdit(); + } + }); - var icnType = ""; - var tmpType = tag.getMetadata("Rekall->Type"); - if(tmpType.indexOf("application/msword") >=0 ) icnType = "background-image:url(css/images/icn-word.png);"; - else if(tmpType.indexOf("application/pdf") >=0 ) icnType = "background-image:url(css/images/icn-pdf.png);"; - else if(tmpType.indexOf("application/") >=0 ) icnType = "background-image:url(css/images/icn-document.png);"; - else if(tmpType.indexOf("audio/") >=0 ) icnType = "background-image:url(css/images/icn-music.png);"; - else if(tmpType.indexOf("image/") >=0 ) icnType = "background-image:url(css/images/icn-image.png);"; - else if(tmpType.indexOf("text/x-vcard") >=0 ) icnType = "background-image:url(css/images/icn-user.png);"; - else if(tmpType.indexOf("text/") >=0 ) icnType = "background-image:url(css/images/icn-document.png);"; - else if(tmpType.indexOf("video/") >=0 ) icnType = "background-image:url(css/images/icn-video.png);"; - - var typeTxt = tmpType.split("/")[1].replace(/marker/g, "note"); - - var htmlHighlight = ""; - htmlHighlight += "<div draggable=true class='flattentimeline_item flattentimeline_highlightitem' style='"+colorTransp+" "+styleImage+"'>"; - htmlHighlight += "<div class='flattentimeline_title' style='" + textColor + "' title='" + tag.getMetadata("Rekall->Name") + "'>" + tag.getMetadata("Rekall->Name") + "</div>"; - - - if(tag.getMetadata("Rekall->Comments")!="") { - - var tmpComments = tag.getMetadata("Rekall->Comments"); - if(tmpComments.length>150){ - tmpComments = tmpComments.substring(0, 150) + "..."; - } - - var tmpcount = 0; - var tmpIndex = tmpComments.indexOf("<br/>"); - while((tmpcount<3)&&(tmpIndex!=-1)) { - tmpcount++; - tmpIndex = tmpComments.indexOf("<br/>",tmpIndex+1); - } - if(tmpIndex!=-1) { - tmpComments = tmpComments.substring(0, tmpIndex) + "..."; - } - htmlHighlight += "<div class='flattentimeline_description'>" + tmpComments + "</div>"; - } - - if(tag.getMetadata("Rekall->Author")!="") htmlHighlight += "<div class='flattentimeline_author'>" + tag.getMetadata("Rekall->Author") + "</div>"; - - - htmlHighlight += "<div class='flattentimeline_typeTxt' >" + typeTxt + "</div>"; - htmlHighlight += "<div class='flattentimeline_opacifiant' style='" + styleColor2 + "'></div>"; - htmlHighlight += "</div>"; - - tag.flattenTimelineDom = $(htmlHighlight); - tag.flattenTimelineDom.click(function(event) { - tag.openPopupEdit(); - }); - tag.flattenTimelineDom.on({ - dragstart: function(event) { - event.dataTransfer.setData("key", tag.document.key); - event.dataTransfer.setData("version", tag.version); - } - }); - - return tag.flattenTimelineDom; - - }); - - } else { - - //Dom - $('#flattentimeline').append(function() { - var styleColor = "background-color: " + tag.color + ";"; - var textColor = "color: " + tag.color + ";"; - var textColor2 = "color: rgba(255,255,255,.8)"; - var textColor3 = "color: rgba(0,0,0,.75);"; - - var colorTransp = styleColor.replace(/rgb/g, "rgba").replace(/\)/g, ",.75)"); + //Captions en popup + if (tag.isMarker()) { + captions.push({ + startTime: tag.getTimeStart() * 1000, + endTime: (tag.timeStart + max(2, tag.timeEnd - tag.timeStart)) * 1000, + position: "HB", + data: tag.getMetadata("Rekall->Name"), + alignment: "C", + css: { + "background-color": "black", + "font-familly": "OpenSans", + "color": tag.color, + }, + onCaptionChange: function () { + tag.openPopupEdit(); + } + }); + } - var styleColor2 = styleColor; - var styleImage = ""; - if(tag.thumbnail.url != undefined) { - styleImage = "background-image: url(" + tag.thumbnail.url + ");"; - } else styleImage = "background-color: rgba(255,255,255,.25)"; + //Analyse de vignettes + let thumbUrl = Utils.getPreviewPath(tag); + tag.thumbnail = {url: thumbUrl, tag: tag}; - var icnType = ""; - var tmpType = tag.getMetadata("Rekall->Type"); - if(tmpType.indexOf("application/msword") >=0 ) icnType = "background-image:url(css/images/icn-word.png);"; - else if(tmpType.indexOf("application/pdf") >=0 ) icnType = "background-image:url(css/images/icn-pdf.png);"; - else if(tmpType.indexOf("application/") >=0 ) icnType = "background-image:url(css/images/icn-document.png);"; - else if(tmpType.indexOf("audio/") >=0 ) icnType = "background-image:url(css/images/icn-music.png);"; - else if(tmpType.indexOf("image/") >=0 ) icnType = "background-image:url(css/images/icn-image.png);"; - else if(tmpType.indexOf("text/x-vcard") >=0 ) icnType = "background-image:url(css/images/icn-user.png);"; - else if(tmpType.indexOf("text/") >=0 ) icnType = "background-image:url(css/images/icn-document.png);"; - else if(tmpType.indexOf("video/") >=0 ) icnType = "background-image:url(css/images/icn-video.png);"; - + $('#flattentimeline').append(tag.createTimelineDiv.call(tag)); - var html = ""; - html += "<div draggable=true class='flattentimeline_item' title='" + tag.getMetadata("Rekall->Comments") + "' >"; - html += "<div class='flattentimeline_image' style='" + styleImage + "'></div>"; - html += "<div class='flattentimeline_opacifiant' style='" + styleColor2 + "'></div>"; - html += "<div class='flattentimeline_type' style='" + icnType +"' title='" + tmpType + "'></div>"; - html += "<div class='flattentimeline_title' style='" + textColor2 + "' title='" + tag.getMetadata("Rekall->Name") + "'>" + tag.getMetadata("Rekall->Name") + "</div>"; - html += "</div>"; + //Ouverture du popup + if ((Tag.keyToOpenAfterLoading != undefined) && (tag.document.key == Tag.keyToOpenAfterLoading)) { + tag.openPopupEdit(); + Tag.keyToOpenAfterLoading = undefined; + } + }); + } + this.rekall.timeline.updateFlattenTimeline(); - tag.flattenTimelineDom = $(html); - tag.flattenTimelineDom.click(function(event) { - tag.openPopupEdit(); - }); - tag.flattenTimelineDom.on({ - dragstart: function(event) { - event.dataTransfer.setData("key", tag.document.key); - event.dataTransfer.setData("version", tag.version); - } - }); - - return tag.flattenTimelineDom; - - }); - } - - //Ouverture du popup - if((Tag.keyToOpenAfterLoading != undefined) && (tag.document.key == Tag.keyToOpenAfterLoading)) { - tag.openPopupEdit(); - Tag.keyToOpenAfterLoading = undefined; - } - }); - } - rekall.timeline.updateFlattenTimeline(); + //Initialisation des captions + if (this.rekall.videoPlayer.caption.updateCaption == undefined) { + this.rekall.videoPlayer.caption({ + data: captions, + setting: { + captionSize: 3, + captionStyle: { + 'background-color': 'rgba(255,0,0,0.8)', + 'color': 'white', + 'padding': '3px', + 'font-family': 'OpenSans', + }, + onCaptionChange: function (num_c) { + } + } + }); + } else if ((captions) && (captions.length > 0)) { + this.rekall.videoPlayer.caption.loadNewCaption({data: captions}); + } - //Initialisation des captions - if(rekall.videoPlayer.caption.updateCaption == undefined) { - rekall.videoPlayer.caption({ - data: captions, - setting: { - captionSize: 3, - captionStyle: { - 'background-color': 'rgba(255,0,0,0.8)', - 'color': 'white', - 'padding': '3px', - 'font-family': 'OpenSans', - }, - onCaptionChange: function(num_c) { - } - } - }); - } - else if((captions) && (captions.length > 0)) { - rekall.videoPlayer.caption.loadNewCaption({data: captions}); - } - - //Ajout des marqueurs sur la timeline - if(rekall.videoPlayer.markers.removeAll == undefined) { - rekall.videoPlayer.markers({ - markerStyle: { - 'width': '7px', - 'border-radius': '30%', - 'background-color': 'yellow' - }, - markerTip:{ - display: true, - text: function(marker) { - return marker.text; - }, - time: function(marker) { - return marker.time; - } - }, - breakOverlay:{ - display: false, - displayTime: 3, - style: { - 'width': '100%', - 'height': '20%', - 'background-color': 'rgba(0,0,0,0.7)', - 'color': 'white', - 'font-size': '17px' - }, - text: function(marker) { - return "Break overlay: " + marker.overlayText; - } - }, - onMarkerClick: function(marker) {}, - onMarkerReached: function(marker) {}, - markers: markers - }); - } - else - rekall.videoPlayer.markers.reset(markers); + //Ajout des marqueurs sur la timeline + if (this.rekall.videoPlayer.markers.removeAll == undefined) { + this.rekall.videoPlayer.markers({ + markerStyle: { + 'width': '7px', + 'border-radius': '30%', + 'background-color': 'yellow' + }, + markerTip: { + display: true, + text: function (marker) { + return marker.text; + }, + time: function (marker) { + return marker.time; + } + }, + breakOverlay: { + display: false, + displayTime: 3, + style: { + 'width': '100%', + 'height': '20%', + 'background-color': 'rgba(0,0,0,0.7)', + 'color': 'white', + 'font-size': '17px' + }, + text: function (marker) { + return "Break overlay: " + marker.overlayText; + } + }, + onMarkerClick: function (marker) { + }, + onMarkerReached: function (marker) { + }, + markers: markers + }); + } else { + this.rekall.videoPlayer.markers.reset(markers); + } } diff --git a/capsule-prototype/js/online-rekall/Rekall.js b/capsule-prototype/js/online-rekall/Rekall.js index 0f1449047b9fcd21c03f02aa6d9f0dd26251cf14..971ed994e585972f879df97e842ae97ee0b81e9e 100644 --- a/capsule-prototype/js/online-rekall/Rekall.js +++ b/capsule-prototype/js/online-rekall/Rekall.js @@ -23,125 +23,230 @@ */ function Rekall(options) { - this.sortings = new Object(); - this.sortings["horizontal"] = new Sorting("Time"); - this.sortings["colors"] = new Sorting("Rekall->Type", false, ""); - this.timeline = new Timeline(); - this.videoPlayer = undefined; - - function getDefaultBaseUrl() { - var oldURL = window.document.location + ""; - var url = oldURL; - var index = 0; - url = url.replace("pro-index.html", ""); - url = url.replace("online-index.html", ""); - url = url.replace("index.html", ""); - index = oldURL.indexOf('?'); - if(index == -1) - index = oldURL.indexOf('#'); - if(index != -1) - url = oldURL.substring(0, index); - if(!url.endsWith("/")) - url = url + "/"; - - return url; - } - - var defaultSettings = { - _allowProjectDeletion: false, - baseUrl: getDefaultBaseUrl() - } - - this.Settings = $.extend({}, defaultSettings, options); + this.sortings = new Object(); + this.sortings["horizontal"] = new Sorting("Time"); + this.sortings["colors"] = new Sorting("Rekall->Type", false, ""); + this.timeline = new Timeline(); + this.videoPlayer = undefined; + + function getDefaultBaseUrl() { + var oldURL = window.document.location + ""; + var url = oldURL; + var index = 0; + url = url.replace("pro-index.html", ""); + url = url.replace("online-index.html", ""); + url = url.replace("index.html", ""); + index = oldURL.indexOf('?'); + if (index == -1) + index = oldURL.indexOf('#'); + if (index != -1) + url = oldURL.substring(0, index); + if (!url.endsWith("/")) + url = url + "/"; + + return url; + } + + let defaultSettings = { + _allowProjectDeletion: false, + baseUrl: getDefaultBaseUrl() + } + + this.Settings = $.extend({}, defaultSettings, options); } -Rekall.prototype.allowProjectDeletion = function(){ - if (arguments.length <= 0 && 'boolean' !== typeof arguments[0]){ - return this.Settings._allowProjectDeletion; - } - - if (arguments[0]) { - this.Settings._allowProjectDeletion = true; - $('#popupSettingsBtnDelete').attr('display', null); - } - else { - this.Settings._allowProjectDeletion = false; - $('#popupSettingsBtnDelete').hide(); - } - this.Settings._allowProjectDeletion = arguments[0]; +Rekall.prototype.allowProjectDeletion = function () { + if (arguments.length <= 0 && 'boolean' !== typeof arguments[0]) { + return this.Settings._allowProjectDeletion; + } + + if (arguments[0]) { + this.Settings._allowProjectDeletion = true; + $('#popupSettingsBtnDelete').attr('display', null); + } else { + this.Settings._allowProjectDeletion = false; + $('#popupSettingsBtnDelete').hide(); + } + this.Settings._allowProjectDeletion = arguments[0]; } -Rekall.prototype.loadXMLFile = function() { - var oldURL = window.document.location + ""; - var index = 0; - var url = oldURL; - url = url.replace("pro-index.html", ""); - url = url.replace("online-index.html", ""); - url = url.replace("index.html", ""); - index = oldURL.indexOf('?'); - if(index == -1) - index = oldURL.indexOf('#'); - if(index != -1) - url = oldURL.substring(0, index); - if(!url.endsWith("/")) - url = url + "/"; - - if(!this.Settings._allowProjectDeletion){ - $('#popupSettingsBtnDelete').hide(); - }; - - this.baseUrl = url; - - var thiss = this; - rouletteStart(); - $.ajax("php/file.php?r=project.xml", { - type: "GET", - cache: false, - data: {"rand": random()}, - dataType: "xml", - success: function(xml) { - if((xml == null) || (xml == undefined)) - openAlert("Your project is unreachable. Did you move the folder to an other location?", 60); - else { - $(xml).find('project').each(function() { - //if($(this).find('document').length == 0) { - // openAlert("Start by adding files to your project.", 60); - //} else { - if(rekall.project == undefined) - rekall.project = new Project(url); - rekall.project.loadXML($(this)); - //} - }); - } - rouletteEnd(); - }, - error: function() { - $.ajax("file/project.xml", { - type: "GET", - cache: false, - data: {"rand": random()}, - dataType: "xml", - success: function(xml) { - if((xml == null) || (xml == undefined)) - openAlert("Your project is unreachable. Did you move the folder to an other location?", 60); - else { - $(xml).find('project').each(function() { - if($(this).find('document').length == 0) { - openAlert("Start by adding files to your project.", 60); - } else { - if(rekall.project == undefined) - rekall.project = new Project(url); - rekall.project.loadXML($(this)); - } - }); - } - rouletteEnd(); - }, - error: function() { - rouletteEnd(); - } - }); - rouletteEnd(); - } - }); -} \ No newline at end of file +Rekall.prototype.publish = function (eventName, data){ + return window.app.rekall.Rekall('pubSub').publish(eventName, data); +} + +Rekall.prototype.loadXMLFile = function () { + var oldURL = window.document.location + ""; + var index = 0; + var url = oldURL; + url = url.replace("pro-index.html", ""); + url = url.replace("online-index.html", ""); + url = url.replace("index.html", ""); + index = oldURL.indexOf('?'); + if (index == -1) + index = oldURL.indexOf('#'); + if (index != -1) + url = oldURL.substring(0, index); + if (!url.endsWith("/")) + url = url + "/"; + + if (!this.Settings._allowProjectDeletion) { + $('#popupSettingsBtnDelete').hide(); + } + + this.baseUrl = url; + + let that = this; + this.publish('roulette.started'); + $.ajax("php/file.php?r=project.xml", { + type: "GET", + cache: false, + data: {"rand": Math.random()}, + dataType: "xml", + success: function (xml) { + if ((xml == null) || (xml == undefined)) { + that.publish('alert', { + message: "Your project is unreachable. Did you move the folder to an other location?", + buttons: 60 + }); + } else { + $(xml).find('project').each(function () { + //if($(this).find('document').length == 0) { + // openAlert("Start by adding files to your project.", 60); + //} else { + if (that.project == undefined) + that.project = new Project(url, that); + that.project.loadXML($(this)); + //} + }); + } + that.publish('roulette.terminated', {}); + }, + error: function () { + $.ajax("file/project.xml", { + type: "GET", + cache: false, + data: {"rand": Math.random()}, + dataType: "xml", + success: function (xml) { + if ((xml == null) || (xml == undefined)) { + that.publish('alert', { + message: "Your project is unreachable. Did you move the folder to an other location?", + buttons: 60 + }); + } else { + $(xml).find('project').each(function () { + if ($(this).find('document').length == 0) { + that.publish('alert', { + message: "Start by adding files to your project.", + buttons: 60 + }); + } else { + if (that.project == undefined) + that.project = new Project(url, that); + that.project.loadXML($(this)); + } + }); + } + that.publish('roulette.terminated', {}); + }, + error: function () { + that.publish('roulette.terminated', {}); + } + }); + that.publish('roulette.terminated'); + } + }); +} + +Rekall.prototype.ensureVideoPlayerCreated = function (url, tech) { + if (undefined !== this.videoPlayer) + return false; + + let that = this; + let techOrder = ["vimeo", "youtube", "html5"]; + if (url.indexOf("youtube") >= 0) tech = "youtube"; + if (url.indexOf("youtu.be") >= 0) tech = "youtube"; + if (url.indexOf("vimeo") >= 0) tech = "vimeo"; + if (url.indexOf("dailymotion") >= 0) tech = "dailymotion"; + if (url.indexOf("dai.ly") >= 0) tech = "dailymotion"; + if ((tech !== "") && (tech !== undefined)) + techOrder = [tech, "html5"]; + + //Video + this.videoPlayer = videojs("video", { + "techOrder": techOrder, + "controls": true, + "autoplay": false, + "loop": "false", + "preload": "auto", + "sources": [ + { + "type": "video/" + tech, + "src": url + } + ] + }, function () { + $(".vjs-fullscreen-control").hide(); + + that.videoPlayer.on("durationchange", function () { + console.log("durationchange"); + that.project.analyse(); + that.videoPlayer.markers.initialize(); + }); + that.videoPlayer.on("ended", function () { + console.log("ended"); + }); + that.videoPlayer.on("error", function () { + console.log("error"); + }); + that.videoPlayer.on("firstplay", function () { + console.log("firstplay"); + }); + that.videoPlayer.on("fullscreenchange", function () { + console.log("fullscreenchange"); + }); + that.videoPlayer.on("loadedalldata", function () { + console.log("loadedalldata"); + }); + that.videoPlayer.on("loadeddata", function () { + console.log("loadeddata"); + }); + that.videoPlayer.on("loadedmetadata", function () { + console.log("loadedmetadata"); + that.project.analyse(); + }); + that.videoPlayer.on("loadstart", function () { + console.log("loadstart"); + }); + that.videoPlayer.on("pause", function () { + console.log("pause"); + }); + that.videoPlayer.on("play", function () { + console.log("play"); + }); + that.videoPlayer.on("progress", function () { + console.log("progress"); + }); + that.videoPlayer.on("seeked", function () { + console.log("seeked"); + }); + that.videoPlayer.on("seeking", function () { + console.log("seeking"); + }); + that.videoPlayer.on("timeupdate", function () { + console.log("timeupdate"); + that.timeline.update(that.videoPlayer.currentTime()); + }); + that.videoPlayer.on("volumechange", function () { + console.log("volumechange"); + }); + that.videoPlayer.on("waiting", function () { + console.log("waiting"); + }); + that.videoPlayer.on("resize", function () { + console.log("resize"); + }); + }); + + return true; +} diff --git a/capsule-prototype/js/online-rekall/RekallApplication.js b/capsule-prototype/js/online-rekall/RekallApplication.js index c214d4e070efd711ed12dd41534e6798ff399253..24b763baff26059b8d84014aeb7e3be198ab3c86 100644 --- a/capsule-prototype/js/online-rekall/RekallApplication.js +++ b/capsule-prototype/js/online-rekall/RekallApplication.js @@ -8,7 +8,8 @@ 'videoPlayer', 'rekall', 'getUrl', - 'projectName' + 'projectName', + 'mosaicWidget' ]; let localOptions = {}; @@ -25,6 +26,14 @@ $.extend(localOptions, opts); } }, + mosaicWidget : function (){ + if (!arguments.length){ + return localOptions.MosaicWidget; + } + if ('object' === typeof arguments[0] && null !== arguments[0]) { + localOptions.MosaicWidget = arguments[0]; + } + }, openUrl: function () { if (!arguments) return; diff --git a/capsule-prototype/js/online-rekall/Tag.js b/capsule-prototype/js/online-rekall/Tag.js index f6cd7fe6bfd0195d6e861e3b3cee41cf94f72d0b..5d0ac8cc30b2abc7162b49663b2458c76ddde113 100644 --- a/capsule-prototype/js/online-rekall/Tag.js +++ b/capsule-prototype/js/online-rekall/Tag.js @@ -23,125 +23,260 @@ */ function Tag(document) { - this.document = document; - this.documentOriginal = this.document; - this.version = document.currentVersion; - this.versionOriginal = this.version; - this.timeStart = 0; - this.timeEnd = 1; - this.color = "#FFFFFF"; - this.shown = false; + NotificationEntityChanged.call(this, {}); + this.document = document; + this.documentOriginal = this.document; + this.version = document.currentVersion; + this.versionOriginal = this.version; + this.timeStart = 0; + this.timeEnd = 1; + this.color = "#FFFFFF"; + this.shown = false; + this.thumbnail = undefined; } -Tag.keyToOpenAfterLoading = undefined; +Tag.prototype = Object.create(NotificationEntityChanged.prototype); + + +Tag.keyToOpenAfterLoading = undefined; -Tag.prototype.getMetadata = function(metadataKey, metadataValue) { - return this.document.getMetadata(metadataKey, this.version); +Tag.prototype.getMetadata = function (metadataKey, metadataValue) { + return this.document.getMetadata(metadataKey, this.version); } -Tag.prototype.setMetadata = function(metadataKey, metadataValue) { - return this.document.setMetadata(metadataKey, metadataValue, this.version); +Tag.prototype.setMetadata = function (metadataKey, metadataValue) { + let result = this.document.setMetadata(metadataKey, metadataValue, this.version); + this.notifyChange(); + return result; } -Tag.prototype.getMetadatas = function() { - return this.document.getMetadatas(this.version); +Tag.prototype.getMetadatas = function () { + return this.document.getMetadatas(this.version); } -Tag.prototype.isVideoOrAudio = function() { - return this.document.isVideoOrAudio(this.version); +Tag.prototype.isVideoOrAudio = function () { + return this.document.isVideoOrAudio(this.version); } -Tag.prototype.isAudio = function() { - return this.document.isAudio(this.version); +Tag.prototype.isAudio = function () { + return this.document.isAudio(this.version); } -Tag.prototype.isVideo = function() { - return this.document.isVideo(this.version); +Tag.prototype.isVideo = function () { + return this.document.isVideo(this.version); } -Tag.prototype.isMarker = function() { - return this.document.isMarker(this.version); +Tag.prototype.isMarker = function () { + return this.document.isMarker(this.version); } -Tag.prototype.isImage = function() { - return this.document.isImage(this.version); +Tag.prototype.isImage = function () { + return this.document.isImage(this.version); } -Tag.prototype.isLink = function() { - return this.document.isLink(this.version); +Tag.prototype.isLink = function () { + return this.document.isLink(this.version); } +Tag.prototype.getTagGradientColor = function() { + var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0; // Opera 8.0+ (UA detection to detect Blink/v8-powered Opera) + var isFirefox = typeof InstallTrigger !== 'undefined'; // Firefox 1.0+ + var isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0; // At least Safari 3+: "[object HTMLElementConstructor]" + var isChrome = !!window.chrome && !isOpera; // Chrome 1+ + var isIE = /*@cc_on!@*/false || !!document.documentMode; // At least IE6 -Tag.prototype.getTimeStart = function() { - return this.timeStart; + if (isOpera) { + return "-o-linear-gradient(right bottom, rgba(20,46,51,1) 0%, " + this.color + " 100%)"; + } + if (isFirefox) { + return "-moz-linear-gradient(right bottom, rgba(20,46,51,1) 0%, " + this.color + " 100%)"; + } + if ((isSafari) || (isChrome)) { + return "-webkit-linear-gradient(right bottom, rgba(20,46,51,1) 0%, " + this.color + " 100%)"; + } } -Tag.prototype.getTimeEnd = function() { - return this.timeEnd; +Tag.prototype.getTimeStart = function () { + return this.timeStart; } -Tag.prototype.setTimeStart = function(val) { - if(!isNaN(val)) - this.timeStart = val; +Tag.prototype.getTimeEnd = function () { + return this.timeEnd; } -Tag.prototype.setTimeEnd = function(val) { - if(!isNaN(val)) - this.timeEnd = val; +Tag.prototype.setTimeStart = function (val) { + if (!isNaN(val)) { + this.timeStart = val; + this.notifyChange(); + } } +Tag.prototype.setTimeEnd = function (val) { + if (!isNaN(val)) { + this.timeEnd = val; + this.notifyChange(); + } - - -Tag.prototype.isGoodVersion = function() { - return this.version == this.document.goodVersion; } - - -Tag.prototype.openFile = function() { - return this.document.openFile(); +Tag.prototype.isGoodVersion = function () { + return this.version == this.document.goodVersion; +} +Tag.prototype.openFile = function () { + return this.document.openFile(); +} +Tag.prototype.openFinder = function () { + return this.document.openFinder(); +} +Tag.prototype.openQuickLook = function () { + return this.document.openQuickLook(); } -Tag.prototype.openFinder = function() { - return this.document.openFinder(); +Tag.prototype.downloadFile = function () { + return this.document.downloadFile(); } -Tag.prototype.openQuickLook = function() { - return this.document.openQuickLook(); +Tag.prototype.getDownloadLink = function (original = false) { + return this.document.getDownloadLink(original); } -Tag.prototype.downloadFile = function() { - return this.document.downloadFile(); +Tag.prototype.getFileName = function () { + return this.document.getFileName(); } -Tag.prototype.getDownloadLink = function(original = false) { - return this.document.getDownloadLink(original); +Tag.prototype.openBrowser = function () { + return this.document.openBrowser(); } -Tag.prototype.getFileName = function() { - return this.document.getFileName(); +Tag.prototype.openPopupEdit = function () { + fillPopupEdit(this); } -Tag.prototype.openBrowser = function() { - return this.document.openBrowser(); -} -Tag.prototype.openPopupEdit = function() { - fillPopupEdit(this); +Tag.prototype.update = function (color, strong) { + if (color != undefined) { + this.colorRaw = color; + this.color = color.toString(); + this.isMarkerCache = this.isMarker(); + } + if (this.color == undefined) + this.color = "#000000"; } +Tag.prototype.createTimelineDiv = function () { + let that = this; + let styleColor = "background-color: " + this.color + ";"; + let textColor2 = "color: rgba(255,255,255,.8)"; -Tag.prototype.update = function(color, strong) { - if(color != undefined) { - this.colorRaw = color; - this.color = color.toString(); - - this.isMarkerCache = this.isMarker(); - /* - if(this.isMarkerCache) { - this.visuel.rect.setCornerRadius(0); - } - else { - this.visuel.rect.setCornerRadius(Tag.tagHeight/3); - } - */ - } - if(this.color == undefined) - this.color = "#000000"; + let styleColor2 = styleColor; + let styleImage = ""; + if (this.thumbnail.url != undefined) { + styleImage = "background-image: url(" + encodeURI(this.thumbnail.url) + ");"; + } else styleImage = "background-color: rgba(255,255,255,.25)"; + + let icnType = ""; + let tmpType = this.getMetadata("Rekall->Type"); + if (tmpType.indexOf("application/msword") >= 0) icnType = "background-image:url(css/images/icn-word.png);"; + else if (tmpType.indexOf("application/pdf") >= 0) icnType = "background-image:url(css/images/icn-pdf.png);"; + else if (tmpType.indexOf("application/") >= 0) icnType = "background-image:url(css/images/icn-document.png);"; + else if (tmpType.indexOf("audio/") >= 0) icnType = "background-image:url(css/images/icn-music.png);"; + else if (tmpType.indexOf("image/") >= 0) icnType = "background-image:url(css/images/icn-image.png);"; + else if (tmpType.indexOf("text/x-vcard") >= 0) icnType = "background-image:url(css/images/icn-user.png);"; + else if (tmpType.indexOf("text/") >= 0) icnType = "background-image:url(css/images/icn-document.png);"; + else if (tmpType.indexOf("video/") >= 0) icnType = "background-image:url(css/images/icn-video.png);"; + + + let html = ""; + html += "<div draggable=true class='flattentimeline_item' title='" + this.getMetadata("Rekall->Comments") + "' >"; + html += "<div class='flattentimeline_image' style='" + styleImage + "'></div>"; + html += "<div class='flattentimeline_opacifiant' style='" + styleColor2 + "'></div>"; + html += "<div class='flattentimeline_type' style='" + icnType + "' title='" + tmpType + "'></div>"; + html += "<div class='flattentimeline_title' style='" + textColor2 + "' title='" + this.getMetadata("Rekall->Name") + "'>" + this.getMetadata("Rekall->Name") + "</div>"; + html += "</div>"; + + this.flattenTimelineDom = $(html); + this.flattenTimelineDom.click(function () { + that.openPopupEdit(); + }); + this.flattenTimelineDom.on({ + dragstart: function (event) { + event.dataTransfer.setData("key", that.document.key); + event.dataTransfer.setData("version", that.version); + } + }); + + return this.flattenTimelineDom; - var fillColor = ''; - var strokeColor = ''; - var strokeWidth = 0; - var opacity = 1; - - if(this.isGoodVersion()) { - fillColor = this.color; - strokeWidth = 0; - strokeColor = ""; - } - else { - fillColor = tinycolor(this.colorRaw.toString()).setAlpha(0.1).toString(); - strokeColor = this.color; - strokeWidth = 0.8; - } } +Tag.prototype.getLabels = function () { + let labels = this.getMetadata('Rekall->Labels'); + if (!labels) + return []; + + let isStringNullOrWhitspace = function (s) { + if (typeof s !== "string" || !s) { + return false; + } + + return !s.trim(); + } + + return labels.split(';').filter(s => !isStringNullOrWhitspace(s)); +} + +function HighLightedTag(data) { + Tag.call(this, data.Document); +} + +HighLightedTag.prototype = Object.create(Tag.prototype); +HighLightedTag.prototype.createTimelineDiv = function () { + let that = this; + let styleColor = "background-color: " + this.color + ";"; + let textColor = "color: " + this.color + ";"; + + let colorTransp = ""; + + let styleColor2 = styleColor; + let styleImage = ""; + if (this.thumbnail?.url) { + styleImage = "background-image: -webkit-linear-gradient(right bottom, rgba(20,46,51,.60) 0%,rgba(20,46,51,.90) 100%), url(" + this.thumbnail.url + "); background-image: -moz-linear-gradient(right bottom, rgba(20,46,51,.60) 0%,rgba(20,46,51,.90) 100%), url(" + this.thumbnail.url + "); background-image: -o-linear-gradient(right bottom, rgba(20,46,51,.60) 0%,rgba(20,46,51,.90) 100%), url(" + this.thumbnail.url + ");"; + } else { + styleImage = "background-color: " + this.color + "; background-image: -webkit-linear-gradient(right bottom, rgba(20,46,51,.5) 0%,rgba(20,46,51,.8) 100%); background-image: -moz-linear-gradient(right bottom, rgba(20,46,51,.5) 0%,rgba(20,46,51,.8) 100%); background-image: -o-linear-gradient(right bottom, rgba(20,46,51,.5) 0%,rgba(20,46,51,.8) 100%);"; + } + + let tmpType = this.getMetadata("Rekall->Type"); + let typeTxt = tmpType.split("/")[1].replace(/marker/g, "note"); + + let htmlHighlight = ""; + htmlHighlight += "<div draggable=true class='flattentimeline_item flattentimeline_highlightitem' style='" + colorTransp + " " + styleImage + "'>"; + htmlHighlight += "<div class='flattentimeline_title' style='" + textColor + "' title='" + this.getMetadata("Rekall->Name") + "'>" + this.getMetadata("Rekall->Name") + "</div>"; + + + if (this.getMetadata("Rekall->Comments") != "") { + + let tmpComments = this.getMetadata("Rekall->Comments"); + if (tmpComments.length > 150) { + tmpComments = tmpComments.substring(0, 150) + "..."; + } + + let tmpcount = 0; + let tmpIndex = tmpComments.indexOf("<br/>"); + while ((tmpcount < 3) && (tmpIndex != -1)) { + tmpcount++; + tmpIndex = tmpComments.indexOf("<br/>", tmpIndex + 1); + } + if (tmpIndex != -1) { + tmpComments = tmpComments.substring(0, tmpIndex) + "..."; + } + htmlHighlight += "<div class='flattentimeline_description'>" + tmpComments + "</div>"; + } + + if (this.getMetadata("Rekall->Author") != "") htmlHighlight += "<div class='flattentimeline_author'>" + this.getMetadata("Rekall->Author") + "</div>"; + + + htmlHighlight += "<div class='flattentimeline_typeTxt' >" + typeTxt + "</div>"; + htmlHighlight += "<div class='flattentimeline_opacifiant' style='" + styleColor2 + "'></div>"; + htmlHighlight += "</div>"; + + this.flattenTimelineDom = $(htmlHighlight); + this.flattenTimelineDom.click(function () { + that.openPopupEdit(); + }); + this.flattenTimelineDom.on({ + dragstart: function (event) { + event.dataTransfer.setData("key", that.document.key); + event.dataTransfer.setData("version", that.version); + } + }); + + return this.flattenTimelineDom; +} + + +const TagFactory = function (document) { + + if (document.getMetadata("Rekall->Highlight", document.currentVersion)) { + return new HighLightedTag({document: document}) + } + + return new Tag(document); +} \ No newline at end of file diff --git a/capsule-prototype/js/online-rekall/Tags.js b/capsule-prototype/js/online-rekall/Tags.js index 6234ec74bcc725c1af7f660b4efb789e4bf17add..9a057be63c43c4fe09c98af8b39963800f6c8f8a 100644 --- a/capsule-prototype/js/online-rekall/Tags.js +++ b/capsule-prototype/js/online-rekall/Tags.js @@ -21,7 +21,39 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ -function Tags() { -} +const Tags = (function() { + let flattenTimelineTags; -Tags.flattenTimelineTags = new Array(); + function getFlattenTimeLineTags() { + if(!flattenTimelineTags){ + flattenTimelineTags = []; + } + + return flattenTimelineTags; + } + + function empty(){ + flattenTimelineTags = []; + } + + let sort = function() { + let localFlattenTimeline = getFlattenTimeLineTags(); + localFlattenTimeline.sort(function (a, b) { + if (a.timeStart < b.timeStart) return -1; + if (a.timeStart > b.timeStart) return 1; + return 0; + }); + } + + let push = function(value) { + let localFlattenTimeline = getFlattenTimeLineTags(); + localFlattenTimeline.push(value); + } + + return { + getFlattenTimeLineTags: getFlattenTimeLineTags, + reset: empty, + sort: sort, + push: push + } +})(); diff --git a/capsule-prototype/js/online-script.js b/capsule-prototype/js/online-script.js index 34d52382b1b0832faf8d114b7c12f38e1b0054b5..4cd35c149311ef296b2ac609a2c38fd8866949ee 100644 --- a/capsule-prototype/js/online-script.js +++ b/capsule-prototype/js/online-script.js @@ -1,6 +1,7 @@ var rekall = new Rekall(); var rekall_common = new Object(); var pubSub = null; +var popupPanel = new PopupPanelWidget({ canEdit: () => rekall_common.owner.canEdit }); window.onload = function() { pubSub = window.top.PubSub; @@ -11,10 +12,14 @@ window.onload = function() { pubSub.subscribe('video', openVideo); pubSub.subscribe('open_paste_modal', openPasteModal); pubSub.subscribe('close_paste_modal', closePasteModal); - pubSub.subscribe('updated.project.name', onUpdatedProjectName) -}; + pubSub.subscribe('updated.project.name', onUpdatedProjectName); + pubSub.subscribe('alert', openAlertWrapper); + pubSub.subscribe('roulette.terminated', rouletteEnd); + pubSub.subscribe('roulette.started', rouletteStart); + pubSub.subscribe('tag.metadata.updated', onMetaFromDomUpdated); + pubSub.subscribe('tag.tc.updated', onTcUpdated); + pubSub.subscribe('image.annotation.edit.open', openImageEdition); -$(document).ready(function() { window.app.rekall.Rekall('init', { Rekall: rekall }); @@ -99,11 +104,7 @@ $(document).ready(function() { $("#popupSpace").click(function(event){ event.stopPropagation(); - closeEdit(); - }); - $("#closePopupEdit").click(function(event){ - event.stopPropagation(); - closeEdit(); + popupPanel.close(); }); $("#popupAlertButtonCancel").click(function(){ @@ -129,53 +130,26 @@ $(document).ready(function() { var tmp = shareLink(); openAlert("input",tmp); }); -}); +}; function setEditionControls() { - $('#new_annotation_label').keypress(function(event) { - var keycode = (event.keyCode ? event.keyCode : event.which); - if (keycode != 13) { - return; - } - var label = $('#new_annotation_label').val(); - var input = $('input.annotation_labels_template').first().clone(); - var html_label = $('label.annotation_labels_template').first().clone(); - var id = 'annotation_label_' + Math.floor((Math.random()*1000)); - - input.attr('name', 'annotation_labels'); - input.attr('checked', 'true'); - input.attr('id', id); - input.attr('value', label); - - html_label.attr('for', id); - html_label.html(label); - - html_label.show(); - html_label.addClass('annotation_labels').removeClass('annotation_labels_template'); - input.addClass('annotation_labels').removeClass('annotation_labels_template'); - - $('#popupLabelsInput').append(input); - $('#popupLabelsInput').append(html_label); - $('#new_annotation_label').val(''); - }) - //Drag&drop files $(document).on({ - dragenter: function(event) { + dragenter: function (event) { event.stopImmediatePropagation(); event.preventDefault(); }, - dragleave: function(event) { + dragleave: function (event) { event.stopImmediatePropagation(); event.preventDefault(); }, - dragover: function(event) { + dragover: function (event) { event.stopImmediatePropagation(); event.preventDefault(); }, - drop: function(event) { - if(event.originalEvent.dataTransfer.files.length) { + drop: function (event) { + if (event.originalEvent.dataTransfer.files.length) { event.stopImmediatePropagation(); event.preventDefault(); uploadFiles(event.originalEvent.dataTransfer.files); @@ -184,18 +158,25 @@ function setEditionControls() { }); $("#flattentimeline").on({ - dragenter: function(event) { /*$(".flattentimeline_item").removeClass("draggable").addClass("drag");*/ }, - dragleave: function(event) { $("#flattentimeline").removeClass("draggable").removeClass("drag"); }, - dragover: function(event) { $("#flattentimeline").removeClass("draggable").addClass("drag"); }, - drop: function(event) { $("#flattentimeline").removeClass("draggable").removeClass("drag"); } + dragenter: function (event) { /*$(".flattentimeline_item").removeClass("draggable").addClass("drag");*/ + }, + dragleave: function (event) { + $("#flattentimeline").removeClass("draggable").removeClass("drag"); + }, + dragover: function (event) { + $("#flattentimeline").removeClass("draggable").addClass("drag"); + }, + drop: function (event) { + $("#flattentimeline").removeClass("draggable").removeClass("drag"); + } }); - $("#left_menu_item_settings").click(function(event){ + $("#left_menu_item_settings").click(function (event) { event.stopPropagation(); rekall.timeline.pause(); $("#popupSettingsSpace").show(); - if(window.app.rekall.Rekall('projectName') && window.app.rekall.Rekall('projectName') != "") { + if (window.app.rekall.Rekall('projectName') && window.app.rekall.Rekall('projectName') != "") { $("#popupSettingsTitle").html(window.app.rekall.Rekall('projectName')).removeClass("empty"); $("#popupSettingsTitleLabel").show(); } else { @@ -203,7 +184,7 @@ function setEditionControls() { $("#popupSettingsTitleLabel").hide(); } - if(rekall.project.metadata["Author"]!="") { + if (rekall.project.metadata["Author"] != "") { $("#popupSettingsAuthor").html(rekall.project.metadata["Author"]).removeClass("empty"); $("#popupSettingsAuthorLabel").show(); } else { @@ -211,7 +192,7 @@ function setEditionControls() { $("#popupSettingsAuthorLabel").hide(); } - if(rekall.project.metadata["Email"]!="") { + if (rekall.project.metadata["Email"] != "") { $("#popupSettingsEmail").html(rekall.project.metadata["Email"]).removeClass("empty"); $("#popupSettingsEmailLabel").show(); } else { @@ -219,7 +200,7 @@ function setEditionControls() { $("#popupSettingsEmailLabel").hide(); } - if(rekall.project.metadata["Comments"]!="") { + if (rekall.project.metadata["Comments"] != "") { $("#popupSettingsCredits").html(rekall.project.metadata["Comments"].replace(/\n/gi, "<br/>")).removeClass("empty"); $("#popupSettingsCreditsLabel").show(); } else { @@ -227,119 +208,123 @@ function setEditionControls() { $("#popupSettingsCreditsLabel").hide(); } - if(rekall_common.owner.canEdit) { + if (rekall_common.owner.canEdit) { $(".empty").show(); } }); - $("#popupSettingsTitleDiv").click(function(event){ + $("#popupSettingsTitleDiv").click(function (event) { event.stopPropagation(); closeSettingsInputs(); $(this).hide(); - if(!$("#popupSettingsTitle").hasClass("empty")) $("#popupSettingsTitleInput").val($("#popupSettingsTitle").html()); + if (!$("#popupSettingsTitle").hasClass("empty")) $("#popupSettingsTitleInput").val($("#popupSettingsTitle").html()); $("#popupSettingsTitleInput").show().focus(); }); - $("#popupSettingsAuthorDiv").click(function(event){ + $("#popupSettingsAuthorDiv").click(function (event) { event.stopPropagation(); closeSettingsInputs(); $(this).hide(); - if(!$("#popupSettingsAuthor").hasClass("empty")) $("#popupSettingsAuthorInput").val($("#popupSettingsAuthor").html()); + if (!$("#popupSettingsAuthor").hasClass("empty")) $("#popupSettingsAuthorInput").val($("#popupSettingsAuthor").html()); $("#popupSettingsAuthorInput").show().focus(); }); - $("#popupSettingsEmailDiv").click(function(event){ + $("#popupSettingsEmailDiv").click(function (event) { event.stopPropagation(); closeSettingsInputs(); $(this).hide(); - if(!$("#popupSettingsEmail").hasClass("empty")) $("#popupSettingsEmailInput").val($("#popupSettingsEmail").html()); + if (!$("#popupSettingsEmail").hasClass("empty")) $("#popupSettingsEmailInput").val($("#popupSettingsEmail").html()); $("#popupSettingsEmailInput").show().focus(); }); - $("#popupSettingsCreditsDiv").click(function(event){ + $("#popupSettingsCreditsDiv").click(function (event) { event.stopPropagation(); closeSettingsInputs(); $(this).hide(); - if(!$("#popupSettingsCredits").hasClass("empty")) $("#popupSettingsCreditsInput").val($("#popupSettingsCredits").html()); + if (!$("#popupSettingsCredits").hasClass("empty")) $("#popupSettingsCreditsInput").val($("#popupSettingsCredits").html()); $("#popupSettingsCreditsInput").show().focus(); }); - $(".popupSettingsInput").keyup(function(event){ + $(".popupSettingsInput").keyup(function (event) { event.stopPropagation(); - if(event.which == 13) { + if (event.which == 13) { closeSettingsInputs(); } }); - $(".popupSettingsInput").click(function(event){ - event.stopPropagation(); + $(".popupSettingsInput").click(function (event) { + event.stopPropagation(); }); - $("#popupSettingsCreditsInput").unbind( "keyup" ); - $("#popupSettingsCreditsInput").keyup(function(event){ + $("#popupSettingsCreditsInput").unbind("keyup"); + $("#popupSettingsCreditsInput").keyup(function (event) { event.stopPropagation(); var isEnter = false; if (event.key !== undefined) { if (event.key === 'Enter' && event.altKey) { - } else if(event.key === 'Enter') isEnter = true; + } else if (event.key === 'Enter') isEnter = true; } else if (event.keyIdentifier !== undefined) { if (event.keyIdentifier === "Enter" && event.altKey) { - } else if(event.keyIdentifier === 'Enter') isEnter = true; + } else if (event.keyIdentifier === 'Enter') isEnter = true; } else if (event.keyCode !== undefined) { if (event.keyCode === 13 && event.altKey) { - } else if(event.keyCode === 13) isEnter = true; + } else if (event.keyCode === 13) isEnter = true; } - if(isEnter == true) { + if (isEnter == true) { closeSettingsInputs(); } }); - $("#popupSettings").click(function(event){ + $("#popupSettings").click(function (event) { event.stopPropagation(); closeSettingsInputs(); }); - $("#popupSettingsSpace").click(function(event){ + $("#popupSettingsSpace").click(function (event) { event.stopPropagation(); closeSettingsPopup(); }); - $("#left_menu_item_preview").click(function(event){ + $("#left_menu_item_preview").click(function (event) { event.stopPropagation(); window.open(window.app.rekall.Rekall('getUrl', 'projectPreview'), '_blank'); }); - $("#popupSettingsBtnDownloadXml").click(function(event){ + $("#popupSettingsBtnDownloadXml").click(function (event) { event.stopPropagation(); window.open("php/project.php?downloadXML=1", '_self'); }); - $("#popupSettingsBtnDelete").click(function(event){ + $("#popupSettingsBtnDelete").click(function (event) { event.stopPropagation(); openAlert("Do you really want to delete this project ?", "yesnodeleteproject"); }); - $("#btn_add_note").click(function(event){ + $("#btn_add_note").click(function (event) { event.stopPropagation(); rekall.timeline.pause(); uploadFiles(["New note"]); }); - $("#btn_add_file").mousedown(function(event) { + $("#btn_add_file").mousedown(function (event) { rekall.timeline.pause(); $("#left_menu_item_btn_addfile").click(); }); - $("#left_menu_item_btn_addfile").change(function(event){ + $("#left_menu_item_btn_addfile").change(function (event) { event.stopPropagation(); uploadFiles($("#left_menu_item_btn_addfile").get(0).files); }); - $("#btn_add_paste").click(function(event) { pubSub.publish('open_paste_modal'); }); - $("#paste_modal button.cancel").click(function(event) { pubSub.publish('close_paste_modal'); }); + $("#btn_add_paste").click(function (event) { + pubSub.publish('open_paste_modal'); + }); + $("#paste_modal button.cancel").click(function (event) { + pubSub.publish('close_paste_modal'); + }); - $("#paste_modal_content").on("paste", function(event) { + $("#paste_modal_content").on("paste", function (event) { $('#paste_modal_content').empty(); }); - $("#paste_modal button.validate").click(function(event) { + $("#paste_modal button.validate").click(function (event) { var img = $("#paste_modal img"); if (img.length < 1) return; @@ -350,78 +335,80 @@ function setEditionControls() { var n = b64data.length; var uar = new Uint8Array(n); while (n--) uar[n] = bin_str.charCodeAt(n); - var file = new File([uar], 'pasted_' + Math.floor(Math.random()*100000) + '.' + subtype, {type: type+'/'+subtype}); + var file = new File([uar], 'pasted_' + Math.floor(Math.random() * 100000) + '.' + subtype, {type: type + '/' + subtype}); $('#left_menu_item_btn_addfile').files += file; uploadFiles([file]); pubSub.publish('close_paste_modal'); }); - $("#btn_add_link").click(function(event){ + $("#btn_add_link").click(function (event) { event.stopPropagation(); rekall.timeline.pause(); $("#popupAddLinkSpace").show(); $("#popupAddLinkInput").focus(); }); - $("#popupAddLinkButtonCancel").click(function(event){ + $("#popupAddLinkButtonCancel").click(function (event) { event.stopPropagation(); closeAddLinkPopup(); }); - $("#popupAddLinkSpace").click(function(event){ + $("#popupAddLinkSpace").click(function (event) { event.stopPropagation(); closeAddLinkPopup(); }); - $("#popupAddLinkButtonOk").click(function(event){ + $("#popupAddLinkButtonOk").click(function (event) { var myLink = $("#popupAddLinkInput").val(); addLink(myLink); }); - $("#popupAddLinkInput").keyup(function(event){ + $("#popupAddLinkInput").keyup(function (event) { event.stopPropagation(); - if(event.which == 13) { + if (event.which == 13) { var myLink = $("#popupAddLinkInput").val(); addLink(myLink); } }); - $('#tab_selector_form').change(function(event) { pubSub.publish(event.target.value) }); + $('#tab_selector_form').change(function (event) { + pubSub.publish(event.target.value) + }); - $("#popupEdit").click(function(event){ + $("#popupEdit").click(function (event) { event.stopPropagation(); closeInputs(); }); - $("#popupNom").click(function(event){ + $("#popupNom").click(function (event) { event.stopPropagation(); closeInputs(); $(this).hide(); $("#popupNomInput").show().focus(); }); - $("#popupTC").click(function(event){ + $("#popupTC").click(function (event) { event.stopPropagation(); closeInputs(); $("#popupTC").hide(); $("#popupTCedit").show(); }); - $(".popupTCeditfield").click(function(event){ + $(".popupTCeditfield").click(function (event) { event.stopPropagation(); }); - $("#nowTCin").click(function(event){ + $("#nowTCin").click(function (event) { event.stopPropagation(); var timeCurrent = convertToTime(Math.round(rekall.timeline.timeCurrent)); $("#popupTCinMin").val(timeCurrent.split(":")[0]); $("#popupTCinSec").val(timeCurrent.split(":")[1]); }); - $("#nowTCout").click(function(event){ + $("#nowTCout").click(function (event) { event.stopPropagation(); var timeCurrent = convertToTime(Math.round(rekall.timeline.timeCurrent)); $("#popupTCoutMin").val(timeCurrent.split(":")[0]); $("#popupTCoutSec").val(timeCurrent.split(":")[1]); }); - $("#eovTCout").click(function(event){ + $("#eovTCout").click(function (event) { event.stopPropagation(); var endVideo = rekall.videoPlayer.duration(); var timeEnd = convertToTime(Math.round(endVideo)); @@ -429,30 +416,30 @@ function setEditionControls() { $("#popupTCoutSec").val(timeEnd.split(":")[1]); }); - $("#TCvalidModif").click(function(event){ + $("#TCvalidModif").click(function (event) { event.stopPropagation(); var keyDoc = $(this).parent().parent().attr("keydoc"); var inMin = $("#popupTCinMin").val(); var inSec = $("#popupTCinSec").val(); var outMin = $("#popupTCoutMin").val(); var outSec = $("#popupTCoutSec").val(); - var TCin = (inMin*60)+(inSec*1); - var TCout = (outMin*60)+(outSec*1); + var TCin = (inMin * 60) + (inSec * 1); + var TCout = (outMin * 60) + (outSec * 1); var endVideo = Math.ceil(rekall.videoPlayer.duration()); - if(TCin>TCout) openAlert("Start time must be set before end time", "ok"); - else if(TCout>endVideo) openAlert("End time must not be set after " + convertToTime(endVideo) + " (end of the video)", "ok"); + if (TCin > TCout) openAlert("Start time must be set before end time", "ok"); + else if (TCout > endVideo) openAlert("End time must not be set after " + convertToTime(endVideo) + " (end of the video)", "ok"); else { setTCFromDom(keyDoc, TCin, TCout); - $("#popupTCin").html(inMin+":"+inSec); - $("#popupTCout").html(outMin+":"+outSec); + $("#popupTCin").html(inMin + ":" + inSec); + $("#popupTCout").html(outMin + ":" + outSec); closeInputs(); } }); - $("#TCinvalidModif").click(function(event){ + $("#TCinvalidModif").click(function (event) { event.stopPropagation(); var TCin = $("#popupTCin").html().split(":"); var TCout = $("#popupTCout").html().split(":"); @@ -463,71 +450,71 @@ function setEditionControls() { closeInputs(); }); - $("#popupLabels").click(function(event){ + $("#popupLabels").click(function (event) { event.stopPropagation(); closeInputs(); $(this).hide(); $("#popupLabelsInput").show().focus(); }); - $("#popupSpeed").click(function(event){ + $("#popupSpeed").click(function (event) { event.stopPropagation(); closeInputs(); $(this).hide(); $("#popupSpeedInput").show().focus(); }); - $("#popupLegende").click(function(event){ + $("#popupLegende").click(function (event) { event.stopPropagation(); closeInputs(); $(this).hide(); $("#popupLegendeInput").show().focus(); }); - $("#popupAuthor").click(function(event){ + $("#popupAuthor").click(function (event) { event.stopPropagation(); closeInputs(); $(this).hide(); $("#popupAuthorInput").show().focus(); }); - $("#popupLink").click(function(event){ + $("#popupLink").click(function (event) { event.stopPropagation(); closeInputs(); $(this).hide(); $("#popupLinkInput").show().focus(); }); - $(".popupInput").click(function(event){ + $(".popupInput").click(function (event) { event.stopPropagation(); }); - $("#popupNomInput").keyup(function(event){ + $("#popupNomInput").keyup(function (event) { event.stopPropagation(); - if(event.which == 13) { + if (event.which == 13) { closeInputs(); } }); - $("#popupAuthorInput").keyup(function(event){ + $("#popupAuthorInput").keyup(function (event) { event.stopPropagation(); - if(event.which == 13) { + if (event.which == 13) { closeInputs(); } }); - $("#popupLinkInput").keyup(function(event){ + $("#popupLinkInput").keyup(function (event) { event.stopPropagation(); - if(event.which == 13) { + if (event.which == 13) { closeInputs(); } }); - $("#popupSetHighlight").click(function(event){ + $("#popupSetHighlight").click(function (event) { event.stopPropagation(); var keyDoc = $(this).parent().attr("keydoc"); var isHL = $(this).attr("isHighlight"); - if(isHL=="true") { + if (isHL == "true") { setMetaFromDom(keyDoc, "Rekall->Highlight", ""); $(this).attr("isHighlight", "false").removeClass("selected"); $("#popupEdit").removeClass("highlightPopup"); @@ -539,45 +526,14 @@ function setEditionControls() { } }); - $("#popupEditSupprimer").click(function(){ + $("#popupEditSupprimer").click(function () { openAlert("Do you really want to delete this file from the project ?", "yesnodelete"); }); - $("#playback_speed_form").change(function(event) { - console.debug("set playback rate to " + event.target.value); - window.app.rekall.Rekall().videoPlayer.playbackRate(Number(event.target.value)); - }); - - $('#editAnnotationPic').click(function(ev) { - $('#edit_pic_modal').show(); - var keyDoc = ev.target.parentElement.parentElement.attributes['keydoc']; - var markerArea = new markerjs2.MarkerArea(document.getElementById('annotation_img_edit')); - markerArea.targetRoot = document.getElementById('edit_pic_modal'); - markerArea.addEventListener('render', (event) => { - var state = markerArea.getState(); - window.my_current_markerjs_data_in_ugly_global = state; - markerArea.close(true); - setMetaFromDom(keyDoc.value, "Rekall->MarkerjsState", btoa(JSON.stringify(state))); - - var b64img = event.dataUrl; - var data = b64img.match(/data:([a-z]+)\/([a-z]+);base64,(.*)/); - var type = data[1], subtype = data[2], b64data = data[3]; - var bin_str = atob(b64data); - var n = b64data.length; - var uar = new Uint8Array(n); - while (n--) uar[n] = bin_str.charCodeAt(n); - var file = new File([uar], keyDoc.value.substr(1), {type: type+'/'+subtype}); - $('#left_menu_item_btn_addfile').files = [file]; - uploadFiles([file], {'edited': 1}); - $('#popupImg').attr('src', $('#popupImg').attr('src') + '&time=' + performance.now()); - }); - markerArea.addEventListener('close', () => $('#edit_pic_modal').hide()); - markerArea.renderAtNaturalSize = true; - markerArea.show(); - if (window.my_current_markerjs_data_in_ugly_global) - markerArea.restoreState(window.my_current_markerjs_data_in_ugly_global); - - }) + $("#playback_speed_form").change(function (event) { + console.debug("set playback rate to " + event.target.value); + window.app.rekall.Rekall().videoPlayer.playbackRate(Number(event.target.value)); + }); } function closeSettingsPopup() { @@ -655,6 +611,10 @@ function openAlert(message, buttons) { } } +function openAlertWrapper(message, data){ + openAlert(data.message, data.buttons); +} + function closeAlert() { $("#popupAlertMessage").html(""); $(".popupAlertButton").hide(); @@ -729,382 +689,41 @@ function closeSettingsInputs() { } function closeInputs() { - $.each($(".popupInput"), function() { - if($(this).css("display") != "none") { - if($(this).attr("id")=="popupNomInput") { - - var keyDoc = $(this).parent().attr("keydoc"); - var newName = $(this).val().trim(); - $(this).val(newName); - setMetaFromDom(keyDoc, "Rekall->Name", newName); - - if(newName!="") $("#popupNom").html(newName).removeClass("empty"); - else $("#popupNom").html("+ Add a name").addClass("empty"); - - } else if($(this).attr("id")=="popupLegendeInput") { - - var keyDoc = $(this).parent().attr("keydoc"); - var newComment = $(this).val().trim(); - $(this).val(newComment); - setMetaFromDom(keyDoc, "Rekall->Comments", newComment.replace(/\n/gi, "<br/>")); - - if(newComment!="") $("#popupLegende").html(newComment.replace(/\n/gi, "<br/>")).removeClass("empty"); - else $("#popupLegende").html("+ Add a comment").addClass("empty"); - - } else if($(this).attr("id")=="popupSpeedInput") { - - var keyDoc = $(this).parent().attr("keydoc"); - var newSpeed = $('#popupSpeedInput input:checked').val(); - setMetaFromDom(keyDoc, "Rekall->Speed", newSpeed); - - } else if($(this).attr("id")=="popupLabelsInput") { - - var keyDoc = $(this).parent().attr("keydoc"); - var newLabels = ''; - $('input.annotation_labels:checked').toArray().forEach(e => newLabels += e.value + ';') - setMetaFromDom(keyDoc, "Rekall->Labels", newLabels); - - } else if($(this).attr("id")=="popupAuthorInput") { - - var keyDoc = $(this).parent().attr("keydoc"); - var newAuthor = $(this).val().trim(); - $(this).val(newAuthor); - setMetaFromDom(keyDoc, "Rekall->Author", newAuthor); - - if(newAuthor!="") $("#popupAuthor").html(newAuthor).removeClass("empty"); - else $("#popupAuthor").html("+ Add an author").addClass("empty"); - - } else if($(this).attr("id")=="popupLinkInput") { - - var keyDoc = $(this).parent().attr("keydoc"); - var newLink = $(this).val().trim(); - - if(newLink!="") if(newLink.indexOf("http")!=0) newLink = "http://"+newLink; - - $(this).val(newLink); - setMetaFromDom(keyDoc, "Rekall->Link", newLink); - - if(newLink!="") { - if(rekall_common.owner.canEdit) $("#popupLink").html(newLink).removeClass("empty"); - else $("#popupLink").html("<a href='"+newLink+"' target='_blank'>"+newLink+"</a>").removeClass("empty"); - } - else $("#popupLink").html("+ Add a link").addClass("empty"); - - } else if($(this).attr("id")=="popupTCedit") { - var keyDoc = $("#popupRight").attr("keydoc"); - var inMin = $("#popupTCinMin").val(); - var inSec = $("#popupTCinSec").val(); - var outMin = $("#popupTCoutMin").val(); - var outSec = $("#popupTCoutSec").val(); - var TCin = (inMin*60)+(inSec*1); - var TCout = (outMin*60)+(outSec*1); - - var endVideo = Math.ceil(rekall.videoPlayer.duration()); - - var isReturn = true; - - if((inMin>=120)||(inSec>=60)||(outMin>=120)||(outSec>=60)||(inMin<0)||(inSec<0)||(outMin<0)||(outSec<0)) openAlert("Invalid time code", "ok"); - else if(TCin>TCout) openAlert("Start time must be set before end time", "ok"); - else if(TCout>endVideo) openAlert("End time must not be set after " + convertToTime(endVideo) + " (end of the video)", "ok"); - else { - setTCFromDom(keyDoc, TCin, TCout); - $("#popupTCin").html(inMin+":"+inSec); - $("#popupTCout").html(outMin+":"+outSec); - isReturn = false; - } - if(isReturn) return true; - } - } - }); - $(".popupInput:not(.popupInputNoHide)").hide(); + popupPanel.ensureLastOpenedEditionClosed(); $(".popupRightItem").show(); - $("#popupTC").show(); - $("#popupTCedit").hide(); } function closeEdit() { - closeInputs(); - var isPaused = $("#popupEdit").attr("isPaused"); - if(isPaused=="false") rekall.timeline.play(); - $("#popupSpace").hide(); - $("#popupEdit").hide(); + popupPanel.close(); + window.app.rekall.Rekall('pubSub').publish('popupEdit.Closed', {}); } function openVideo() { - $('#mosaic_tab').hide(); - $('#video_tab').show(); - $('#left_menu_controls').show(); + window.app.rekall.Rekall('mosaicWidget').hide(); + $('#video_tab').show(); + $('#left_menu_controls').show(); } function openMosaic() { - function getMosaicItem(tagOrDoc) { - let path = Utils.getPreviewPath(tagOrDoc); - let name = tagOrDoc.getMetadata("Rekall->Name"); - let url =''; - if ('undefined' === typeof path) { - let [reg, type] = tagOrDoc.getMetadata("Rekall->Type").split('/'); - if (reg === 'rekall') { - if (type === 'marker') type = 'note'; - } - url = "../shared/css/images/img-"+type+".png"; - } else { - url = path; - } - let div=$('<div/>').addClass('mosaic_item').on('click', function() {tagOrDoc.openPopupEdit();}); - div.append($('<img/>').attr('src', url).attr('onerror', "this.src='../shared/css/images/img-document.png';")); - div.append($('<span/>').addClass('caption').text(name)); - div.attr('data-rekall-labels', ''); - div.attr('data-rekall-labels', tagOrDoc.getMetadata('Rekall->Labels')); - return div; - } - function getFilterElement(text, color, callback, css_class) { - return $('<div/>') - .addClass('mosaic_filter_item') - .addClass(css_class) - .on('click', callback) - .css('background-color', color) - .append($('<h2/>').text(text)); - } - - - rekall.timeline.pause(); - $('#mosaic_tab').show(); - $('#video_tab').hide(); - $('#left_menu_controls').hide(); - - let container = $('#mosaic_tab'); - container.html(''); - let filterdiv = $('<div/>').addClass('mosaic_filter'); - filterdiv.append(getFilterElement( - 'Reset filters', - 'rgb(100,100,100)', - function () { - $('.mosaic_filter_item').removeClass('mosaic_filter_disabled'); - $('.mosaic_category').show(); - }, - 'mosaic_filter_item_all' - )); - container.append(filterdiv); - var labels = new Set(); - // TODO is there a better way to iterate over tags or documents ? - for ( let [k, v] of Object.entries(rekall.sortings.colors.categories)) { - let categoryName = rekall.sortings.colors.getCategoryName(k) - let category = $('<div/>').addClass('mosaic_category').css('background', getTagGradientColor(v)); - - let grid = $('<div/>').addClass('mosaic_category_grid'); - - category.append($('<h2/>').text(categoryName)); - category.append(grid); - - filterdiv.append(getFilterElement( - categoryName, - v.color,function() { - category.toggle(); - $(this).toggleClass('mosaic_filter_disabled'); - }, - '' - )); - - for (let i in v.tags){ - grid.append(getMosaicItem(v.tags[i])); - var current_labels = v.tags[i].getMetadata('Rekall->Labels'); - if (current_labels && current_labels != '') { - current_labels.split(';').forEach(l => {if (l != '') labels.add(l)}); - } - } - container.append(category); - } - labels.forEach(l => { - var button = $('<p/>').html(l); - button.my_state = undefined; - button.addClass('mosaic_label_filter'); - button.click(ev => { - if (typeof(ev.target.my_state) === 'undefined') ev.target.my_state = true; - else ev.target.my_state = !ev.target.my_state; - if (ev.target.my_state) $(ev.target).addClass('mosaic_label_filter_enabled'); - else $(ev.target).removeClass('mosaic_label_filter_enabled'); - var labels = new Set(); - $('.mosaic_label_filter').toArray().forEach(f => { - if (f.my_state == true) - labels.add(f.innerHTML); - }); - if (!labels.size) { - $('.mosaic_label_filter').toArray().forEach(f => { - f.my_state = undefined; - $(f).removeClass('mosaic_label_filter_enabled'); - }); - } - console.debug('filters: ', labels); - $('.mosaic_item').toArray().forEach(t => { - if (!labels.size || Array.from(labels).map(l => t.dataset.rekallLabels.indexOf(l) != -1).includes(true)) - $(t).show(); - else - $(t).hide(); - }); - }) - filterdiv.append(button); - }); -} - -function getTagGradientColor(tag) { - var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0; // Opera 8.0+ (UA detection to detect Blink/v8-powered Opera) - var isFirefox = typeof InstallTrigger !== 'undefined'; // Firefox 1.0+ - var isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0; // At least Safari 3+: "[object HTMLElementConstructor]" - var isChrome = !!window.chrome && !isOpera; // Chrome 1+ - var isIE = /*@cc_on!@*/false || !!document.documentMode; // At least IE6 - - if(isOpera) { - return "-o-linear-gradient(right bottom, rgba(20,46,51,1) 0%, "+tag.color+" 100%)"; - } - if(isFirefox) { - return "-moz-linear-gradient(right bottom, rgba(20,46,51,1) 0%, "+tag.color+" 100%)"; - } - if((isSafari)||(isChrome)){ - return "-webkit-linear-gradient(right bottom, rgba(20,46,51,1) 0%, "+tag.color+" 100%)"; - } + $('#video_tab').hide(); + $('#left_menu_controls').hide(); + window.app.rekall.Rekall('mosaicWidget').show(); } function fillPopupEdit(tag) { - var isPaused = rekall.timeline.isPaused(); - rekall.timeline.pause(); - - $("#popupEdit").attr("isPaused",isPaused); - $("#popupTC").css("background",tag.color); - - var bgColorLeft = tag.color.replace(/rgb/g, "rgba").replace(/\)/g, ",.35)"); - - bgColorLeft = getTagGradientColor(tag); - - $("#popupLeft").css("background",bgColorLeft); - - var type = tag.getMetadata("Rekall->Type"); - - $("#popupImg").unbind( "click" ); - if(tag.isMarker()==true){ - $("#popupImg").show(); - $("#popupImg").attr("src","../shared/css/images/img-note.png"); - } else { - if(tag.thumbnail.url){ - $("#popupImg").attr("src", tag.getDownloadLink() || tag.thumbnail.url); - $('#annotation_img_edit').attr('src', tag.getDownloadLink(true)); - } else { - if(type.indexOf("image") > -1) $("#popupImg").attr("src","../shared/css/images/img-image.png") - else if(type.indexOf("pdf") > -1) $("#popupImg").attr("src","../shared/css/images/img-pdf.png") - else if(type.indexOf("audio") > -1) $("#popupImg").attr("src","../shared/css/images/img-music.png") - else if(type.indexOf("vcard") > -1) $("#popupImg").attr("src","../shared/css/images/img-user.png") - else if(type.indexOf("video") > -1) $("#popupImg").attr("src","../shared/css/images/img-video.png") - else if(type.indexOf("msword") > -1) $("#popupImg").attr("src","../shared/css/images/img-word.png") - else if(type.indexOf("link") > -1) $("#popupImg").attr("src","../shared/css/images/img-link.png") - else $("#popupImg").attr("src","../shared/css/images/img-document.png"); - } - $("#popupImg").click(function(event){ - event.stopPropagation(); - if(tag.isLink()) { - if(link != "") window.open(link,'_blank'); - } - else - window.open($('#popupImg')[0].src, '_blank'); - }); - } - - $("#popupNom").css("color",tag.color); - - window.my_current_markerjs_data_in_ugly_global = null; - $('#editAnnotationPic').hide(); - $('#linkToOriginalImage').hide(); - if (type.split('/')[0] == 'image') { - $('#editAnnotationPic').html('edit'); - $('#editAnnotationPic').show(); - $('#linkToOriginalImage').show(); - $('#linkToOriginalImage').unbind('click'); - $('#linkToOriginalImage').click(() => window.open(tag.getDownloadLink(true), '_blank')); - var data = tag.getMetadata('Rekall->MarkerjsState'); - if (data) - window.my_current_markerjs_data_in_ugly_global = JSON.parse(atob(data)); - } - - $("#popupType").html(type).css("color",tag.color); - - var name = tag.getMetadata("Rekall->Name"); - if(name!="") $("#popupNom").html(name).removeClass("empty"); - else $("#popupNom").html("+ Add a name").addClass("empty"); - - var startVerb = convertToTime(tag.getTimeStart()); - $("#popupTCin").html(startVerb); - - var endVerb = convertToTime(tag.getTimeEnd()); - $("#popupTCout").html(endVerb); - - var speed = tag.getMetadata("Rekall->Speed"); - if (!speed || speed == '') - speed = 1; - $('#popupSpeedInput input').attr('checked', false); - $('#popupSpeedInput input[value="'+speed+'"]').attr('checked', true); - - var labels = tag.getMetadata("Rekall->Labels"); - $('input.annotation_labels').attr('checked', false); - if (labels && labels != '') { - var _labels = labels.split(';'); - $('input.annotation_labels').toArray().forEach(e => { - e.checked = (_labels.indexOf(e.value) != -1); - }) - } - - var comments = tag.getMetadata("Rekall->Comments"); - if((comments)&&(comments!="")) $("#popupLegende").html(comments).removeClass("empty"); - else $("#popupLegende").html("+ Add a comment").addClass("empty"); - - var author = tag.getMetadata("Rekall->Author"); - if((author)&&(author!="")) $("#popupAuthor").html(author).removeClass("empty"); - else $("#popupAuthor").html("+ Add an author").addClass("empty"); - - var link = tag.getMetadata("Rekall->Link"); - if((link)&&(link!="")) { - if(rekall_common.owner.canEdit) $("#popupLink").html(link).removeClass("empty"); - else $("#popupLink").html("<a href='"+link+"' target='_blank'>"+link+"</a>").removeClass("empty"); - } - else $("#popupLink").html("+ Add a link").addClass("empty"); + popupPanel.createPopupContent(tag); if(rekall_common.owner.canEdit) { - if(tag.isMarker()==true) $("#popupEditSupprimer").html("Delete Note"); - else $("#popupEditSupprimer").html("Delete File"); - $(".empty").show(); $(".displayMode").hide(); - $("#popupNomInput").val(tag.getMetadata("Rekall->Name")); - - $("#popupTCinMin").val(startVerb.split(":")[0]); - $("#popupTCinSec").val(startVerb.split(":")[1]); - - $("#popupTCoutMin").val(endVerb.split(":")[0]); - $("#popupTCoutSec").val(endVerb.split(":")[1]); - - $("#popupLegendeInput").val(""+comments.replace(/<br\/>/gi, '\n')); - $("#popupAuthorInput").val(""+author); - $("#popupLinkInput").val(""+link); - $("#popupSpeedInput").val(""+speed); - - var highlight = tag.getMetadata("Rekall->Highlight"); - if(highlight=="true") { - $("#popupSetHighlight").attr("isHighlight","true").addClass("selected"); - $("#popupEdit").addClass("highlightPopup"); - } - else { - $("#popupSetHighlight").attr("isHighlight","false").removeClass("selected"); - $("#popupEdit").removeClass("highlightPopup"); - } } else { $(".empty").hide(); $(".editmode").hide(); $(".displayMode").show(); } - $("#popupLeft") .attr("keydoc", tag.document.key); - $("#popupRight").attr("keydoc", tag.document.key); - - $("#popupSpace").show(); - $("#popupEdit").show(); + popupPanel.show(); } function convertToTime(seconds) { @@ -1171,6 +790,14 @@ function setMetaFromDom(keyDoc, metaType, meta) { }); } +function onMetaFromDomUpdated(message, data){ + setMetaFromDom(data.tag.document.key, data.metadata, data.tag.getMetadata(data.metadata)); +} + +function onTcUpdated(message, data){ + setTCFromDom(data.tag.document.key, data.tag.getTimeStart(), data.tag.getTimeEnd()); +} + function setTCFromDom(keyDoc, TCin, TCout) { rouletteStart(); $.ajax("php/project.php", { @@ -1209,12 +836,12 @@ function deleteFromDom(keyDoc) { function deleteFromDomFinished() { closeAlert(); - closeEdit(); + popupPanel.close(); } //Gestion d'upload var filesToUpload = [], fileIsUploading = false; -function uploadFiles(files, additionnal_post_data={}) { +function uploadFiles(files, additionnal_post_data={}, callBack = undefined) { $.each(files, function(index, file) { var formData = new FormData(); @@ -1251,7 +878,7 @@ function uploadFiles(files, additionnal_post_data={}) { formData.append("author", rekall_common.owner.author); formData.append("locationGps", rekall_common.owner.locationGps); formData.append("locationName", rekall_common.owner.locationName); - Object.keys(additionnal_post_data).forEach(k => formData.append(k, additionnal_post_data[k])); + Object.keys(additionnal_post_data).forEach(k => formData.append(k, additionnal_post_data[k])); if(formData != undefined) { filesToUpload.push({ @@ -1287,6 +914,9 @@ function uploadFiles(files, additionnal_post_data={}) { rouletteEnd(); uploadFilesNext(); + if(callBack && typeof callBack === 'function'){ + callBack(); + } }, error: function(data) { openAlert("Uploading error. Try again."); @@ -1295,6 +925,9 @@ function uploadFiles(files, additionnal_post_data={}) { rouletteEnd(); uploadFilesNext(); + if(callBack && typeof callBack === 'function'){ + callBack(); + } } }); uploadFilesNext(); @@ -1374,3 +1007,63 @@ $(window).trigger("resize"); function openPasteModal() { $('#paste_modal').css('display', 'flex'); $('#paste_modal_content').first().focus() } function closePasteModal() { $('#paste_modal').hide(); $('#paste_modal_content').empty(); } +function openImageEdition(message, tag) { + $('#edit_pic_modal').show(); + let keyDoc = tag.document.key; + let annotationEdit = $('#annotation_img_edit')[0]; + $('#annotation_img_edit').attr('src', tag.getDownloadLink(true)); + + function loadImage(url, elem) { + return new Promise((resolve, reject) => { + elem.onload = () => resolve(elem); + elem.onerror = reject; + elem.src = url; + }); + } + function openMakerArea() { + // eslint-disable-next-line no-empty + let markerArea = new markerjs2.MarkerArea($('#annotation_img_edit')[0]); + let imageState; + + if (tag.getMetadata("Rekall->MarkerjsState") && tag.getMetadata("Rekall->MarkerjsState").trim().length) { + imageState = JSON.parse(atob(tag.getMetadata("Rekall->MarkerjsState"))); + } + + markerArea.targetRoot = document.getElementById('edit_pic_modal'); + markerArea.addEventListener('render', (event) => { + imageState = markerArea.getState(); + markerArea.close(true); + tag.setMetadata("Rekall->MarkerjsState", btoa(JSON.stringify(imageState))); + + let b64img = event.dataUrl; + let data = b64img.match(/data:([a-z]+)\/([a-z]+);base64,(.*)/); + let type = data[1], subtype = data[2], b64data = data[3]; + let bin_str = atob(b64data); + let n = b64data.length; + let uar = new Uint8Array(n); + while (n--) uar[n] = bin_str.charCodeAt(n); + let file = new File([uar], keyDoc.substr(1), {type: type + '/' + subtype}); + $('#left_menu_item_btn_addfile').files = [file]; + uploadFiles([file], {'edited': 1}, function () { + $('#popupImg').attr('src', tag.getDownloadLink()); + }); + setMetaFromDom(tag.document.key, "Rekall->MarkerjsState", tag.getMetadata('Rekall->MarkerjsState')); + }); + + markerArea.addEventListener('close', () => { + $('#edit_pic_modal').hide(); + }); + markerArea.renderAtNaturalSize = true; + markerArea.show(); + if (imageState) + markerArea.restoreState(imageState); + } + + async function changeImageSrc() { + await loadImage(tag.getDownloadLink(true), annotationEdit); + openMakerArea(); + } + + // noinspection JSIgnoredPromiseFromCall + changeImageSrc(); +} diff --git a/capsule-prototype/js/rekall/Document.js b/capsule-prototype/js/rekall/Document.js index f06c3ba2a28ebff72c67ad5c36c079a063531700..cb4a3d73cf87af6d07efa22660cd078f05ac9a3b 100644 --- a/capsule-prototype/js/rekall/Document.js +++ b/capsule-prototype/js/rekall/Document.js @@ -21,14 +21,19 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ -function Document() { +function Document(data) { + NotificationEntityChanged.call(this, {}); this.tags = new Array(); this.metadatas = new Array(); this.currentVersion = 0; this.goodVersion = 0; this.setMetadata("Rekall->Group", ""); this.setMetadata("Rekall->Visibility", ""); + this.project = data.project; } + +Document.prototype = Object.create(NotificationEntityChanged.prototype); + Document.prototype.addTag = function(tag) { this.tags.push(tag); } @@ -47,6 +52,7 @@ Document.prototype.getMetadatas = function(version) { Document.prototype.setMetadatas = function(metadatas, version) { version = this.initMetadatas(); this.metadatas[version] = metadatas; + this.notifyChange(); } Document.prototype.isVideoOrAudio = function(version) { return this.isAudio(version) || this.isVideo(version); @@ -88,13 +94,19 @@ Document.prototype.isLink = function(version) { } Document.prototype.getDownloadLink = function(original = false) { var path = Utils.getLocalFilePath(this, "file"); - return original ? path.replace('file.php?r=', 'file.php?r=rk_original_af7ef02e_') : path; + return original ? path.replace('file.php?r=', 'file.php?r=rk_original_af7ef02e_') : path + '&timegeneration=' + performance.now(); } Document.prototype.getFileName = function() { var path = Utils.getLocalFilePath(this, "file"); return path.replace(/.*r=(.*)/, (f, m) => m); } +Document.prototype.getLabels = function() { + let labels = this.project.labels; + if (!labels) + return []; + return labels; +} Document.availableMetadataKeys = new Object(); @@ -120,6 +132,9 @@ Document.prototype.setMetadata = function(metadataKey, metadataValue, version) { Document.availableMetadataKeys[metadataKey] = {count: 0}; Document.availableMetadataKeys[metadataKey].count++; } + if(currentValue != metadataValue) { + this.notifyChange(); + } return (currentValue != metadataValue); } @@ -152,7 +167,7 @@ Document.prototype.addVersion = function(document) { for (var index in this.tags) { var tag = this.tags[index]; if(tag.version == thisVersion) { - var newTag = new Tag(this); + var newTag = TagFactory(this); newTag.timeStart = tag.getTimeStart(); newTag.timeEnd = tag.getTimeEnd(); this.addTag(newTag); diff --git a/capsule-prototype/js/rekall/Sorting.js b/capsule-prototype/js/rekall/Sorting.js index 614f7e0ee9dd43f4d7dde03e6d566d3af5ab635b..0829e4c9785b9ae314889a5cf39bf9584fdaa2c4 100644 --- a/capsule-prototype/js/rekall/Sorting.js +++ b/capsule-prototype/js/rekall/Sorting.js @@ -108,9 +108,9 @@ Sorting.prototype.analyseStart = function(tags) { this.valMin = 0; else { this.categoriesIndex = 0; - for (var key in this.categories) { + for (let key in this.categories) { this.categories[key].shoudBeRemoved = true; - this.categories[key].tags = new Array(); + this.categories[key].tags = []; } } } diff --git a/capsule-prototype/js/rekall/Source.js b/capsule-prototype/js/rekall/Source.js index 7a1e631cb3b436f6ec9c31372231c814c2b96bcc..58080ed262002951a4cff5f97f867416f6d5b4a3 100644 --- a/capsule-prototype/js/rekall/Source.js +++ b/capsule-prototype/js/rekall/Source.js @@ -35,7 +35,7 @@ Source.prototype.addDocument = function(document) { if(this.documents[document.key] == undefined) { if(document.tags.length == 0) { - var tag = new Tag(document); + var tag = TagFactory(document); document.addTag(tag); } document.metadatas[-1] = document.cloneMetadatas(); diff --git a/capsule-prototype/js/shared.js b/capsule-prototype/js/shared.js new file mode 100644 index 0000000000000000000000000000000000000000..bb434ceb51e5245850616d856cc33b81429d2a50 --- /dev/null +++ b/capsule-prototype/js/shared.js @@ -0,0 +1,17 @@ +function getTagGradientColor(tag) { + var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0; // Opera 8.0+ (UA detection to detect Blink/v8-powered Opera) + var isFirefox = typeof InstallTrigger !== 'undefined'; // Firefox 1.0+ + var isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0; // At least Safari 3+: "[object HTMLElementConstructor]" + var isChrome = !!window.chrome && !isOpera; // Chrome 1+ + var isIE = /*@cc_on!@*/false || !!document.documentMode; // At least IE6 + + if (isOpera) { + return "-o-linear-gradient(right bottom, rgba(20,46,51,1) 0%, " + tag.color + " 100%)"; + } + if (isFirefox) { + return "-moz-linear-gradient(right bottom, rgba(20,46,51,1) 0%, " + tag.color + " 100%)"; + } + if ((isSafari) || (isChrome)) { + return "-webkit-linear-gradient(right bottom, rgba(20,46,51,1) 0%, " + tag.color + " 100%)"; + } +} \ No newline at end of file diff --git a/capsule-prototype/php/upload.php b/capsule-prototype/php/upload.php index 69de6b99bccabd7f334473ad56e905efa2f9f542..307ca5ee8b9cc60fa7856190c22347465234a075 100644 --- a/capsule-prototype/php/upload.php +++ b/capsule-prototype/php/upload.php @@ -62,7 +62,7 @@ //echo "Upload de ".$fileinfo."\t".$filename."..."; if(move_uploaded_file($_FILES[$fileinfo]['tmp_name'], $uploadFolder.$filename)) { if (!file_exists($uploadFolder.'rk_original_af7ef02e_'.$filename) && $_POST['edited'] != 1) { - copy($uploadFolder.$filename, $uploadFolder.'original_'.$filename); + copy($uploadFolder.$filename, $uploadFolder.'rk_original_af7ef02e_'.$filename); $metasAdded = addFileToProject($uploadFolder.$filename, $metas, $tcIn, $tcOut); $key = $metasAdded["key"]; unset($metasAdded["key"]);