Read/unread change frontend
parent
89a44d590c
commit
29fb001af3
|
@ -25,7 +25,7 @@ export default class AccountFolders extends React.PureComponent
|
||||||
<div className={"account-folders"+(this.state.collapsed ? ' collapsed' : '')} style={{ height: this.state.h }}>
|
<div className={"account-folders"+(this.state.collapsed ? ' collapsed' : '')} style={{ height: this.state.h }}>
|
||||||
<div ref="vis" className={'visible-part'+(this.state.animating ? ' animating' : '')}>
|
<div ref="vis" className={'visible-part'+(this.state.animating ? ' animating' : '')}>
|
||||||
{this.props.account.folders.map((f, i) =>
|
{this.props.account.folders.map((f, i) =>
|
||||||
<div key={'f'+i} data-i={i} className={'folder'+(f.unreadCount > 0 ? ' with-unread' : '')+
|
<div key={'f'+i} data-i={i} className={'folder'+(f.type != 'pinned' && f.unreadCount > 0 ? ' with-unread' : '')+
|
||||||
(this.props.selected == i ? ' selected' : '')} onClick={this.selectFolder}>
|
(this.props.selected == i ? ' selected' : '')} onClick={this.selectFolder}>
|
||||||
{f.icon ? <img src={'icons/'+f.icon+'.png'} /> : null}
|
{f.icon ? <img src={'icons/'+f.icon+'.png'} /> : null}
|
||||||
{' '}
|
{' '}
|
||||||
|
|
|
@ -1,10 +1,23 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
import DropDownBase from './DropDownBase.js';
|
import DropDownBase from './DropDownBase.js';
|
||||||
|
|
||||||
export default class DropDownButton extends React.PureComponent
|
export default class DropDownButton extends React.PureComponent
|
||||||
{
|
{
|
||||||
state = { pressed: false, checked: false }
|
static propTypes = {
|
||||||
|
checkable: PropTypes.bool,
|
||||||
|
whole: PropTypes.bool,
|
||||||
|
checked: PropTypes.bool,
|
||||||
|
className: PropTypes.string,
|
||||||
|
icon: PropTypes.string,
|
||||||
|
checkedIcon: PropTypes.string,
|
||||||
|
text: PropTypes.string,
|
||||||
|
checkedText: PropTypes.string,
|
||||||
|
onClick: PropTypes.func,
|
||||||
|
}
|
||||||
|
|
||||||
|
state = { pressed: false }
|
||||||
|
|
||||||
componentDidUpdate(prevProps, prevState)
|
componentDidUpdate(prevProps, prevState)
|
||||||
{
|
{
|
||||||
|
@ -17,12 +30,12 @@ export default class DropDownButton extends React.PureComponent
|
||||||
|
|
||||||
render()
|
render()
|
||||||
{
|
{
|
||||||
return <a ref="btn" title={(this.state.checked ? this.props.checkedTitle : null) || this.props.title} onClick={this.onClickButton}
|
return <a ref="btn" title={(this.props.checked ? this.props.checkedTitle : null) || this.props.title} onClick={this.onClickButton}
|
||||||
className={'button '+(this.props.dropdownId ? 'show-dropdown ' : '')+(this.state.checked ? 'checked ' : '')+
|
className={'button '+(this.props.dropdownId ? 'show-dropdown ' : '')+(this.props.checked ? 'checked ' : '')+
|
||||||
(this.props.hidden ? 'hidden ' : '')+
|
(this.props.hidden ? 'hidden ' : '')+
|
||||||
(this.state.pressed ? 'pressed ' : '')+(this.props.className || '')}>
|
(this.state.pressed ? 'pressed ' : '')+(this.props.className || '')}>
|
||||||
{this.props.icon ? <img src={'icons/'+(this.state.checked && this.props.checkedIcon || this.props.icon)+'.png'} /> : null}
|
{this.props.icon ? <img src={'icons/'+(this.props.checked ? this.props.checkedIcon : this.props.icon)+'.png'} /> : null}
|
||||||
{this.state.checked && this.props.checkedText || this.props.text || null}
|
{(this.props.checked ? this.props.checkedText : this.props.text) || null}
|
||||||
{this.props.dropdownId ? <span className="down" onClick={this.onClickDown}></span> : null}
|
{this.props.dropdownId ? <span className="down" onClick={this.onClickDown}></span> : null}
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
|
@ -50,9 +63,8 @@ export default class DropDownButton extends React.PureComponent
|
||||||
this.toggle();
|
this.toggle();
|
||||||
if (this.props.checkable)
|
if (this.props.checkable)
|
||||||
{
|
{
|
||||||
this.setState({ checked: !this.state.checked });
|
|
||||||
if (this.props.onClick)
|
if (this.props.onClick)
|
||||||
this.props.onClick(this.state.checked);
|
this.props.onClick(!this.props.checked);
|
||||||
}
|
}
|
||||||
else if (this.props.onClick)
|
else if (this.props.onClick)
|
||||||
this.props.onClick();
|
this.props.onClick();
|
||||||
|
|
|
@ -58,7 +58,12 @@ export default class MessageView extends React.PureComponent
|
||||||
<DropDownButton dropdownId="reply" icon="mail_reply" text="Reply" />
|
<DropDownButton dropdownId="reply" icon="mail_reply" text="Reply" />
|
||||||
<a className="button"><img src="icons/mail_reply_all.png" />Reply All</a>
|
<a className="button"><img src="icons/mail_reply_all.png" />Reply All</a>
|
||||||
<DropDownButton dropdownId="forward" icon="mail_forward" text="Forward" />
|
<DropDownButton dropdownId="forward" icon="mail_forward" text="Forward" />
|
||||||
<DropDownButton className="action-read" icon="read" checkedIcon="read_selected" checkable="1" text="Read" checkedText="Unread" />
|
<DropDownButton className="action-read"
|
||||||
|
checkable="1" checked={msg && !msg.flags.filter(f => f == 'unread').length}
|
||||||
|
checkedIcon="read_selected" icon="read"
|
||||||
|
checkedText="Unread" text="Read"
|
||||||
|
onClick={this.props.onToggleRead}
|
||||||
|
/>
|
||||||
<DropDownButton className="action-spam" icon="spam" checkedIcon="spam_selected" checkable="1" text="Spam" checkedText="Not Spam" />
|
<DropDownButton className="action-spam" icon="spam" checkedIcon="spam_selected" checkable="1" text="Spam" checkedText="Not Spam" />
|
||||||
<DropDownButton dropdownId="delete" className="action-delete" icon="delete" checkedIcon="delete_selected" checkable="1" text="Delete" checkedText="Undelete" />
|
<DropDownButton dropdownId="delete" className="action-delete" icon="delete" checkedIcon="delete_selected" checkable="1" text="Delete" checkedText="Undelete" />
|
||||||
<a className="button show-dropdown"><img src="icons/label.png" />Label <span className="down"></span></a>
|
<a className="button show-dropdown"><img src="icons/label.png" />Label <span className="down"></span></a>
|
||||||
|
|
48
mail.js
48
mail.js
|
@ -91,7 +91,7 @@ class MainWindow extends React.PureComponent
|
||||||
warning: false,
|
warning: false,
|
||||||
folders: [
|
folders: [
|
||||||
{ name: _('Unread'), icon: 'mail_unread', unreadCount: 0, type: 'unread' },
|
{ name: _('Unread'), icon: 'mail_unread', unreadCount: 0, type: 'unread' },
|
||||||
{ name: _('Pinned'), icon: 'mail_pinned', unreadCount: a.pinned_unread_count, type: 'pinned' },
|
{ name: _('Pinned'), icon: 'mail_pinned', unreadCount: a.pinned_count-0, type: 'pinned' },
|
||||||
],
|
],
|
||||||
folderMap: a.foldermap,
|
folderMap: a.foldermap,
|
||||||
folderTypes: {}
|
folderTypes: {}
|
||||||
|
@ -105,10 +105,20 @@ class MainWindow extends React.PureComponent
|
||||||
account.folderTypes[account.folderMap[f]] = f;
|
account.folderTypes[account.folderMap[f]] = f;
|
||||||
}
|
}
|
||||||
for (let f of a.folders)
|
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');
|
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 });
|
account.folders.push({ name: f.name, icon: icon, unreadCount: f.unread_count-0, folderId: f.id });
|
||||||
account.folders[0].unreadCount += (f.unread_count-0);
|
if (f.kind != 'sent' && f.kind != 'trash' && f.kind != 'drafts')
|
||||||
|
{
|
||||||
|
account.folders[0].unreadCount += (f.unread_count-0);
|
||||||
|
}
|
||||||
if (account.folderTypes[f.name])
|
if (account.folderTypes[f.name])
|
||||||
{
|
{
|
||||||
accounts[0].folders[ixOfAll[account.folderTypes[f.name]]].unreadCount += (f.unread_count-0);
|
accounts[0].folders[ixOfAll[account.folderTypes[f.name]]].unreadCount += (f.unread_count-0);
|
||||||
|
@ -116,8 +126,10 @@ class MainWindow extends React.PureComponent
|
||||||
account.unreadCount += (f.unread_count-0);
|
account.unreadCount += (f.unread_count-0);
|
||||||
}
|
}
|
||||||
accounts.push(account);
|
accounts.push(account);
|
||||||
accounts[0].unreadCount += account.unreadCount;
|
// unread total
|
||||||
accounts[0].folders[0].unreadCount += account.unreadCount;
|
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;
|
accounts[0].folders[2].unreadCount += account.folders[1].unreadCount;
|
||||||
}
|
}
|
||||||
this.setState({ accounts });
|
this.setState({ accounts });
|
||||||
|
@ -172,6 +184,32 @@ class MainWindow extends React.PureComponent
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 = () =>
|
startResync = () =>
|
||||||
{
|
{
|
||||||
superagent.post('backend/sync').send().end((err, res) =>
|
superagent.post('backend/sync').send().end((err, res) =>
|
||||||
|
@ -309,6 +347,7 @@ class MainWindow extends React.PureComponent
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<MailSettingsWindow
|
<MailSettingsWindow
|
||||||
|
id="settings"
|
||||||
defaultSorting={{
|
defaultSorting={{
|
||||||
sort: {
|
sort: {
|
||||||
sortby: 'sent date',
|
sortby: 'sent date',
|
||||||
|
@ -352,6 +391,7 @@ class MainWindow extends React.PureComponent
|
||||||
layout={this.state.layout}
|
layout={this.state.layout}
|
||||||
quickReply={this.state.quickReply}
|
quickReply={this.state.quickReply}
|
||||||
msg={this.state.msg}
|
msg={this.state.msg}
|
||||||
|
onToggleRead={this.toggleRead}
|
||||||
/>,
|
/>,
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue