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:active,
.folder-list .account-folders .folder.pressed .folder-list .listview:focus .account-folders .folder.selected
{ {
background: #43ace8; background: #43ace8;
border: 1px dotted gray; border: 1px dotted gray;
} }
.folder-list .account-folders .folder:active .msg-count, .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; 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 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.folders.map((f, i) => {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} {f.icon ? <img src={'icons/'+f.icon+'.png'} /> : null}
{' '} {' '}
<span>{f.name}</span> <span>{f.name}</span>
@ -558,6 +559,19 @@ var AccountFolders = React.createClass({
</div> </div>
</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) showCfg: function(ev)
{ {
var self = this; var self = this;
@ -573,7 +587,7 @@ var AccountFolders = React.createClass({
}, },
getInitialState: function() 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() onClick: function()
{ {
@ -598,6 +612,7 @@ var AccountFolders = React.createClass({
var FolderList = React.createClass({ var FolderList = React.createClass({
render: function() render: function()
{ {
var self = this;
return <div className={"folder-list"+(this.props.progress !== undefined ? ' progress-visible' : '')}> return <div className={"folder-list"+(this.props.progress !== undefined ? ' progress-visible' : '')}>
<div className="top-border-gradient"></div> <div className="top-border-gradient"></div>
<div className="bottom-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> <a className="button"><img src="icons/compose.png" /> Compose</a>
<DropDownButton dropdownId="check-send" className="check-send" icon="mail_check_send" /> <DropDownButton dropdownId="check-send" className="check-send" icon="mail_check_send" />
</div> </div>
<div className="listview"> // TODO: keyboard navigation
<div className="listview" tabIndex="1">
{this.props.accounts.map(function(account) { {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>
<div className="progress-bar" ref="pbar"> <div className="progress-bar" ref="pbar">
@ -618,6 +634,12 @@ var FolderList = React.createClass({
</div> </div>
</div> </div>
}, },
onSelectFolder: function(folders, i)
{
if (this.prevSelected && this.prevSelected != folders)
this.prevSelected.setState({ selected: -1 });
this.prevSelected = folders;
},
getInitialState: function() getInitialState: function()
{ {
return { pbarWidth: '' }; return { pbarWidth: '' };
@ -666,6 +688,7 @@ var TabPanel = React.createClass({
}, },
componentWillReceiveProps: function(nextProps, nextContent) componentWillReceiveProps: function(nextProps, nextContent)
{ {
// FIXME: Do not own tabs?
this.setState({ selected: this.state.selected % nextProps.tabs.length, tabs: nextProps.tabs }); this.setState({ selected: this.state.selected % nextProps.tabs.length, tabs: nextProps.tabs });
}, },
getInitialState: function() getInitialState: function()
@ -827,15 +850,22 @@ var ComposeWindow = React.createClass({
}); });
var MessageInList = React.createClass({ var MessageInList = React.createClass({
msgClasses: [ 'unread', 'unseen', 'replied', 'pinned', 'sent', 'unloaded', 'selected' ], msgClasses: [ 'unread', 'unseen', 'replied', 'pinned', 'sent', 'unloaded' ],
onClick: function() onClick: function()
{ {
Store.set('msg', this.props.msg); Store.set('msg', this.props.msg);
this.setState({ selected: true });
this.props.onClick(this);
},
getInitialState: function()
{
return { selected: false };
}, },
render: function() render: function()
{ {
var msg = this.props.msg; 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="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> <div className="subject" style={{ paddingLeft: (20+10*(msg.level||0)) }}>{msg.subject}</div>
{msg.thread ? <div className={'expand'+(msg.collapsed ? '' : ' collapse')}></div> : null} {msg.thread ? <div className={'expand'+(msg.collapsed ? '' : ' collapse')}></div> : null}
@ -894,6 +924,9 @@ var MessageList = React.createClass({
}, },
onMsgClick: function(msg) 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-table">
<div className="header"> <div className="header">
<div className="field">From</div> <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>
<div className="header"> <div className="header">
<div className="field">To</div> <div className="field">To</div>