highlight selected messages and folders

master
Vitaliy Filippov 2016-06-22 14:31:15 +03:00
parent 29e4ff8ff7
commit 2ec51f96a3
2 changed files with 42 additions and 9 deletions

View File

@ -556,14 +556,14 @@ div
}
.folder-list .account-folders .folder:active,
.folder-list .account-folders .folder.pressed
.folder-list .listview:focus .account-folders .folder.selected
{
background: #43ace8;
border: 1px dotted gray;
}
.folder-list .account-folders .folder:active .msg-count,
.folder-list .account-folders .folder.pressed .msg-count
.folder-list .listview:focus .account-folders .folder.selected .msg-count
{
background: #7bc5ef;
}

47
mail.js
View File

@ -547,7 +547,8 @@ var AccountFolders = React.createClass({
<div className={"account-folders"+(this.state.collapsed ? ' collapsed' : '')} style={{ height: this.state.h }}>
<div ref="vis" className={'visible-part'+(this.state.animating ? ' animating' : '')}>
{this.props.folders.map((f, i) =>
<div key={'f'+i} className={'folder'+(f.unreadCount > 0 ? ' with-unread' : '')+(f.selected ? ' selected' : '')}>
<div key={'f'+i} data-i={i} className={'folder'+(f.unreadCount > 0 ? ' with-unread' : '')+
(this.state.selected == i ? ' selected' : '')} onClick={this.selectFolder}>
{f.icon ? <img src={'icons/'+f.icon+'.png'} /> : null}
{' '}
<span>{f.name}</span>
@ -558,6 +559,19 @@ var AccountFolders = React.createClass({
</div>
</div>
},
selectFolder: function(ev)
{
var t = ev.target;
while (t && !t.getAttribute('data-i') && t != this.refs.vis)
t = t.parentNode;
if (t && t != this.refs.vis)
{
var i = t.getAttribute('data-i');
this.setState({ selected: i });
this.props.onSelect(this, i);
}
// FIXME: send select event + switch focus to message list if folder changed
},
showCfg: function(ev)
{
var self = this;
@ -573,7 +587,7 @@ var AccountFolders = React.createClass({
},
getInitialState: function()
{
return { collapsed: this.props.collapsed, animating: false, h: null, cfgPressed: false };
return { collapsed: this.props.collapsed, animating: false, h: null, cfgPressed: false, selected: -1 };
},
onClick: function()
{
@ -598,6 +612,7 @@ var AccountFolders = React.createClass({
var FolderList = React.createClass({
render: function()
{
var self = this;
return <div className={"folder-list"+(this.props.progress !== undefined ? ' progress-visible' : '')}>
<div className="top-border-gradient"></div>
<div className="bottom-border-gradient"></div>
@ -605,9 +620,10 @@ var FolderList = React.createClass({
<a className="button"><img src="icons/compose.png" /> Compose</a>
<DropDownButton dropdownId="check-send" className="check-send" icon="mail_check_send" />
</div>
<div className="listview">
// TODO: keyboard navigation
<div className="listview" tabIndex="1">
{this.props.accounts.map(function(account) {
return <AccountFolders key={'a'+account.accountId} {...account} />
return <AccountFolders key={'a'+account.accountId} onSelect={self.onSelectFolder} {...account} />
})}
</div>
<div className="progress-bar" ref="pbar">
@ -618,6 +634,12 @@ var FolderList = React.createClass({
</div>
</div>
},
onSelectFolder: function(folders, i)
{
if (this.prevSelected && this.prevSelected != folders)
this.prevSelected.setState({ selected: -1 });
this.prevSelected = folders;
},
getInitialState: function()
{
return { pbarWidth: '' };
@ -666,6 +688,7 @@ var TabPanel = React.createClass({
},
componentWillReceiveProps: function(nextProps, nextContent)
{
// FIXME: Do not own tabs?
this.setState({ selected: this.state.selected % nextProps.tabs.length, tabs: nextProps.tabs });
},
getInitialState: function()
@ -827,15 +850,22 @@ var ComposeWindow = React.createClass({
});
var MessageInList = React.createClass({
msgClasses: [ 'unread', 'unseen', 'replied', 'pinned', 'sent', 'unloaded', 'selected' ],
msgClasses: [ 'unread', 'unseen', 'replied', 'pinned', 'sent', 'unloaded' ],
onClick: function()
{
Store.set('msg', this.props.msg);
this.setState({ selected: true });
this.props.onClick(this);
},
getInitialState: function()
{
return { selected: false };
},
render: function()
{
var msg = this.props.msg;
return <div className={'message'+(this.msgClasses.map(c => (msg[c] ? ' '+c : '')).join(''))+(msg.thread ? ' thread0' : '')} onClick={this.onClick}>
return <div className={'message'+(this.msgClasses.map(c => (msg[c] ? ' '+c : '')).join(''))+
(this.state.selected ? ' selected' : '')+(msg.thread ? ' thread0' : '')} onMouseDown={this.onClick}>
<div className="icon" style={{ width: (20+10*(msg.level||0)), backgroundPosition: (10*(msg.level||0))+'px 7px' }}></div>
<div className="subject" style={{ paddingLeft: (20+10*(msg.level||0)) }}>{msg.subject}</div>
{msg.thread ? <div className={'expand'+(msg.collapsed ? '' : ' collapse')}></div> : null}
@ -894,6 +924,9 @@ var MessageList = React.createClass({
},
onMsgClick: function(msg)
{
if (this.prevSelected && this.prevSelected != msg)
this.prevSelected.setState({ selected: false });
this.prevSelected = msg;
}
});
@ -962,7 +995,7 @@ var MessageView = React.createClass({
<div className="header-table">
<div className="header">
<div className="field">From</div>
<div className="value"><a className="button">{msg.from+' <'+msg.fromEmail+'>'}></a></div>
<div className="value"><a className="button">{msg.from+' <'+msg.fromEmail+'>'}</a></div>
</div>
<div className="header">
<div className="field">To</div>