From 6f2f40b9837f2accd67089a6bed9e1a5546e0a1a Mon Sep 17 00:00:00 2001 From: the-djmaze <> Date: Tue, 8 Oct 2024 17:49:21 +0200 Subject: [PATCH] Prepare for #1793 --- dev/Sieve/View/Filter.js | 2 +- dev/View/Popup/Compose.js | 38 ++++++++--------- plugins/send-save-in/LICENSE | 20 +++++++++ plugins/send-save-in/index.php | 23 +++++++++++ plugins/send-save-in/savein.js | 75 ++++++++++++++++++++++++++++++++++ 5 files changed, 138 insertions(+), 20 deletions(-) create mode 100644 plugins/send-save-in/LICENSE create mode 100644 plugins/send-save-in/index.php create mode 100644 plugins/send-save-in/savein.js diff --git a/dev/Sieve/View/Filter.js b/dev/Sieve/View/Filter.js index ee7799d75..41bf85998 100644 --- a/dev/Sieve/View/Filter.js +++ b/dev/Sieve/View/Filter.js @@ -66,7 +66,7 @@ export class FilterPopupView extends rl.pluginPopupView { }); this.defaultOptionsAfterRender = defaultOptionsAfterRender; - this.folderSelectList = koComputable(() => folderListOptionsBuilder()); + this.folderSelectList = koComputable(folderListOptionsBuilder); this.selectedFolderValue.subscribe(() => this.filter().actionValueError(false)); diff --git a/dev/View/Popup/Compose.js b/dev/View/Popup/Compose.js index 581ad9f21..302017dfb 100644 --- a/dev/View/Popup/Compose.js +++ b/dev/View/Popup/Compose.js @@ -457,10 +457,21 @@ export class ComposePopupView extends AbstractViewPopup { this.from(IdentityUserStore()[0].formattedName()); } - sendCommand() { - const identity = this.currentIdentity(); - let sSentFolder = identity?.sentFolder?.() || FolderUserStore.sentFolder(); + sentFolder() + { + let sSentFolder = this.currentIdentity()?.sentFolder?.() || FolderUserStore.sentFolder(); + if (SettingsUserStore.replySameFolder()) { + if ( + 3 === arrayLength(this.aDraftInfo) && + this.aDraftInfo[2]?.length + ) { + sSentFolder = this.aDraftInfo[2]; + } + } + return UNUSED_OPTION_VALUE === sSentFolder ? null : sSentFolder; + } + sendCommand() { this.attachmentsInProcessError(false); this.attachmentsInErrorError(false); this.emptyToError(false); @@ -478,16 +489,8 @@ export class ComposePopupView extends AbstractViewPopup { } if (!this.emptyToError() && !this.attachmentsInErrorError() && !this.attachmentsInProcessError()) { - if (SettingsUserStore.replySameFolder()) { - if ( - 3 === arrayLength(this.aDraftInfo) && - this.aDraftInfo[2]?.length - ) { - sSentFolder = this.aDraftInfo[2]; - } - } - - if (!sSentFolder) { + const sSentFolder = this.sentFolder(); + if ('' === sSentFolder) { showScreenPopup(FolderSystemPopupView, [FolderType.Sent]); } else { const sendError = e => { @@ -507,8 +510,6 @@ export class ComposePopupView extends AbstractViewPopup { this.sendError(false); this.sending(true); - sSentFolder = UNUSED_OPTION_VALUE === sSentFolder ? '' : sSentFolder; - const sendMessage = params => { Remote.request('SendMessage', (iError, data) => { @@ -538,7 +539,7 @@ export class ComposePopupView extends AbstractViewPopup { this.sendError(true); sendFailed(iError, data); // Remove remembered passphrase as it could be wrong - let key = ('S/MIME' === params.sign) ? identity : null; + let key = ('S/MIME' === params.sign) ? this.currentIdentity() : null; params.signFingerprint && this.signOptions.forEach(option => ('GnuPG' === option[0]) && (key = option[1])); key && Passphrases.delete(key); @@ -560,10 +561,9 @@ export class ComposePopupView extends AbstractViewPopup { this.close(); } setFolderETag(this.draftsFolder(), ''); - setFolderETag(sSentFolder, ''); + setFolderETag(params.saveFolder, ''); if (3 === arrayLength(this.aDraftInfo)) { - const folder = this.aDraftInfo[2]; - setFolderETag(folder, ''); + setFolderETag(this.aDraftInfo[2], ''); } reloadDraftFolder(); }, diff --git a/plugins/send-save-in/LICENSE b/plugins/send-save-in/LICENSE new file mode 100644 index 000000000..f709b02e2 --- /dev/null +++ b/plugins/send-save-in/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2016 RainLoop Team + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/plugins/send-save-in/index.php b/plugins/send-save-in/index.php new file mode 100644 index 000000000..e3b4e3fe6 --- /dev/null +++ b/plugins/send-save-in/index.php @@ -0,0 +1,23 @@ +UseLangs(true); // start use langs folder + $this->addJs('savein.js'); + } +} diff --git a/plugins/send-save-in/savein.js b/plugins/send-save-in/savein.js new file mode 100644 index 000000000..b95e18892 --- /dev/null +++ b/plugins/send-save-in/savein.js @@ -0,0 +1,75 @@ +(rl => { + const templateId = 'PopupsCompose', + folderListOptionsBuilder = () => { + const + aResult = [{ + id: '', + name: '', + system: false, + disabled: false + }], + sDeepPrefix = '\u00A0\u00A0\u00A0', + showUnsubscribed = true/*!SettingsUserStore.hideUnsubscribed()*/, + + foldersWalk = folders => { + folders.forEach(oItem => { + if (showUnsubscribed || oItem.hasSubscriptions() || !oItem.exists) { + aResult.push({ + id: oItem.fullName, + name: sDeepPrefix.repeat(oItem.deep) + oItem.detailedName(), + system: false, + disabled: !oItem.selectable() + }); + } + + if (oItem.subFolders.length) { + foldersWalk(oItem.subFolders()); + } + }); + }; + + + // FolderUserStore.folderList() + foldersWalk(rl.app.folderList() || []); + + return aResult; + }; + + let oldSentFolderFn; + + addEventListener('rl-view-model.create', e => { + if (templateId === e.detail.viewModelTemplateID) { + const view = e.detail; // ComposePopupView + + view.sentFolderValue = ko.observable(''); + view.sentFolderSelectList = ko.computed(folderListOptionsBuilder, {'pure':true}); + view.defaultOptionsAfterRender = (domItem, item) => + item && undefined !== item.disabled && domItem?.classList.toggle('disabled', domItem.disabled = item.disabled); + + oldSentFolderFn = view.sentFolder.bind(view); + view.sentFolder = () => view.sentFolderValue() || oldSentFolderFn(); + + document.getElementById(templateId).content.querySelector('.b-header tbody').append(Element.fromHTML(` + + Store in + + + (When send, store a copy of the message in the selected folder) + + `)); + + view.currentIdentity.subscribe(()=>{ + view.sentFolderValue(oldSentFolderFn()); + }); + } + }); + + addEventListener('rl-vm-visible', e => { + if (templateId === e.detail.viewModelTemplateID) { + const view = e.detail; // ComposePopupView + view.sentFolderValue(oldSentFolderFn()); + } + }); + +})(window.rl);