import React from 'react'; import ReactDOM from 'react-dom'; import superagent from 'superagent'; import socket_io from 'socket.io-client'; import ComposeWindow from './ComposeWindow.js'; import FolderList from './FolderList.js'; import MessageList from './MessageList.js'; import MessageView from './MessageView.js'; import DropDownMenu from './DropDownMenu.js'; import ListSortSettingsWindow from './ListSortSettingsWindow.js'; import MailSettingsWindow from './MailSettingsWindow.js'; import TabPanel from './TabPanel.js'; import _ from './I18n.js'; import Util from './Util.js'; window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame; class MainWindow extends React.PureComponent { state = { layout: 'message-on-right', quickReply: true, msg: null, threads: false, accounts: [], listGroups: [], messages: [] } startIo = () => { this.io = socket_io('', { path: window.location.pathname.replace(/[^\/]+$/, 'backend/socket.io') }); this.io.on('sync', (params) => { if (params.state == 'start') { this.setState({ progressText: 'Syncing '+params.email+' / '+params.folder, progressPercent: 0 }); } else if (params.state == 'progress') { this.setState({ progressPercent: Math.round(100*params.done/(params.total||1)) }); } else if (params.state == 'finish-box') { this.setState({ progressPercent: 100 }); } else if (params.state == 'complete') { this.setState({ progressText: '', progressPercent: 0 }); } this.setState({ sync: params.progress }); }); } loadAccounts() { superagent.get('backend/folders').end((err, res) => { let ixOfAll = { received: 1, outbox: 3, sent: 4, drafts: 5, spam: 6, trash: 7 }; let accounts = [ { name: _('All Messages'), accountId: null, unreadCount: 0, folders: [ { name: _('Unread'), icon: 'mail_unread', unreadCount: 0, type: 'unread' }, { name: _('Received'), icon: 'mail_received', unreadCount: 0, type: 'inbox' }, { name: _('Pinned'), icon: 'mail_pinned', unreadCount: 0, type: 'pinned' }, { name: _('Outbox'), icon: 'mail_outbox', unreadCount: 0, type: 'outbox' }, // FIXME { name: _('Sent'), icon: 'mail_sent', unreadCount: 0, type: 'sent' }, { name: _('Drafts'), icon: 'mail_drafts', unreadCount: 0, type: 'drafts' }, { name: _('Spam'), icon: 'mail_spam', unreadCount: 0, type: 'spam' }, { name: _('Trash'), icon: 'mail_trash', unreadCount: 0, type: 'trash' }, ], } ]; for (let a of res.body.accounts) { let account = { name: a.name, email: a.email, accountId: a.id, unreadCount: 0, warning: false, folders: [ { name: _('Unread'), icon: 'mail_unread', unreadCount: 0, type: 'unread' }, { name: _('Pinned'), icon: 'mail_pinned', unreadCount: a.pinned_count-0, type: 'pinned' }, ], folderMap: a.foldermap, folderTypes: {} }; if (!account.folderMap.received) { account.folderMap.received = 'INBOX'; } for (let f in account.folderMap) { account.folderTypes[account.folderMap[f]] = f; } for (let f of a.folders) { if (f.kind) { account.folderTypes[f.name] = f.kind; } } for (let f of a.folders) { let icon = (account.folderTypes[f.name] ? 'mail_'+account.folderTypes[f.name] : 'folder'); account.folders.push({ name: f.name, icon: icon, unreadCount: f.unread_count-0, folderId: f.id }); if (f.kind != 'sent' && f.kind != 'trash' && f.kind != 'drafts') { account.folders[0].unreadCount += (f.unread_count-0); } if (account.folderTypes[f.name]) { accounts[0].folders[ixOfAll[account.folderTypes[f.name]]].unreadCount += (f.unread_count-0); } account.unreadCount += (f.unread_count-0); } accounts.push(account); // unread total accounts[0].unreadCount += account.folders[0].unreadCount; accounts[0].folders[0].unreadCount += account.folders[0].unreadCount; // pinned total (not unread) accounts[0].folders[2].unreadCount += account.folders[1].unreadCount; } this.setState({ accounts }); }); } loadFolder = (folderParams) => { superagent.get('backend/groups').query(folderParams).end((err, res) => { let groups = res.body.groups.map(g => ({ name: Util.getGroupName(g.name), messageCount: g.count-0, start: 0 })); let start = 0; for (let i = 0; i < groups.length; i++) { groups[i].start = start; start += groups[i].messageCount; } this.setState({ folderParams: folderParams, listGroups: groups, messages: [] }); }); } search = (text) => { this.loadFolder({ ...this.state.folderParams, search: text }); } loadMessages = (start, count) => { let p = { ...this.state.folderParams }; p.offset = start; p.limit = count; superagent.get('backend/messages').query(p).end((err, res) => { let msgs = [ ...this.state.messages ]; let par = res.body.messages; par.unshift(par.length); par.unshift(start); msgs.splice.apply(msgs, par); this.setState({ messages: msgs }); }); } loadMessage = (msgId, callback) => { superagent.get('backend/message').query({ msgId: msgId }).end((err, res) => { callback(res.body.msg); }); } toggleRead = (is_read) => { // FIXME: Support marking multiple messages as read let msg = this.state.msg; if (!msg) { return; } let flags = [ ...msg.flags.filter(f => f != 'unread') ]; if (!is_read) { flags.push('unread'); } superagent.post('backend/mark').query({ msgId: msg.id, flag: 'seen', del: is_read ? '' : '1' }).end((err, res) => { if (this.state.msg == msg) { let newMsg = { ...msg, flags }; this.setState({ msg: newMsg, messages: this.state.messages.map(m => m == msg ? newMsg : m), }); } }); } startResync = () => { superagent.post('backend/sync').send().end((err, res) => { }); } setLayout = (l) => { this.setState({ layout: l }); } toggleQuickReply = () => { this.setState({ quickReply: !this.state.quickReply }); } setMessage = (msg) => { this.setState({ msg }); } render() { return (
, , ] }, { icon: 'mail_drafts', i16: true, title: 'Compose Message', children: [ ] } ]} />
); } componentDidMount() { this.loadAccounts(); this.startIo(); } } ReactDOM.render(, document.getElementById('app'));