' + i18n('COMPOSE/REPLY_MESSAGE_TITLE', { DATETIME: sDate, EMAIL: sFrom }) + ':
' - + sText.replace(/'; break; @@ -1068,6 +1069,7 @@ export class ComposePopupView extends AbstractViewPopup { case ComposeType.ForwardAsAttachment: sText = ''; break; + default: encrypted = PgpUserStore.isEncrypted(sText); if (encrypted) { @@ -1131,7 +1133,8 @@ export class ComposePopupView extends AbstractViewPopup { this.setFocusInPopup(); } - const downloads = this.getAttachmentsDownloadsForUpload(); + // item.CID item.isInline item.isLinked + const downloads = this.attachments.filter(item => item && !item.tempName()).map(item => item.id); if (arrayLength(downloads)) { Remote.request('MessageUploadAttachments', (iError, oData) => { @@ -1148,7 +1151,7 @@ export class ComposePopupView extends AbstractViewPopup { }); } else { this.attachments.forEach(attachment => { - if (attachment && attachment.fromMessage) { + if (attachment?.fromMessage) { attachment .waiting(false) .uploading(false) @@ -1175,7 +1178,7 @@ export class ComposePopupView extends AbstractViewPopup { if (!this.to()) { this.to.focused(true); } else if (!this.to.focused()) { - this.oEditor && this.oEditor.focus(); + this.oEditor?.focus(); } }, 100); } @@ -1261,7 +1264,7 @@ export class ComposePopupView extends AbstractViewPopup { }) .on('onComplete', (id, result, data) => { const attachment = this.getAttachmentById(id), - response = (data && data.Result) || {}, + response = data?.Result || {}, errorCode = response.ErrorCode, attachmentJson = result && response.Attachment; @@ -1349,7 +1352,7 @@ export class ComposePopupView extends AbstractViewPopup { prepareAttachmentsForSendOrSave() { const result = {}; this.attachments.forEach(item => { - if (item && item.complete() && item.tempName() && item.enabled()) { + if (item?.complete() && item?.tempName() && item?.enabled()) { result[item.tempName()] = [item.fileName(), item.isInline ? '1' : '0', item.CID, item.contentLocation]; } }); @@ -1376,7 +1379,7 @@ export class ComposePopupView extends AbstractViewPopup { oJua || attachment.waiting(false).uploading(true); attachment.cancel = () => { this.attachments.remove(attachment); - oJua && oJua.cancel(attachment.id); + oJua?.cancel(attachment.id); }; this.attachments.push(attachment); view && this.attachmentsArea(); @@ -1402,35 +1405,22 @@ export class ComposePopupView extends AbstractViewPopup { if (message) { if (ComposeType.ForwardAsAttachment === type) { this.addMessageAsAttachment(message); - } else { + } else if ([ + ComposeType.Reply, ComposeType.ReplyAll, + ComposeType.Forward, ComposeType.Draft, ComposeType.EditAsNew + ].includes(type)) { message.attachments.forEach(item => { - let add = false; - switch (type) { - case ComposeType.Reply: - case ComposeType.ReplyAll: - break; - - case ComposeType.Forward: - case ComposeType.Draft: - case ComposeType.EditAsNew: - add = true; - break; - // no default - } - - if (add) { - const attachment = new ComposeAttachmentModel( - item.download, - item.fileName, - item.estimatedSize, - item.isInline(), - item.isLinked(), - item.cid, - item.contentLocation - ); - attachment.fromMessage = true; - this.addAttachment(attachment); - } + const attachment = new ComposeAttachmentModel( + item.download, + item.fileName, + item.estimatedSize, + item.isInline(), + item.isLinked(), + item.cid, + item.contentLocation + ); + attachment.fromMessage = true; + this.addAttachment(attachment); }); } } @@ -1443,7 +1433,7 @@ export class ComposePopupView extends AbstractViewPopup { isEmptyForm(includeAttachmentInProgress = true) { const withoutAttachment = includeAttachmentInProgress ? !this.attachments.length - : !this.attachments.some(item => item && item.complete()); + : !this.attachments.some(item => item?.complete()); return ( !this.to.length && @@ -1463,8 +1453,8 @@ export class ComposePopupView extends AbstractViewPopup { this.replyTo(''); this.subject(''); - this.requestDsn(false); - this.requestReadReceipt(false); + this.requestDsn(SettingsUserStore.requestDsn()); + this.requestReadReceipt(SettingsUserStore.requestReadReceipt()); this.markAsImportant(false); this.bodyArea(); @@ -1485,8 +1475,8 @@ export class ComposePopupView extends AbstractViewPopup { this.showBcc(false); this.showReplyTo(false); - this.pgpSign(false); - this.pgpEncrypt(false); + this.pgpSign(SettingsUserStore.pgpSign()); + this.pgpEncrypt(SettingsUserStore.pgpEncrypt()); this.attachments([]); @@ -1499,20 +1489,11 @@ export class ComposePopupView extends AbstractViewPopup { this.sending(false); this.saving(false); - this.oEditor && this.oEditor.clear(); + this.oEditor?.clear(); this.dropMailvelope(); } - /** - * @returns {Array} - */ - getAttachmentsDownloadsForUpload() { - return this.attachments.filter(item => item && !item.tempName()).map( - item => item.id - ); - } - mailvelopeArea() { if (!this.mailvelope) { /** diff --git a/dev/View/Popup/Contacts.js b/dev/View/Popup/Contacts.js index 9f1d81ded..5d86f6cf3 100644 --- a/dev/View/Popup/Contacts.js +++ b/dev/View/Popup/Contacts.js @@ -78,7 +78,7 @@ export class ContactsPopupView extends AbstractViewPopup { contactsPaginator: computedPaginatorHelper(this.contactsPage, pagecount), contactsCheckedOrSelected: () => { - const checked = ContactUserStore.filter(item => item.checked && item.checked()), + const checked = ContactUserStore.filter(item => item.checked?.()), selected = this.selectorContact(); return selected @@ -128,7 +128,7 @@ export class ContactsPopupView extends AbstractViewPopup { const data = oItem.getNameAndEmailHelper(), email = data ? new EmailModel(data[0], data[1]) : null; - if (email && email.validate()) { + if (email?.validate()) { return email; } } @@ -235,7 +235,7 @@ export class ContactsPopupView extends AbstractViewPopup { if (this.contactsCheckedOrSelected().length) { Remote.request('ContactsDelete', (iError, oData) => { - if (500 < (!iError && oData && oData.Time ? pInt(oData.Time) : 0)) { + if (500 < (!iError && oData?.Time) ? pInt(oData.Time) : 0) { this.reloadContactList(this.bDropPageAfterDelete); } else { setTimeout(() => this.reloadContactList(this.bDropPageAfterDelete), 500); @@ -274,7 +274,7 @@ export class ContactsPopupView extends AbstractViewPopup { } ContactUserStore.loading(true); - Remote.request('Contacts', + Remote.abort('Contacts').request('Contacts', (iError, data) => { let count = 0, list = []; @@ -299,10 +299,7 @@ export class ContactsPopupView extends AbstractViewPopup { Offset: offset, Limit: CONTACTS_PER_PAGE, Search: this.search() - }, - null, - '', - ['Contacts'] + } ); } diff --git a/dev/View/Popup/Domain.js b/dev/View/Popup/Domain.js index dbe07bc03..d5bc6151b 100644 --- a/dev/View/Popup/Domain.js +++ b/dev/View/Popup/Domain.js @@ -8,6 +8,8 @@ import { AbstractViewPopup } from 'Knoin/AbstractViews'; import { DomainAdminStore } from 'Stores/Admin/Domain'; +import { AskPopupView } from 'View/Popup/Ask'; + const domainToParams = oDomain => ({ Name: oDomain.name(), @@ -179,39 +181,46 @@ export class DomainPopupView extends AbstractViewPopup { testConnectionCommand() { this.clearTesting(false); - this.testing(true); + // https://github.com/the-djmaze/snappymail/issues/477 + AskPopupView.credentials('IMAP', 'GLOBAL/TEST').then(credentials => { + if (credentials) { + this.testing(true); + const params = domainToParams(this); + params.username = credentials.username; + params.password = credentials.password; + Remote.request('AdminDomainTest', + (iError, oData) => { + this.testing(false); + if (iError) { + this.testingImapError(true); + this.testingSieveError(true); + this.testingSmtpError(true); + } else { + this.testingDone(true); + this.testingImapError(true !== oData.Result.Imap); + this.testingSieveError(true !== oData.Result.Sieve); + this.testingSmtpError(true !== oData.Result.Smtp); - Remote.request('AdminDomainTest', - (iError, oData) => { - this.testing(false); - if (iError) { - this.testingImapError(true); - this.testingSieveError(true); - this.testingSmtpError(true); - } else { - this.testingDone(true); - this.testingImapError(true !== oData.Result.Imap); - this.testingSieveError(true !== oData.Result.Sieve); - this.testingSmtpError(true !== oData.Result.Smtp); + if (this.testingImapError() && oData.Result.Imap) { + this.testingImapErrorDesc(''); + this.testingImapErrorDesc(oData.Result.Imap); + } - if (this.testingImapError() && oData.Result.Imap) { - this.testingImapErrorDesc(''); - this.testingImapErrorDesc(oData.Result.Imap); - } + if (this.testingSieveError() && oData.Result.Sieve) { + this.testingSieveErrorDesc(''); + this.testingSieveErrorDesc(oData.Result.Sieve); + } - if (this.testingSieveError() && oData.Result.Sieve) { - this.testingSieveErrorDesc(''); - this.testingSieveErrorDesc(oData.Result.Sieve); - } - - if (this.testingSmtpError() && oData.Result.Smtp) { - this.testingSmtpErrorDesc(''); - this.testingSmtpErrorDesc(oData.Result.Smtp); - } - } - }, - domainToParams(this) - ); + if (this.testingSmtpError() && oData.Result.Smtp) { + this.testingSmtpErrorDesc(''); + this.testingSmtpErrorDesc(oData.Result.Smtp); + } + } + }, + params + ); + } + }); } onDomainCreateOrSaveResponse(iError) { @@ -239,7 +248,7 @@ export class DomainPopupView extends AbstractViewPopup { if (oDomain) { this.enableSmartPorts(false); this.edit(true); - forEachObjectEntry(oDomain, (key, value) => this[key] && this[key](value)); + forEachObjectEntry(oDomain, (key, value) => this[key]?.(value)); this.enableSmartPorts(true); } } diff --git a/dev/View/Popup/FolderSystem.js b/dev/View/Popup/FolderSystem.js index a5186a3f2..3b6994cbe 100644 --- a/dev/View/Popup/FolderSystem.js +++ b/dev/View/Popup/FolderSystem.js @@ -19,7 +19,7 @@ export class FolderSystemPopupView extends AbstractViewPopup { this.folderSelectList = koComputable(() => folderListOptionsBuilder( - FolderUserStore.folderListSystemNames(), + FolderUserStore.systemFoldersNames(), [ ['', i18n('POPUPS_SYSTEM_FOLDERS/SELECT_CHOOSE_ONE')], [UNUSED_OPTION_VALUE, i18n('POPUPS_SYSTEM_FOLDERS/SELECT_UNUSE_NAME')] diff --git a/dev/View/Popup/Identity.js b/dev/View/Popup/Identity.js index dcdbde8bc..2972f7ad8 100644 --- a/dev/View/Popup/Identity.js +++ b/dev/View/Popup/Identity.js @@ -63,9 +63,7 @@ export class IdentityPopupView extends AbstractViewPopup { submitForm() { if (!this.submitRequest()) { - if (this.signature && this.signature.__fetchEditorValue) { - this.signature.__fetchEditorValue(); - } + this.signature?.__fetchEditorValue?.(); if (!this.emailHasError()) { this.emailHasError(!this.email().trim()); diff --git a/dev/View/Popup/Languages.js b/dev/View/Popup/Languages.js index ff62f63e3..f7d33327c 100644 --- a/dev/View/Popup/Languages.js +++ b/dev/View/Popup/Languages.js @@ -51,7 +51,7 @@ export class LanguagesPopupView extends AbstractViewPopup { } changeLanguage(lang) { - this.fLang && this.fLang(lang); + this.fLang?.(lang); this.close(); } } diff --git a/dev/View/Popup/OpenPgpGenerate.js b/dev/View/Popup/OpenPgpGenerate.js index 6d50d8dd8..0b392c586 100644 --- a/dev/View/Popup/OpenPgpGenerate.js +++ b/dev/View/Popup/OpenPgpGenerate.js @@ -94,7 +94,7 @@ export class OpenPgpGeneratePopupView extends AbstractViewPopup { showError(e) { console.log(e); - if (e && e.message) { + if (e?.message) { this.submitError(e.message); } } diff --git a/dev/View/User/Login.js b/dev/View/User/Login.js index 51eb9aed6..03066afb0 100644 --- a/dev/View/User/Login.js +++ b/dev/View/User/Login.js @@ -114,9 +114,9 @@ export class LoginUserView extends AbstractViewLogin { if (Notification.InvalidInputArgument == iError) { iError = Notification.AuthError; } - this.submitError(getNotification(iError, (oData ? oData.ErrorMessage : ''), + this.submitError(getNotification(iError, oData?.ErrorMessage, Notification.UnknownNotification)); - this.submitErrorAdditional((oData && oData.ErrorMessageAdditional) || ''); + this.submitErrorAdditional(oData?.ErrorMessageAdditional); } else { rl.setData(oData.Result); } diff --git a/dev/View/User/MailBox/FolderList.js b/dev/View/User/MailBox/FolderList.js index 7b05be5b5..113f3d98d 100644 --- a/dev/View/User/MailBox/FolderList.js +++ b/dev/View/User/MailBox/FolderList.js @@ -31,9 +31,7 @@ export class MailFolderList extends AbstractViewLeft { this.composeInEdit = AppUserStore.composeInEdit; - this.folderList = FolderUserStore.folderList; - this.folderListSystem = FolderUserStore.folderListSystem; - this.foldersChanging = FolderUserStore.foldersChanging; + this.systemFolders = FolderUserStore.systemFolders; this.moveAction = moveAction; @@ -84,7 +82,7 @@ export class MailFolderList extends AbstractViewLeft { } el = eqs(event, 'a'); - if (el && el.matches('.selectable')) { + if (el?.matches('.selectable')) { event.preventDefault(); const folder = ko.dataFor(el); if (folder) { @@ -172,10 +170,10 @@ export class MailFolderList extends AbstractViewLeft { AppUserStore.focusedState.subscribe(value => { let el = qs('li a.focused'); - el && el.classList.remove('focused'); + el?.classList.remove('focused'); if (Scope.FolderList === value) { el = qs('li a.selected'); - el && el.classList.add('focused'); + el?.classList.add('focused'); } }); } diff --git a/dev/View/User/MailBox/MessageList.js b/dev/View/User/MailBox/MessageList.js index b023e0c95..d94831820 100644 --- a/dev/View/User/MailBox/MessageList.js +++ b/dev/View/User/MailBox/MessageList.js @@ -20,7 +20,7 @@ import { isFullscreen, toggleFullscreen } from 'Common/Fullscreen'; import { mailBox, serverRequest } from 'Common/Links'; import { Selector } from 'Common/Selector'; -import { i18n, initOnStartOrLangChange } from 'Common/Translator'; +import { i18n } from 'Common/Translator'; import { getFolderFromCacheList, @@ -55,14 +55,14 @@ const */ listAction = (...args) => MessagelistUserStore.setAction(...args); +let + iGoToUpOrDownTimeout = 0, + sLastSearchValue = ''; + export class MailMessageList extends AbstractViewRight { constructor() { super(); - this.emptySubjectValue = ''; - - this.iGoToUpOrDownTimeout = 0; - this.newMoveToFolder = !!SettingsGet('NewMoveToFolder'); this.allowSearch = SettingsCapa('Search'); @@ -76,19 +76,10 @@ export class MailMessageList extends AbstractViewRight { this.isMobile = ThemeStore.isMobile; this.leftPanelDisabled = leftPanelDisabled; - this.messageListSearch = MessagelistUserStore.listSearch; - this.messageListError = MessagelistUserStore.error; - this.popupVisibility = arePopupsVisible; this.useCheckboxesInList = SettingsUserStore.useCheckboxesInList; - this.messageListThreadUid = MessagelistUserStore.endThreadUid; - - this.messageListIsLoading = MessagelistUserStore.isLoading; - - initOnStartOrLangChange(() => this.emptySubjectValue = i18n('MESSAGE_LIST/EMPTY_SUBJECT_TEXT')); - this.userUsageProc = FolderUserStore.quotaPercentage; this.addObservables({ @@ -99,15 +90,13 @@ export class MailMessageList extends AbstractViewRight { dragOverArea: null, dragOverBodyArea: null, - inputMessageListSearchFocus: false + focusSearch: false }); // append drag and drop this.dragOver = ko.observable(false).extend({ throttle: 1 }); this.dragOverEnter = ko.observable(false).extend({ throttle: 1 }); - this.sLastSearchValue = ''; - this.addComputables({ sortSupported: () => @@ -136,9 +125,9 @@ export class MailMessageList extends AbstractViewRight { } }, - inputProxyMessageListSearch: { + inputSearch: { read: MessagelistUserStore.mainSearch, - write: value => this.sLastSearchValue = value + write: value => sLastSearchValue = value }, isIncompleteChecked: () => { @@ -146,33 +135,28 @@ export class MailMessageList extends AbstractViewRight { return c && MessagelistUserStore().length > c; }, - hasMessages: () => 0 < MessagelistUserStore().length, - isSpamFolder: () => (FolderUserStore.spamFolder() || 0) === MessagelistUserStore().Folder, - isSpamDisabled: () => UNUSED_OPTION_VALUE === FolderUserStore.spamFolder(), - isTrashFolder: () => (FolderUserStore.trashFolder() || 0) === MessagelistUserStore().Folder, isDraftFolder: () => (FolderUserStore.draftsFolder() || 0) === MessagelistUserStore().Folder, - isSentFolder: () => (FolderUserStore.sentFolder() || 0) === MessagelistUserStore().Folder, + archiveAllowed: () => + (FolderUserStore.archiveFolder() || 0) !== MessagelistUserStore().Folder + && UNUSED_OPTION_VALUE !== FolderUserStore.archiveFolder() + && !this.isDraftFolder(), - isArchiveFolder: () => (FolderUserStore.archiveFolder() || 0) === MessagelistUserStore().Folder, + spamAllowed: () => UNUSED_OPTION_VALUE !== FolderUserStore.spamFolder() + && (FolderUserStore.sentFolder() || 0) !== MessagelistUserStore().Folder + && !this.isDraftFolder(), - isArchiveDisabled: () => UNUSED_OPTION_VALUE === FolderUserStore.archiveFolder(), + isSpamVisible: () => !this.isSpamFolder() && this.spamAllowed(), - isArchiveVisible: () => !this.isArchiveFolder() && !this.isArchiveDisabled() && !this.isDraftFolder(), + isUnSpamVisible: () => this.isSpamFolder() && this.spamAllowed(), - isSpamVisible: () => - !this.isSpamFolder() && !this.isSpamDisabled() && !this.isDraftFolder() && !this.isSentFolder(), + mobileCheckedStateShow: () => ThemeStore.isMobile() ? MessagelistUserStore.listChecked().length : 1, - isUnSpamVisible: () => - this.isSpamFolder() && !this.isSpamDisabled() && !this.isDraftFolder() && !this.isSentFolder(), - - mobileCheckedStateShow: () => ThemeStore.isMobile() ? 0 < MessagelistUserStore.listChecked().length : true, - - mobileCheckedStateHide: () => ThemeStore.isMobile() ? !MessagelistUserStore.listChecked().length : true, + mobileCheckedStateHide: () => ThemeStore.isMobile() ? !MessagelistUserStore.listChecked().length : 1, sortText: () => { let mode = FolderUserStore.sortMode(), @@ -188,8 +172,6 @@ export class MailMessageList extends AbstractViewRight { } }); - this.hasCheckedOrSelectedLines = MessagelistUserStore.hasCheckedOrSelected, - this.selector = new Selector( MessagelistUserStore, MessagelistUserStore.selectedMessage, @@ -228,7 +210,7 @@ export class MailMessageList extends AbstractViewRight { const sFolder = e.detail.Folder, iUid = e.detail.Uid; const message = MessagelistUserStore.find( - item => item && sFolder === item.folder && iUid == item.uid + item => sFolder === item?.folder && iUid == item?.uid ); if ('INBOX' === sFolder) { @@ -344,7 +326,7 @@ export class MailMessageList extends AbstractViewRight { moveNewCommand(vm, event) { if (this.newMoveToFolder && this.mobileCheckedStateShow()) { - if (vm && event && event.preventDefault) { + if (vm && event?.preventDefault) { event.preventDefault(); event.stopPropagation(); } @@ -364,8 +346,8 @@ export class MailMessageList extends AbstractViewRight { return false; } - clearTimeout(this.iGoToUpOrDownTimeout); - this.iGoToUpOrDownTimeout = setTimeout(() => { + clearTimeout(iGoToUpOrDownTimeout); + iGoToUpOrDownTimeout = setTimeout(() => { let prev, next, temp, current; this.messageListPaginator().find(item => { @@ -412,7 +394,7 @@ export class MailMessageList extends AbstractViewRight { cancelSearch() { MessagelistUserStore.mainSearch(''); - this.inputMessageListSearchFocus(false); + this.focusSearch(false); } cancelThreadUid() { @@ -446,7 +428,7 @@ export class MailMessageList extends AbstractViewRight { getDragData(event) { const item = ko.dataFor(doc.elementFromPoint(event.clientX, event.clientY)); - item && item.checked && item.checked(true); + item?.checked?.(true); const uids = MessagelistUserStore.listCheckedOrSelectedUidsWithSubMails(); item && !uids.includes(item.uid) && uids.push(item.uid); return uids.length ? { @@ -589,7 +571,7 @@ export class MailMessageList extends AbstractViewRight { } gotoThread(message) { - if (message && 0 < message.threadsLen()) { + if (0 < message?.threadsLen()) { MessagelistUserStore.pageBeforeThread(MessagelistUserStore.page()); hasher.setHash( @@ -643,7 +625,7 @@ export class MailMessageList extends AbstractViewRight { el && this.gotoThread(ko.dataFor(el)); }, dblclick: event => { - let el = eqs(event, '.actionHandle'); + let el = eqs(event, '.actionHandle'); el && this.gotoThread(ko.dataFor(el)); } }); @@ -684,7 +666,7 @@ export class MailMessageList extends AbstractViewRight { addShortcut('enter,open', '', Scope.MessageList, () => { if (formFieldFocused()) { - MessagelistUserStore.mainSearch(this.sLastSearchValue); + MessagelistUserStore.mainSearch(sLastSearchValue); return false; } if (MessageUserStore.message() && this.useAutoSelect()) { @@ -735,15 +717,10 @@ export class MailMessageList extends AbstractViewRight { }); registerShortcut('t', '', [Scope.MessageList], () => { - let message = MessagelistUserStore.selectedMessage(); - if (!message) { - message = MessagelistUserStore.focusedMessage(); - } - - if (message && 0 < message.threadsLen()) { + let message = MessagelistUserStore.selectedMessage() || MessagelistUserStore.focusedMessage(); + if (0 < message?.threadsLen()) { this.gotoThread(message); } - return false; }); @@ -778,7 +755,7 @@ export class MailMessageList extends AbstractViewRight { if (SettingsCapa('Search')) { // search input focus addShortcut('/', '', [Scope.MessageList, Scope.MessageView], () => { - this.inputMessageListSearchFocus(true); + this.focusSearch(true); return false; }); } diff --git a/dev/View/User/MailBox/MessageView.js b/dev/View/User/MailBox/MessageView.js index 3c0d039f9..20b4d7613 100644 --- a/dev/View/User/MailBox/MessageView.js +++ b/dev/View/User/MailBox/MessageView.js @@ -7,7 +7,6 @@ import { Scope } from 'Common/Enums'; import { ComposeType, - ClientSideKeyNameLastReplyAction, ClientSideKeyNameMessageHeaderFullInfo, ClientSideKeyNameMessageAttachmentControls, FolderType, @@ -94,10 +93,11 @@ export class MailMessageView extends AbstractViewRight { } }, this.messageVisibility); + this.msgDefaultAction = SettingsUserStore.msgDefaultAction; + this.addObservables({ showAttachmentControls: !!Local.get(ClientSideKeyNameMessageAttachmentControls), downloadAsZipLoading: false, - lastReplyAction_: '', showFullInfo: '1' === Local.get(ClientSideKeyNameMessageHeaderFullInfo), moreDropdownTrigger: false, @@ -134,19 +134,10 @@ export class MailMessageView extends AbstractViewRight { allowAttachmentControls: () => arrayLength(attachmentsActions) && SettingsCapa('AttachmentsActions'), downloadAsZipAllowed: () => this.attachmentsActions.includes('zip') - && (currentMessage() ? currentMessage().attachments : []) - .filter(item => item && !item.isLinked() && item.checked() && item.download) + && (currentMessage()?.attachments || []) + .filter(item => item?.download && !item?.isLinked() && item?.checked()) .length, - lastReplyAction: { - read: this.lastReplyAction_, - write: value => this.lastReplyAction_( - [ComposeType.Reply, ComposeType.ReplyAll, ComposeType.Forward].includes(value) - ? ComposeType.Reply - : value - ) - }, - tagsAllowed: () => FolderUserStore.currentFolder() ? FolderUserStore.currentFolder().tagsAllowed() : false, messageVisibility: () => !MessageUserStore.loading() && !!currentMessage(), @@ -182,8 +173,6 @@ export class MailMessageView extends AbstractViewRight { }); this.addSubscribables({ - lastReplyAction_: value => Local.set(ClientSideKeyNameLastReplyAction, value), - message: message => { MessageUserStore.activeDom(null); @@ -207,8 +196,6 @@ export class MailMessageView extends AbstractViewRight { showFullInfo: value => Local.set(ClientSideKeyNameMessageHeaderFullInfo, value ? '1' : '0') }); - this.lastReplyAction(Local.get(ClientSideKeyNameLastReplyAction) || ComposeType.Reply); - // commands this.replyCommand = createCommandReplyHelper(ComposeType.Reply); this.replyAllCommand = createCommandReplyHelper(ComposeType.ReplyAll); @@ -256,7 +243,6 @@ export class MailMessageView extends AbstractViewRight { * @returns {void} */ replyOrforward(sType) { - this.lastReplyAction(sType); showMessageComposer([sType, currentMessage()]); } @@ -300,7 +286,7 @@ export class MailMessageView extends AbstractViewRight { el = eqs(event, '.attachmentsPlace .attachmentItem .attachmentNameParent'); if (el) { const attachment = ko.dataFor(el); - if (attachment && attachment.linkDownload()) { + if (attachment?.linkDownload()) { if ('message/rfc822' == attachment.mimeType) { // TODO rl.fetch(attachment.linkDownload()).then(response => { @@ -407,7 +393,7 @@ export class MailMessageView extends AbstractViewRight { // toggle message blockquotes registerShortcut('b', '', [Scope.MessageList, Scope.MessageView], () => { const message = currentMessage(); - if (message && message.body) { + if (message?.body) { message.body.querySelectorAll('.rlBlockquoteSwitcher').forEach(node => node.click()); return false; } @@ -425,7 +411,7 @@ export class MailMessageView extends AbstractViewRight { // print addShortcut('p,printscreen', 'meta', [Scope.MessageView, Scope.MessageList], () => { - currentMessage() && currentMessage().printMessage(); + currentMessage()?.printMessage(); return false; }); @@ -524,7 +510,7 @@ export class MailMessageView extends AbstractViewRight { downloadAsZip() { const hashes = (currentMessage() ? currentMessage().attachments : []) - .map(item => (item && !item.isLinked() && item.checked() ? item.download : '')) + .map(item => item?.checked() && !item?.isLinked() ? item.download : '') .filter(v => v); if (hashes.length) { Remote.post('AttachmentsActions', this.downloadAsZipLoading, { @@ -532,7 +518,7 @@ export class MailMessageView extends AbstractViewRight { Hashes: hashes }) .then(result => { - let hash = result && result.Result && result.Result.FileHash; + let hash = result?.Result?.FileHash; if (hash) { download(attachmentDownload(hash), hash+'.zip'); } else { @@ -591,7 +577,7 @@ export class MailMessageView extends AbstractViewRight { if (result.data) { MimeToMessage(result.data, oMessage); oMessage.html() ? oMessage.viewHtml() : oMessage.viewPlain(); - if (result.signatures && result.signatures.length) { + if (result.signatures?.length) { oMessage.pgpSigned(true); oMessage.pgpVerified({ signatures: result.signatures, @@ -610,7 +596,7 @@ export class MailMessageView extends AbstractViewRight { oMessage.pgpVerified(result); } /* - if (result && result.success) { + if (result?.success) { i18n('OPENPGP/GOOD_SIGNATURE', { USER: validKey.user + ' (' + validKey.id + ')' }); @@ -618,7 +604,7 @@ export class MailMessageView extends AbstractViewRight { } else { const keyIds = arrayLength(signingKeyIds) ? signingKeyIds : null, additional = keyIds - ? keyIds.map(item => (item && item.toHex ? item.toHex() : null)).filter(v => v).join(', ') + ? keyIds.map(item => item?.toHex?.()).filter(v => v).join(', ') : ''; i18n('OPENPGP/ERROR', { diff --git a/dev/View/User/SystemDropDown.js b/dev/View/User/SystemDropDown.js index b56eefc53..b3e5560f1 100644 --- a/dev/View/User/SystemDropDown.js +++ b/dev/View/User/SystemDropDown.js @@ -52,7 +52,7 @@ export class SystemDropDownUserView extends AbstractViewRight { } accountClick(account, event) { - let email = account && account.email; + let email = account?.email; if (email && 0 === event.button && AccountUserStore.email() != email) { AccountUserStore.loading(true); event.preventDefault(); diff --git a/dev/dragdropgecko.js b/dev/dragdropgecko.js index e48ea3f8f..65836b5e9 100644 --- a/dev/dragdropgecko.js +++ b/dev/dragdropgecko.js @@ -70,7 +70,7 @@ htmlDrag = b => doc.documentElement.classList.toggle('firefox-drag', b), setDragImage = (src, xOffset, yOffset) => { - img && img.remove(); + img?.remove(); if (src) { // create drag image from custom element or drag source img = src.cloneNode(true); @@ -85,7 +85,7 @@ if (dragSource) { clearInterval(holdInterval); // dispose of drag image element - img && img.remove(); + img?.remove(); isDragging && dispatchEvent(lastTouch, 'dragend', dragSource); img = dragSource = lastTouch = lastTarget = dataTransfer = holdInterval = null; isDragging = allowDrop = false; @@ -163,6 +163,17 @@ return false; }; +/* + doc.addEventListener('pointerdown', e => { + doc.addEventListener('pointermove', e => { + e.clientX + }); + doc.setPointerCapture(e.pointerId); + }); + doc.addEventListener('pointerup', e => { + doc.releasePointerCapture(e.pointerId); + }); +*/ doc.addEventListener('touchstart', e => { // clear all variables reset(); diff --git a/dev/shortcuts.js b/dev/shortcuts.js index 794cfd2bf..0ff31b78d 100644 --- a/dev/shortcuts.js +++ b/dev/shortcuts.js @@ -64,9 +64,8 @@ const keydown = event => { let key = (event.key || '').toLowerCase().replace(' ','space'), modifiers = ['alt','ctrl','meta','shift'].filter(v => event[v+'Key']).join('+'); - scope[key] && scope[key][modifiers] && scope[key][modifiers].forEach(cmd => exec(event, cmd)); - !event.defaultPrevented && _scope !== 'all' && _scopes.all[key] && _scopes.all[key][modifiers] - && _scopes.all[key][modifiers].forEach(cmd => exec(event, cmd)); + scope[key]?.[modifiers]?.forEach(cmd => exec(event, cmd)); + !event.defaultPrevented && _scope !== 'all' && _scopes.all[key]?.[modifiers]?.forEach(cmd => exec(event, cmd)); }; win.shortcuts = shortcuts; diff --git a/dev/sieve.js b/dev/sieve.js index fcae436f7..e28639e08 100644 --- a/dev/sieve.js +++ b/dev/sieve.js @@ -17,7 +17,6 @@ import { SieveScriptPopupView } from 'Sieve/View/Script'; window.Sieve = { capa: capa, scripts: scripts, - setError: setError, loading: loading, serverError: serverError, serverErrorDesc: serverErrorDesc, diff --git a/gulpfile.js b/gulpfile.js index c614fb21a..e6cf1c2ed 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,4 +1,4 @@ -/* RainLoop Webmail (c) RainLoop Team | Licensed under AGPL 3 */ +/* RainLoop Webmail (c) RainLoop Team | Licensed under MIT */ const gulp = require('gulp'); const { cleanStatic } = require('./tasks/common'); diff --git a/index.php b/index.php index efcc8acd1..bce64d161 100644 --- a/index.php +++ b/index.php @@ -6,9 +6,9 @@ if (!defined('APP_VERSION')) define('APP_INDEX_ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR); } -if (file_exists('snappymail/v/'.APP_VERSION.'/include.php')) +if (file_exists(APP_INDEX_ROOT_PATH.'snappymail/v/'.APP_VERSION.'/include.php')) { - include 'snappymail/v/'.APP_VERSION.'/include.php'; + include APP_INDEX_ROOT_PATH.'snappymail/v/'.APP_VERSION.'/include.php'; } else { diff --git a/integrations/cloudron/DESCRIPTION.md b/integrations/cloudron/DESCRIPTION.md index d34828c42..d9c178956 100644 --- a/integrations/cloudron/DESCRIPTION.md +++ b/integrations/cloudron/DESCRIPTION.md @@ -1,4 +1,4 @@ -This app packages SnappyMail]+>/g, '').replace(/]+><\/a>/g, '').trim() + + sText.trim() + '
| - - - + | diff --git a/snappymail/v/0.0.0/app/templates/Views/User/SettingsGeneral.html b/snappymail/v/0.0.0/app/templates/Views/User/SettingsGeneral.html index f62cb91fa..421a57079 100644 --- a/snappymail/v/0.0.0/app/templates/Views/User/SettingsGeneral.html +++ b/snappymail/v/0.0.0/app/templates/Views/User/SettingsGeneral.html @@ -24,19 +24,6 @@ } }"> -