highlight selected messages and folders
parent
29e4ff8ff7
commit
2ec51f96a3
4
mail.css
4
mail.css
|
@ -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
47
mail.js
|
@ -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>
|
||||||
|
|
Loading…
Reference in New Issue