diff --git a/www/code/inner.js b/www/code/inner.js index 11f0fbf7e..fbb170e53 100644 --- a/www/code/inner.js +++ b/www/code/inner.js @@ -310,24 +310,11 @@ define([ editor: editor }); - var $removeAuthorColorsButton = framework._.sfCommon.createButton('removeauthorcolors', true, {icon: 'fa-paint-brush', title: 'Autorenfarben entfernen'}); // XXX - framework._.toolbar.$rightside.append($removeAuthorColorsButton); - $removeAuthorColorsButton.click(function() { - var selfrom = editor.getCursor("from"); - var selto = editor.getCursor("to"); - if (!editor.somethingSelected() || selfrom === selto) { - editor.getAllMarks().forEach(function (marker) { - marker.clear(); - }); - authormarks.authors = {}; - authormarks.marks = []; - } else { - editor.findMarks(selfrom, selto).forEach(function (marker) { - marker.clear(); - }); - } - framework.localChange(); - }); + var $showAuthorColorsButton = framework._.sfCommon.createButton('', true, { + icon: 'fa-paint-brush', + }).hide(); + framework._.toolbar.$rightside.append($showAuthorColorsButton); + markers.setButton($showAuthorColorsButton); var $print = $('#cp-app-code-print'); var $content = $('#cp-app-code-preview-content'); @@ -358,7 +345,7 @@ define([ } // Fix the markers offsets - markers.checkAuthors(newContent); + markers.checkMarks(newContent); // Apply the text content CodeMirror.contentUpdate(newContent); diff --git a/www/code/markers.js b/www/code/markers.js index 2092df781..459a6a856 100644 --- a/www/code/markers.js +++ b/www/code/markers.js @@ -6,19 +6,21 @@ define([ ], function (Util, SFCodeMirror, Messages, ChainPad) { var Markers = {}; - Messages.cba_writtenBy = 'Written by {0}'; - var MARK_OPACITY = 90; + + Messages.cba_writtenBy = 'Written by {0}'; // XXX + var addMark = function (Env, from, to, uid) { + if (!Env.enabled) { return; } var author = Env.authormarks.authors[uid] || {}; uid = Number(uid); var name = Util.fixHTML(author.name || Messages.anonymous); return Env.editor.markText(from, to, { inclusiveLeft: uid === Env.myAuthorId, inclusiveRight: uid === Env.myAuthorId, - css: "background-color: " + author.color + MARK_OPACITY, + css: "background-color: " + author.color + Env.opacity, attributes: { - title: Messages._getKey('cba_writtenBy', [name]), + title: Env.opacity ? Messages._getKey('cba_writtenBy', [name]) : undefined, 'data-type': 'authormark', 'data-uid': uid } @@ -60,6 +62,8 @@ define([ }; var updateAuthorMarks = function (Env) { + if (!Env.enabled) { return; } + // get author marks var _marks = []; var all = []; @@ -195,7 +199,8 @@ define([ } }; - var checkAuthors = function (Env, userDoc) { + var checkMarks = function (Env, userDoc) { + var chainpad = Env.framework._.cpNfInner.chainpad; var editor = Env.editor; var CodeMirror = Env.CodeMirror; @@ -203,6 +208,8 @@ define([ setAuthorMarks(Env, userDoc.authormarks); + if (!Env.enabled) { return; } + var authDoc = JSON.parse(chainpad.getAuthDoc() || '{}'); if (!authDoc.content || !userDoc.content) { return; } if (authDoc.content === userDoc.content) { return; } // No uncommitted work @@ -280,12 +287,14 @@ define([ }; var setMarks = function (Env) { - // on remote update: remove all marks, add new marks + // on remote update: remove all marks, add new marks if colors are enabled Env.editor.getAllMarks().forEach(function (marker) { if (marker.attributes && marker.attributes['data-type'] === 'authormark') { marker.clear(); } }); + + if (!Env.enabled) { return; } var authormarks = Env.authormarks; authormarks.marks.forEach(function (mark) { var uid = mark[0]; @@ -316,20 +325,24 @@ define([ }; var setMyData = function (Env) { + if (!Env.enabled) { return; } + var userData = Env.common.getMetadataMgr().getUserData(); var old = Env.authormarks.authors[Env.myAuthorId]; - if (!old || (old.name === userData.data && old.color === userData.color)) { return; } Env.authormarks.authors[Env.myAuthorId] = { name: userData.name, curvePublic: userData.curvePublic, color: userData.color }; + if (!old || (old.name === userData.name && old.color === userData.color)) { return; } return true; }; var localChange = function (Env, change, cb) { cb = cb || function () {}; + if (!Env.enabled) { return void cb(); } + if (change.origin === "setValue") { // If the content is changed from a remote patch, we call localChange // in "onContentUpdate" directly @@ -397,6 +410,31 @@ define([ cb(); }; + Messages.cba_show = "Show user colors"; // XXX + Messages.cba_hide = "Hide user colors"; // XXX + var setButton = function (Env, $button) { + var toggle = function () { + var tippy = $button[0] && $button[0]._tippy; + if (Env.opacity) { + Env.opacity = 0; + if (tippy) { tippy.title = Messages.cba_show; } + else { $button.attr('title', Messages.cba_show); } + $button.removeClass("cp-toolbar-button-active"); + } else { + Env.opacity = MARK_OPACITY; + if (tippy) { tippy.title = Messages.cba_hide; } + else { $button.attr('title', Messages.cba_hide); } + $button.addClass("cp-toolbar-button-active"); + } + }; + toggle(); + Env.$button = $button; + $button.click(function() { + toggle(); + setMarks(Env); + }); + }; + var authorUid = function (existing) { if (!Array.isArray(existing)) { existing = []; } var n; @@ -422,28 +460,55 @@ define([ }); return uid || authorUid(existing); }; - var ready = function (Env) { + var metadataMgr = Env.common.getMetadataMgr(); + var md = metadataMgr.getMetadata(); + Env.ready = true; Env.myAuthorId = getAuthorId(Env); - var changed = setMyData(Env); - if (changed) { - Env.framework.localChange(); + Env.enabled = md.enableColors; + + if (Env.enabled) { + if (Env.$button) { Env.$button.show(); } setMarks(Env); } }; Markers.create = function (config) { var Env = config; - setAuthorMarks(Env); + Env.authormarks = { + authors: {}, + marks: [] + }; + Env.enabled = false; Env.myAuthorId = 0; var metadataMgr = Env.common.getMetadataMgr(); metadataMgr.onChange(function () { + var md = metadataMgr.getMetadata(); + // If the state has changed in the pad, change the Env too + if (Env.enabled !== md.enableColors) { + Env.enabled = md.enableColors; + if (!Env.enabled) { + // Reset marks + Env.authormarks = { + authors: {}, + marks: [] + }; + setMarks(Env); + if (Env.$button) { Env.$button.hide(); } + } else { + Env.myAuthorId = getAuthorId(Env); + if (Env.$button) { Env.$button.show(); } + } + if (Env.ready) { Env.framework.localChange(); } + } + + if (!Env.enabled) { return; } // Update my data var changed = setMyData(Env); if (changed) { - Env.framework.localChange(); setMarks(Env); + Env.framework.localChange(); } }); @@ -457,13 +522,13 @@ define([ return { addMark: call(addMark), - setAuthorMarks: call(setAuthorMarks), getAuthorMarks: call(getAuthorMarks), updateAuthorMarks: call(updateAuthorMarks), - checkAuthors: call(checkAuthors), + checkMarks: call(checkMarks), setMarks: call(setMarks), localChange: call(localChange), ready: call(ready), + setButton: call(setButton) }; }; diff --git a/www/common/inner/properties.js b/www/common/inner/properties.js index 58f10e738..07193a679 100644 --- a/www/common/inner/properties.js +++ b/www/common/inner/properties.js @@ -50,6 +50,51 @@ define([ // File and history size... var owned = Modal.isOwned(Env, data); + var metadataMgr = common.getMetadataMgr(); + var priv = metadataMgr.getPrivateData(); + Messages.cba_properties = "Author colors (experimental)"; // XXX + Messages.cba_enable = "Enable author colors in this pad"; // XXX + Messages.cba_disable = "Clear all colors and disable"; // XXX + if (owned && priv.app === 'code') { + (function () { + var md = metadataMgr.getMetadata(); + var div = h('div'); + var $div = $(div); + var setButton = function (state) { + var button = h('button.btn'); + var $button = $(button); + $div.html('').append($button); + if (state) { + // Add "enable" button + $button.addClass('btn-secondary').text(Messages.cba_enable); + UI.confirmButton(button, { + classes: 'btn-primary' + }, function () { + $button.remove(); + var md = Util.clone(metadataMgr.getMetadata()); + md.enableColors = true; + metadataMgr.updateMetadata(md); + setButton(false); + }); + return; + } + // Add "disable" button + $button.addClass('btn-danger-alt').text(Messages.cba_disable); + UI.confirmButton(button, { + classes: 'btn-danger' + }, function () { + $button.remove(); + var md = Util.clone(metadataMgr.getMetadata()); + md.enableColors = false; + metadataMgr.updateMetadata(md); + setButton(true); + }); + }; + setButton(!md.enableColors); + $d.append(h('div.cp-app-prop', [Messages.cba_properties, h('br'), div])); + })(); + } + // check the size of this file, including additional channels var bytes = 0; var historyBytes;