From 03a84fe1272f070a191a17a7a597c510e65c1670 Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 5 Jun 2025 12:57:18 +0200 Subject: [PATCH 1/4] Add support for readOnly mode in API --- www/common/onlyoffice/inner.js | 25 +++++++++++++------------ www/common/sframe-app-framework.js | 7 ++++++- www/common/sframe-common-outer.js | 2 +- www/cryptpad-api.js | 1 + www/integration/main.js | 1 + 5 files changed, 22 insertions(+), 14 deletions(-) diff --git a/www/common/onlyoffice/inner.js b/www/common/onlyoffice/inner.js index 529dfd92c..b60b1b7b0 100644 --- a/www/common/onlyoffice/inner.js +++ b/www/common/onlyoffice/inner.js @@ -2136,6 +2136,19 @@ define([ } }; + const copy = (a, b) => { + Object.keys(b).forEach(k => { + if (k === "user") { return; } // Don't change user values + if (a[k]) { + if (typeof(a[k]) === "object" && typeof(b[k]) === "object") { + copy(a[k], b[k]); + } + return; + } + a[k] = b[k]; + }); + }; + const createOOConfig = function(blob, file, lock, fromContent, lang, force) { const url = URL.createObjectURL(blob); let username = Util.find(privateData, ['integrationConfig', 'user', 'name']) @@ -2185,18 +2198,6 @@ define([ } }; - let copy = (a, b) => { - Object.keys(b).forEach(k => { - if (k === "user") { return; } // Don't change user values - if (a[k]) { - if (typeof(a[k]) === "object" && typeof(b[k]) === "object") { - copy(a[k], b[k]); - } - return; - } - a[k] = b[k]; - }); - }; if (integrationConfig) { let ec = integrationConfig.editorConfig; let c = ooconfig.editorConfig.customization; diff --git a/www/common/sframe-app-framework.js b/www/common/sframe-app-framework.js index 75a934a7f..ea7733d4e 100644 --- a/www/common/sframe-app-framework.js +++ b/www/common/sframe-app-framework.js @@ -776,8 +776,13 @@ define([ }; var setFileImporter = function (options, fi, async) { - if (readOnly) { return; } + const priv = cpNfInner.metadataMgr.getPrivateData(); + const isReadOnlyIntegration = priv.isNewFile && + Boolean(priv.integrationConfig) && + priv.initialState; + if (readOnly && !isReadOnlyIntegration) { return; } fileImporter = function (c, f) { + console.error(state, STATE.READY, unsyncMode); if (state !== STATE.READY || unsyncMode) { return void UI.warn(Messages.disconnected); } diff --git a/www/common/sframe-common-outer.js b/www/common/sframe-common-outer.js index 4cb708ef3..a1a6a4eea 100644 --- a/www/common/sframe-common-outer.js +++ b/www/common/sframe-common-outer.js @@ -799,7 +799,7 @@ define([ origin: window.location.origin, pathname: window.location.pathname, fileHost: ApiConfig.fileHost, - readOnly: readOnly, + readOnly: cfg?.integrationConfig?.readOnly || readOnly, isTemplate: isTemplate, newTemplate: Array.isArray(Cryptpad.initialPath) && Cryptpad.initialPath[0] === "template", diff --git a/www/cryptpad-api.js b/www/cryptpad-api.js index 9efd6c569..ac185e945 100644 --- a/www/cryptpad-api.js +++ b/www/cryptpad-api.js @@ -135,6 +135,7 @@ document: blob, ext: config.document.fileType, autosave: config.events.onSave && (config.autosave || 10), + readOnly: config.mode === 'view', editorConfig: config.editorConfig || {}, _config: serializedConfig() }, function (obj) { diff --git a/www/integration/main.js b/www/integration/main.js index 0e8ca50be..4046d068c 100644 --- a/www/integration/main.js +++ b/www/integration/main.js @@ -240,6 +240,7 @@ define([ href: href, initialState: blob, config: { + readOnly: data.readOnly, fileName: data.name, fileType: data.ext, autosave: data.autosave, From 9658f4c21b4a894dacae2204b12b6279e9cee7c0 Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 5 Jun 2025 13:01:01 +0200 Subject: [PATCH 2/4] Document view/edit mode for the integration API --- www/cryptpad-api.js | 1 + 1 file changed, 1 insertion(+) diff --git a/www/cryptpad-api.js b/www/cryptpad-api.js index ac185e945..9a40d291b 100644 --- a/www/cryptpad-api.js +++ b/www/cryptpad-api.js @@ -270,6 +270,7 @@ * @param {function} events.onNewKey (data, callback) The function called when a new key is used. * @param {function} events.onInsertImage (data, callback) The function called the user wants to add an image. * @param {string} config.documentType The editor to load in CryptPad. + * @param {string} config.mode The editing state of the document to load ("view" or "edit", defaults to edit). * @return {promise} */ var init = function (cryptpadURL, containerId, config) { From fe5878b42e506b31852cd992de900e8e5468f9e6 Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 6 Jun 2025 13:52:52 +0200 Subject: [PATCH 3/4] lint compliance --- www/common/common-ui-elements.js | 22 ---------------------- www/common/cryptpad-common.js | 1 - www/common/onlyoffice/inner.js | 18 ++++-------------- www/common/toolbar.js | 2 +- www/profile/inner.js | 2 +- 5 files changed, 6 insertions(+), 39 deletions(-) diff --git a/www/common/common-ui-elements.js b/www/common/common-ui-elements.js index c3de21053..3ffb4f079 100644 --- a/www/common/common-ui-elements.js +++ b/www/common/common-ui-elements.js @@ -2830,7 +2830,6 @@ define([ var selected = 0; // Selected template in the list (highlighted) var TEMPLATES_DISPLAYED = big ? 6 : 3; // Max templates displayed per page - var next = function () {}; // Function called when pressing tab to highlight the next template var i = 0; // Index of the first template displayed in the current page sframeChan.query("Q_CREATE_TEMPLATES", type, function (err, res) { if (!res.data || !Array.isArray(res.data)) { @@ -2939,27 +2938,6 @@ define([ redraw(0); } - - // Change template selection when Tab is pressed - next = function (revert) { - var max = $creation.find('.cp-creation-template-element').length; - if (selected + 1 === max && !revert) { - selected = i + TEMPLATES_DISPLAYED < allData.length ? 0 : max; - return void redraw(i + TEMPLATES_DISPLAYED); - } - if (selected === 0 && revert) { - selected = i - TEMPLATES_DISPLAYED >= 0 ? TEMPLATES_DISPLAYED - 1 : 0; - return void redraw(i - TEMPLATES_DISPLAYED); - } - selected = revert ? - (--selected < 0 ? 0 : selected) : - ++selected >= max ? max-1 : selected; - $creation.find('.cp-creation-template-element') - .removeClass('cp-creation-template-selected'); - $($creation.find('.cp-creation-template-element').get(selected)) - .addClass('cp-creation-template-selected'); - }; - $w.on('resize', function () { var _big = $w.width() > 800; if (big === _big) { return; } diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index 234bb8515..32d887e74 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -1181,7 +1181,6 @@ define([ return; } - let rtChannel, lastVersion, answersChannel; let attributes = {}; nThen(function (waitFor) { if (parsed.hashData.type !== 'pad') { return; } diff --git a/www/common/onlyoffice/inner.js b/www/common/onlyoffice/inner.js index b60b1b7b0..a7f71d65f 100644 --- a/www/common/onlyoffice/inner.js +++ b/www/common/onlyoffice/inner.js @@ -306,6 +306,10 @@ define([ return; } delete hashes[lastIndex]; + APP.onLocal(); + APP.realtime.onSettle(function () { + UI.log(Messages.saved); + }); }; var rtChannel = { @@ -642,20 +646,6 @@ define([ }); } }; - var deleteLastCp = function () { - var hashes = content.hashes; - if (!hashes || !Object.keys(hashes).length) { return; } - var i = 0; - var idx = Object.keys(hashes).map(Number).sort(function (a, b) { - return a-b; - }); - var lastIndex = idx[idx.length - 1 - i]; - delete content.hashes[lastIndex]; - APP.onLocal(); - APP.realtime.onSettle(function () { - UI.log(Messages.saved); - }); - }; var restoreLastCp = function () { content.saveLock = myOOId; APP.onLocal(); diff --git a/www/common/toolbar.js b/www/common/toolbar.js index d5e6f34e7..a74bd9d77 100644 --- a/www/common/toolbar.js +++ b/www/common/toolbar.js @@ -427,7 +427,7 @@ MessengerUI, Messages, Pages, PadTypes) { $span.append($rightCol); }, data.uid); $span.data('uid', data.uid); - if (false && data.badge && data.edPublic) { // XXX 2025.6 + if (data.badge && data.edPublic) { const addBadge = (badge) => { let i = Badges.render(badge); if (!i) { return; } diff --git a/www/profile/inner.js b/www/profile/inner.js index 455595286..1f4723e4b 100644 --- a/www/profile/inner.js +++ b/www/profile/inner.js @@ -654,7 +654,7 @@ define([ addLink($rightside); addFriendRequest($rightside); addMuteButton($rightside); - //addBadges($rightside); // XXX 2025.6 + addBadges($rightside); addPublicKey($rightside); addCopyData($rightside); addViewButton($rightside); From d9150528298160b2f36690ac54af787b238b3e4a Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 13 Jun 2025 16:29:12 +0200 Subject: [PATCH 4/4] Add funding.json and FUNDING.json to .gitignore This may fix issues with case-insensitive file systems --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 346d62bce..78212683a 100644 --- a/.gitignore +++ b/.gitignore @@ -35,6 +35,9 @@ www/common/onlyoffice/v* www/common/worker.bundle.js _build +FUNDING.json +funding.json + # ---> Node # Logs logs