Switch quick reply on/off, select viewed msg
parent
62b30d6a39
commit
29e4ff8ff7
120
mail.js
120
mail.js
|
@ -1,5 +1,8 @@
|
|||
window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame;
|
||||
|
||||
var WeekDays = [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ];
|
||||
var Months = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ];
|
||||
|
||||
function getOffset(elem)
|
||||
{
|
||||
if (elem.getBoundingClientRect)
|
||||
|
@ -30,16 +33,27 @@ function getOffset(elem)
|
|||
|
||||
var Store = {
|
||||
layout: 'message-on-right',
|
||||
quickReply: true,
|
||||
msg: null,
|
||||
|
||||
listeners: {},
|
||||
on: function(ev, cb)
|
||||
{
|
||||
this.listeners[ev] = this.listeners[ev] || [];
|
||||
this.listeners[ev].push(cb);
|
||||
},
|
||||
setLayout: function(l)
|
||||
un: function(ev, cb)
|
||||
{
|
||||
this.layout = l;
|
||||
(this.listeners['setLayout'] || []).map(i => i());
|
||||
if (!this.listeners[ev])
|
||||
return;
|
||||
for (var i = this.listeners[ev].length; i >= 0; i--)
|
||||
if (this.listeners[ev] == cb)
|
||||
this.listeners[ev].splice(i, 1);
|
||||
},
|
||||
set: function(k, v)
|
||||
{
|
||||
this[k] = v;
|
||||
(this.listeners[k] || []).map(i => i());
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -443,25 +457,35 @@ var MailSettingsWindow = React.createClass({
|
|||
},
|
||||
componentDidMount: function()
|
||||
{
|
||||
Store.on('setLayout', this.setLayout);
|
||||
Store.on('layout', this.setLayout);
|
||||
Store.on('quickReply', this.setQuickReply);
|
||||
},
|
||||
componentWillUnmount: function()
|
||||
{
|
||||
Store.un('layout', this.setLayout);
|
||||
Store.un('quickReply', this.setQuickReply);
|
||||
},
|
||||
setLayout: function()
|
||||
{
|
||||
this.setState({ layout: Store.layout });
|
||||
},
|
||||
setQuickReply: function()
|
||||
{
|
||||
this.setState({ showQuickReply: Store.quickReply });
|
||||
},
|
||||
switchLayout: function(ev)
|
||||
{
|
||||
var t = ev.target.nodeName == 'A' ? ev.target : ev.target.parentNode;
|
||||
var l = / mail-(\S+)/.exec(t.className)[1];
|
||||
Store.setLayout(l);
|
||||
Store.set('layout', l);
|
||||
},
|
||||
getInitialState: function()
|
||||
{
|
||||
return { showQuickReply: this.props.showQuickReply && true, layout: Store.layout };
|
||||
return { showQuickReply: Store.quickReply, layout: Store.layout };
|
||||
},
|
||||
showQuickReply: function()
|
||||
{
|
||||
this.setState({ showQuickReply: !this.state.showQuickReply });
|
||||
Store.set('quickReply', !this.state.showQuickReply);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -495,7 +519,6 @@ var dropdown_settings = React.createElement(
|
|||
MailSettingsWindow, {
|
||||
id: 'settings',
|
||||
window: true,
|
||||
showQuickReply: true,
|
||||
markDelay: -1,
|
||||
defaultSorting: {
|
||||
sort: {
|
||||
|
@ -686,7 +709,7 @@ function formatBytes(s)
|
|||
function formatDate(dt)
|
||||
{
|
||||
if (!(dt instanceof Date))
|
||||
dt = new Date(dt);
|
||||
dt = new Date(dt.replace(' ', 'T'));
|
||||
var tod = new Date();
|
||||
tod.setHours(0);
|
||||
tod.setMinutes(0);
|
||||
|
@ -702,9 +725,7 @@ function formatDate(dt)
|
|||
}
|
||||
else if (dt.getTime() < tod.getTime())
|
||||
{
|
||||
var wd = [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ];
|
||||
var mon = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ];
|
||||
return wd[dt.getDay()]+' '+dt.getDate()+' '+mon[dt.getMonth()];
|
||||
return WeekDays[dt.getDay()]+' '+dt.getDate()+' '+Months[dt.getMonth()];
|
||||
}
|
||||
var h = dt.getHours();
|
||||
var m = dt.getMinutes();
|
||||
|
@ -807,10 +828,14 @@ var ComposeWindow = React.createClass({
|
|||
|
||||
var MessageInList = React.createClass({
|
||||
msgClasses: [ 'unread', 'unseen', 'replied', 'pinned', 'sent', 'unloaded', 'selected' ],
|
||||
onClick: function()
|
||||
{
|
||||
Store.set('msg', this.props.msg);
|
||||
},
|
||||
render: function()
|
||||
{
|
||||
var msg = this.props.msg;
|
||||
return <div className={'message'+(this.msgClasses.map(c => (msg[c] ? ' '+c : '')).join(''))+(msg.thread ? ' thread0' : '')}>
|
||||
return <div className={'message'+(this.msgClasses.map(c => (msg[c] ? ' '+c : '')).join(''))+(msg.thread ? ' thread0' : '')} onClick={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}
|
||||
|
@ -818,7 +843,7 @@ var MessageInList = React.createClass({
|
|||
<div className="from" style={{ left: (21+10*(msg.level||0)) }}>{(msg.sent || msg.outgoing ? 'To '+msg.to : msg.from)}</div>
|
||||
<div className="size">{formatBytes(msg.size)}</div>
|
||||
<div className="attach" style={msg.attach ? null : { display: 'none' }}></div>
|
||||
<div className="time">{formatDate(msg.date)}</div>
|
||||
<div className="time">{formatDate(msg.time)}</div>
|
||||
</div>
|
||||
}
|
||||
});
|
||||
|
@ -855,10 +880,10 @@ var MessageList = React.createClass({
|
|||
i > 0 ? <div className="day">{grp.name}</div> : null,
|
||||
<div className="day-list">
|
||||
{grp.messages.map(msg => [
|
||||
<MessageInList msg={msg} />,
|
||||
<MessageInList msg={msg} onClick={this.onMsgClick} />,
|
||||
(msg.thread ?
|
||||
<div className="thread">
|
||||
{msg.thread.map(reply => <MessageInList msg={reply} />)}
|
||||
{msg.thread.map(reply => <MessageInList msg={reply} onClick={this.onMsgClick} />)}
|
||||
</div>
|
||||
: null)
|
||||
])}
|
||||
|
@ -866,17 +891,48 @@ var MessageList = React.createClass({
|
|||
])}
|
||||
</div>
|
||||
</div>
|
||||
},
|
||||
onMsgClick: function(msg)
|
||||
{
|
||||
}
|
||||
});
|
||||
|
||||
var MessageView = React.createClass({
|
||||
formatLongTime: function(d)
|
||||
formatLongDate: function(dt)
|
||||
{
|
||||
//Чт 09 июн 2016 21:10:50
|
||||
if (!(dt instanceof Date))
|
||||
dt = new Date(dt.replace(' ', 'T'));
|
||||
var h = dt.getHours();
|
||||
var m = dt.getMinutes();
|
||||
var s = dt.getSeconds();
|
||||
return WeekDays[dt.getDay()]+' '+dt.getDate()+' '+Months[dt.getMonth()]+' '+dt.getFullYear()+' '+(h < 10 ? '0' : '')+h+':'+(m < 10 ? '0' : '')+m+':'+(s < 10 ? '0' : '')+s
|
||||
//return dt.toLocaleString();
|
||||
},
|
||||
componentDidMount: function()
|
||||
{
|
||||
Store.on('quickReply', this.setQuickReply);
|
||||
Store.on('msg', this.setMsg);
|
||||
},
|
||||
componentWillUnmount: function()
|
||||
{
|
||||
Store.un('quickReply', this.setQuickReply);
|
||||
Store.un('msg', this.setMsg);
|
||||
},
|
||||
setQuickReply: function()
|
||||
{
|
||||
this.setState({ quickReply: Store.quickReply });
|
||||
},
|
||||
setMsg: function()
|
||||
{
|
||||
this.setState({ msg: Store.msg });
|
||||
},
|
||||
getInitialState: function()
|
||||
{
|
||||
return { quickReply: Store.quickReply };
|
||||
},
|
||||
render: function()
|
||||
{
|
||||
var msg = this.props.msg;
|
||||
var msg = this.state.msg;
|
||||
return <div className={'message-view'+(!msg ? ' no-mail-shown' : '')}>
|
||||
<div className="actions">
|
||||
<DropDownButton dropdownId="reply" icon="mail_reply" text="Reply" />
|
||||
|
@ -900,13 +956,13 @@ var MessageView = React.createClass({
|
|||
<div className="headers">
|
||||
<div className="top">
|
||||
<div className="pin"></div>
|
||||
<div className="time">{this.formatLongTime(msg.time)}</div>
|
||||
<div className="time">{this.formatLongDate(msg.time)}</div>
|
||||
<div className="subject">{msg.subject}</div>
|
||||
</div>
|
||||
<div className="header-table">
|
||||
<div className="header">
|
||||
<div className="field">From</div>
|
||||
<div className="value"><a className="button">{msg.from}</a></div>
|
||||
<div className="value"><a className="button">{msg.from+' <'+msg.fromEmail+'>'}></a></div>
|
||||
</div>
|
||||
<div className="header">
|
||||
<div className="field">To</div>
|
||||
|
@ -935,7 +991,8 @@ var MessageView = React.createClass({
|
|||
<label><input type="checkbox" /> Always load from {msg.from}</label>
|
||||
</div>
|
||||
: null),
|
||||
<div className="text" dangerouslySetInnerHTML={msg.body}></div>,
|
||||
<div className="text" dangerouslySetInnerHTML={{ __html: msg.body }}></div>,
|
||||
this.state.quickReply ?
|
||||
<div className="quick-reply">
|
||||
<textarea></textarea>
|
||||
<div className="btns">
|
||||
|
@ -943,6 +1000,7 @@ var MessageView = React.createClass({
|
|||
<a className="button"><img src="icons/mail_reply_all.png" /> Quick Reply All</a>
|
||||
</div>
|
||||
</div>
|
||||
: null
|
||||
] : null}
|
||||
</div>
|
||||
}
|
||||
|
@ -1010,13 +1068,19 @@ var listGroups = [ {
|
|||
messages: [ {
|
||||
subject: 'кошку хочешь?))',
|
||||
sent: true,
|
||||
from: 'Виталий Филиппов',
|
||||
fromEmail: 'vitalif@mail.ru',
|
||||
to: 'Margarita Philippova',
|
||||
date: '2016-06-14 21:24',
|
||||
time: '2016-06-14 21:24',
|
||||
body: 'к нам тут пришла какая-то и к нам в дом рвётся, симпатишная) потеряшка какая-то, но явно домашняя, не боится людей))',
|
||||
thread: [ {
|
||||
subject: 'Re: кошку хочешь?))',
|
||||
from: 'Margarita Philippova',
|
||||
date: '2016-06-14 22:31',
|
||||
level: 1
|
||||
fromEmail: 'philippova.marga@gmail.com',
|
||||
to: 'Виталий Филиппов',
|
||||
time: '2016-06-14 22:31',
|
||||
level: 1,
|
||||
body: 'Нет, конечно, не хочу. Я уеду в Баку, а кошка как? Уеду в Астану - а кошка как? Наташа меня Сухорукова приглашает в Барселону - а кошку куда? Я только испытала радость облегчения от того, что у меня больше нет горшочных цветов - и кошку мне? НЕт! Папику предложи - у него уже много зверья, одной кошкой больше - одной меньше - какая разница?'
|
||||
} ]
|
||||
} ]
|
||||
} ];
|
||||
|
@ -1024,7 +1088,11 @@ var listGroups = [ {
|
|||
var AllTabs = React.createClass({
|
||||
componentDidMount: function()
|
||||
{
|
||||
Store.on('setLayout', this.setLayout);
|
||||
Store.on('layout', this.setLayout);
|
||||
},
|
||||
componentWillUnmount: function()
|
||||
{
|
||||
Store.un('layout', this.setLayout);
|
||||
},
|
||||
setLayout: function()
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue