import ko from 'ko'; import { Capa, Layout, Focused, ComposeType, FolderType, MessageSetAction, KeyState, StorageResultType } from 'Common/Enums'; import { UNUSED_OPTION_VALUE } from 'Common/Consts'; import { bMobileDevice, leftPanelDisabled, moveAction } from 'Common/Globals'; import { computedPagenatorHelper, friendlySize } from 'Common/Utils'; import { mailBox, append } from 'Common/Links'; import { Selector } from 'Common/Selector'; import { i18n, initOnStartOrLangChange } from 'Common/Translator'; import { getFolderFromCacheList, clearMessageFlagsFromCacheByFolder, hasRequestedMessage, addRequestedMessage } from 'Common/Cache'; import AppStore from 'Stores/User/App'; import QuotaStore from 'Stores/User/Quota'; import SettingsStore from 'Stores/User/Settings'; import FolderStore from 'Stores/User/Folder'; import MessageStore from 'Stores/User/Message'; import Remote from 'Remote/User/Fetch'; import { view, command, ViewType, showScreenPopup, setHash, popupVisibility } from 'Knoin/Knoin'; import { AbstractViewNext } from 'Knoin/AbstractViewNext'; const Settings = rl.settings, canBeMovedHelper = (self) => self.canBeMoved(), ifvisible = window.ifvisible; @view({ name: 'View/User/MailBox/MessageList', type: ViewType.Right, templateID: 'MailMessageList' }) class MessageListMailBoxUserView extends AbstractViewNext { constructor() { super(); this.sLastUid = null; this.bPrefetch = false; this.emptySubjectValue = ''; this.iGoToUpUpOrDownDownTimeout = 0; this.mobile = !!Settings.app('mobile'); this.newMoveToFolder = AppStore.newMoveToFolder; this.allowReload = !!Settings.capa(Capa.Reload); this.allowSearch = !!Settings.capa(Capa.Search); this.allowSearchAdv = !!Settings.capa(Capa.SearchAdv); this.allowComposer = !!Settings.capa(Capa.Composer); this.allowMessageListActions = !!Settings.capa(Capa.MessageListActions); this.allowDangerousActions = !!Settings.capa(Capa.DangerousActions); this.allowFolders = !!Settings.capa(Capa.Folders); this.popupVisibility = popupVisibility; this.message = MessageStore.message; this.messageList = MessageStore.messageList; this.messageListDisableAutoSelect = MessageStore.messageListDisableAutoSelect; this.folderList = FolderStore.folderList; this.composeInEdit = AppStore.composeInEdit; this.leftPanelDisabled = leftPanelDisabled; this.selectorMessageSelected = MessageStore.selectorMessageSelected; this.selectorMessageFocused = MessageStore.selectorMessageFocused; this.isMessageSelected = MessageStore.isMessageSelected; this.messageListSearch = MessageStore.messageListSearch; this.messageListThreadUid = MessageStore.messageListThreadUid; this.messageListError = MessageStore.messageListError; this.folderMenuForMove = FolderStore.folderMenuForMove; this.useCheckboxesInList = SettingsStore.useCheckboxesInList; this.mainMessageListSearch = MessageStore.mainMessageListSearch; this.messageListEndFolder = MessageStore.messageListEndFolder; this.messageListEndThreadUid = MessageStore.messageListEndThreadUid; this.messageListChecked = MessageStore.messageListChecked; this.messageListCheckedOrSelected = MessageStore.messageListCheckedOrSelected; this.messageListCheckedOrSelectedUidsWithSubMails = MessageStore.messageListCheckedOrSelectedUidsWithSubMails; this.messageListCompleteLoadingThrottle = MessageStore.messageListCompleteLoadingThrottle; this.messageListCompleteLoadingThrottleForAnimation = MessageStore.messageListCompleteLoadingThrottleForAnimation; initOnStartOrLangChange(() => this.emptySubjectValue = i18n('MESSAGE_LIST/EMPTY_SUBJECT_TEXT')); this.userQuota = QuotaStore.quota; this.userUsageSize = QuotaStore.usage; this.userUsageProc = QuotaStore.percentage; this.moveDropdownTrigger = ko.observable(false); this.moreDropdownTrigger = ko.observable(false); // append drag and drop this.dragOver = ko.observable(false).extend({ 'throttle': 1 }); this.dragOverEnter = ko.observable(false).extend({ 'throttle': 1 }); this.dragOverArea = ko.observable(null); this.dragOverBodyArea = ko.observable(null); this.messageListItemTemplate = ko.computed(() => this.mobile || Layout.SidePreview === SettingsStore.layout() ? 'MailMessageListItem' : 'MailMessageListItemNoPreviewPane' ); this.messageListSearchDesc = ko.computed(() => { const value = MessageStore.messageListEndSearch(); return value ? i18n('MESSAGE_LIST/SEARCH_RESULT_FOR', { 'SEARCH': value }) : ''; }); this.messageListPagenator = ko.computed( computedPagenatorHelper(MessageStore.messageListPage, MessageStore.messageListPageCount) ); this.checkAll = ko.computed({ read: () => 0 < MessageStore.messageListChecked().length, write: (value) => { value = !!value; MessageStore.messageList().forEach(message => message.checked(value)); } }); this.inputMessageListSearchFocus = ko.observable(false); this.sLastSearchValue = ''; this.inputProxyMessageListSearch = ko.computed({ read: this.mainMessageListSearch, write: value => this.sLastSearchValue = value }); this.isIncompleteChecked = ko.computed(() => { const c = MessageStore.messageListChecked().length; return c && MessageStore.messageList().length > c; }); this.hasMessages = ko.computed(() => 0 < this.messageList().length); this.hasCheckedOrSelectedLines = ko.computed(() => 0 < this.messageListCheckedOrSelected().length); this.isSpamFolder = ko.computed( () => FolderStore.spamFolder() === this.messageListEndFolder() && FolderStore.spamFolder() ); this.isSpamDisabled = ko.computed(() => UNUSED_OPTION_VALUE === FolderStore.spamFolder()); this.isTrashFolder = ko.computed( () => FolderStore.trashFolder() === this.messageListEndFolder() && FolderStore.trashFolder() ); this.isDraftFolder = ko.computed( () => FolderStore.draftFolder() === this.messageListEndFolder() && FolderStore.draftFolder() ); this.isSentFolder = ko.computed( () => FolderStore.sentFolder() === this.messageListEndFolder() && FolderStore.sentFolder() ); this.isArchiveFolder = ko.computed( () => FolderStore.archiveFolder() === this.messageListEndFolder() && FolderStore.archiveFolder() ); this.isArchiveDisabled = ko.computed(() => UNUSED_OPTION_VALUE === FolderStore.archiveFolder()); this.isArchiveVisible = ko.computed( () => !this.isArchiveFolder() && !this.isArchiveDisabled() && !this.isDraftFolder() ); this.isSpamVisible = ko.computed( () => !this.isSpamFolder() && !this.isSpamDisabled() && !this.isDraftFolder() && !this.isSentFolder() ); this.isUnSpamVisible = ko.computed( () => this.isSpamFolder() && !this.isSpamDisabled() && !this.isDraftFolder() && !this.isSentFolder() ); this.mobileCheckedStateShow = ko.computed(() => { return this.mobile ? 0 < this.messageListChecked().length : true; }); this.mobileCheckedStateHide = ko.computed(() => this.mobile ? !this.messageListChecked().length : true); this.messageListFocused = ko.computed(() => Focused.MessageList === AppStore.focusedState()); this.canBeMoved = this.hasCheckedOrSelectedLines; this.quotaTooltip = this.quotaTooltip.bind(this); this.selector = new Selector( this.messageList, this.selectorMessageSelected, this.selectorMessageFocused, '.messageListItem .actionHandle', '.messageListItem.selected', '.messageListItem .checkboxMessage', '.messageListItem.focused' ); this.selector.on('onItemSelect', message => MessageStore.selectMessage(message)); this.selector.on('onItemGetUid', message => (message ? message.generateUid() : '')); this.selector.on('onAutoSelect', () => this.useAutoSelect()); this.selector.on('onUpUpOrDownDown', v => this.goToUpUpOrDownDown(v)); addEventListener('mailbox.message-list.selector.go-down', e => this.selector.goDown(e.detail)); addEventListener('mailbox.message-list.selector.go-up', e => this.selector.goUp(e.detail)); addEventListener('mailbox.message.show', e => { const sFolder = e.detail.Folder, sUid = e.detail.Uid; const message = this.messageList().find( item => item && sFolder === item.folderFullNameRaw && sUid === item.uid ); if ('INBOX' === sFolder) { setHash(mailBox(sFolder, 1)); } if (message) { this.selector.selectMessageItem(message); } else { if ('INBOX' !== sFolder) { setHash(mailBox(sFolder, 1)); } MessageStore.selectMessageByFolderAndUid(sFolder, sUid); } }); MessageStore.messageListEndHash.subscribe((() => this.selector.scrollToFocused() ).throttle(50)); } @command() clearCommand() { if (Settings.capa(Capa.DangerousActions)) { showScreenPopup(require('View/Popup/FolderClear'), [FolderStore.currentFolder()]); } } @command() reloadCommand() { if (!MessageStore.messageListCompleteLoadingThrottleForAnimation() && this.allowReload) { rl.app.reloadMessageList(false, true); } } @command(canBeMovedHelper) multyForwardCommand() { if (Settings.capa(Capa.Composer)) { showScreenPopup(require('View/Popup/Compose'), [ ComposeType.ForwardAsAttachment, MessageStore.messageListCheckedOrSelected() ]); } } @command(canBeMovedHelper) deleteWithoutMoveCommand() { if (Settings.capa(Capa.DangerousActions)) { rl.app.deleteMessagesFromFolder( FolderType.Trash, FolderStore.currentFolderFullNameRaw(), MessageStore.messageListCheckedOrSelectedUidsWithSubMails(), false ); } } @command(canBeMovedHelper) deleteCommand() { rl.app.deleteMessagesFromFolder( FolderType.Trash, FolderStore.currentFolderFullNameRaw(), MessageStore.messageListCheckedOrSelectedUidsWithSubMails(), true ); } @command(canBeMovedHelper) archiveCommand() { rl.app.deleteMessagesFromFolder( FolderType.Archive, FolderStore.currentFolderFullNameRaw(), MessageStore.messageListCheckedOrSelectedUidsWithSubMails(), true ); } @command(canBeMovedHelper) spamCommand() { rl.app.deleteMessagesFromFolder( FolderType.Spam, FolderStore.currentFolderFullNameRaw(), MessageStore.messageListCheckedOrSelectedUidsWithSubMails(), true ); } @command(canBeMovedHelper) notSpamCommand() { rl.app.deleteMessagesFromFolder( FolderType.NotSpam, FolderStore.currentFolderFullNameRaw(), MessageStore.messageListCheckedOrSelectedUidsWithSubMails(), true ); } @command(canBeMovedHelper) moveCommand() {} // eslint-disable-line no-empty-function @command(canBeMovedHelper) moveNewCommand(vm, event) { if (this.newMoveToFolder() && this.mobileCheckedStateShow()) { if (vm && event && event.preventDefault) { event.preventDefault(); if (event.stopPropagation) { event.stopPropagation(); } } if (moveAction()) { AppStore.focusedState(Focused.MessageList); moveAction(false); } else { AppStore.focusedState(Focused.FolderList); moveAction(true); } } } hideLeft(item, event) { event.preventDefault(); event.stopPropagation(); leftPanelDisabled(true); } showLeft(item, event) { event.preventDefault(); event.stopPropagation(); leftPanelDisabled(false); } composeClick() { if (Settings.capa(Capa.Composer)) { showScreenPopup(require('View/Popup/Compose')); } } goToUpUpOrDownDown(up) { if (this.messageListChecked().length) { return false; } clearTimeout(this.iGoToUpUpOrDownDownTimeout); this.iGoToUpUpOrDownDownTimeout = setTimeout(() => { let prev = null, next = null, temp = null, current = null; this.messageListPagenator().find(item => { if (item) { if (current) { next = item; } if (item.current) { current = item; prev = temp; } if (next) { return true; } temp = item; } return false; }); if (Layout.NoPreview === SettingsStore.layout() && !this.message()) { this.selector.iFocusedNextHelper = up ? -1 : 1; } else { this.selector.iSelectNextHelper = up ? -1 : 1; } if (up ? prev : next) { this.selector.unselect(); this.gotoPage(up ? prev : next); } }, 350); return true; } useAutoSelect() { if (this.messageListDisableAutoSelect()) { return false; } if (/is:unseen/.test(this.mainMessageListSearch())) { return false; } return Layout.NoPreview !== SettingsStore.layout(); } searchEnterAction() { this.mainMessageListSearch(this.sLastSearchValue); this.inputMessageListSearchFocus(false); } /** * @returns {string} */ printableMessageCountForDeletion() { const cnt = this.messageListCheckedOrSelectedUidsWithSubMails().length; return 1 < cnt ? ' (' + (100 > cnt ? cnt : '99+') + ')' : ''; // eslint-disable-line no-magic-numbers } cancelSearch() { this.mainMessageListSearch(''); this.inputMessageListSearchFocus(false); } cancelThreadUid() { setHash( mailBox( FolderStore.currentFolderFullNameHash(), MessageStore.messageListPageBeforeThread(), MessageStore.messageListSearch() ) ); } /** * @param {string} sToFolderFullNameRaw * @param {boolean} bCopy * @returns {boolean} */ moveSelectedMessagesToFolder(sToFolderFullNameRaw, bCopy) { if (this.canBeMoved()) { rl.app.moveMessagesToFolder( FolderStore.currentFolderFullNameRaw(), MessageStore.messageListCheckedOrSelectedUidsWithSubMails(), sToFolderFullNameRaw, bCopy ); } return false; } dragAndDronHelper(oMessageListItem) { if (oMessageListItem) { oMessageListItem.checked(true); } const el = Element.fromHTML('