,
- this.state.quickReply ?
+ this.props.quickReply ?
@@ -111,3 +90,5 @@ var MessageView = module.exports = React.createClass({
}
});
+
+module.exports = StoreListener(MessageView, (data) => { return { quickReply: data.quickReply, msg: data.msg }; });
diff --git a/Store.js b/Store.js
index 48f8b28..eef9bc6 100644
--- a/Store.js
+++ b/Store.js
@@ -1,26 +1,102 @@
-var Store = module.exports = {
- layout: 'message-on-right',
- quickReply: true,
- msg: null,
- threads: false,
+const superagent = require('superagent');
+const _ = require('./I18n.js');
- listeners: {},
- on: function(ev, cb)
- {
- this.listeners[ev] = this.listeners[ev] || [];
- this.listeners[ev].push(cb);
+var Store = module.exports = {
+ data: {
+ layout: 'message-on-right',
+ quickReply: true,
+ msg: null,
+ threads: false,
+ accounts: [],
},
- un: function(ev, cb)
+
+ listeners: [],
+ on: function(cb)
{
- 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);
+ this.listeners.push(cb);
+ },
+ un: function(cb)
+ {
+ for (var i = this.listeners.length; i >= 0; i--)
+ if (this.listeners[i] == cb)
+ this.listeners.splice(i, 1);
+ },
+ get: function(k)
+ {
+ return this.data[k];
},
set: function(k, v)
{
- this[k] = v;
- (this.listeners[k] || []).map(i => i());
+ this.data[k] = v;
+ (this.listeners || []).map(i => i());
+ },
+
+ loadAccounts: function()
+ {
+ superagent.get('backend/folders').end(function(err, res)
+ {
+ var ixOfAll = {
+ received: 1,
+ outbox: 3,
+ sent: 4,
+ drafts: 5,
+ spam: 6,
+ trash: 7
+ };
+ var accounts = [ {
+ name: _('All Messages'),
+ accountId: null,
+ unreadCount: 0,
+ folders: [
+ { name: _('Unread'), icon: 'mail_unread', unreadCount: 0, type: 'unread' },
+ { name: _('Received'), icon: 'mail_received', unreadCount: 0, type: 'inbox' },
+ { name: _('Pinned'), icon: 'mail_pinned', unreadCount: 0, type: 'pinned' },
+ { name: _('Outbox'), icon: 'mail_outbox', unreadCount: 0, type: 'outbox' },
+ { name: _('Sent'), icon: 'mail_sent', unreadCount: 0, type: 'sent' },
+ { name: _('Drafts'), icon: 'mail_drafts', unreadCount: 0, type: 'drafts' },
+ { name: _('Spam'), icon: 'mail_spam', unreadCount: 0, type: 'spam' },
+ { name: _('Trash'), icon: 'mail_trash', unreadCount: 0, type: 'trash' },
+ ],
+ } ];
+ for (let a of res.body.accounts)
+ {
+ let account = {
+ name: a.name,
+ email: a.email,
+ accountId: a.id,
+ unreadCount: 0,
+ warning: false,
+ folders: [
+ { name: _('Unread'), icon: 'mail_unread', unreadCount: 0, type: 'unread' },
+ { name: _('Pinned'), icon: 'mail_pinned', unreadCount: a.pinned_unread_count, type: 'pinned' },
+ ],
+ folderMap: a.foldermap,
+ folderTypes: {}
+ };
+ if (!account.folderMap.received)
+ {
+ account.folderMap.received = 'INBOX';
+ }
+ for (let f in account.folderMap)
+ {
+ account.folderTypes[account.folderMap[f]] = f;
+ }
+ for (let f of a.folders)
+ {
+ 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[0].unreadCount -= -f.unread_count;
+ if (account.folderTypes[f.name])
+ {
+ accounts[0].folders[ixOfAll[account.folderTypes[f.name]]].unreadCount -= -f.unread_count;
+ }
+ }
+ accounts.push(account);
+ accounts[0].unreadCount += account.unreadCount;
+ accounts[0].folders[0].unreadCount += account.unreadCount;
+ accounts[0].folders[2].unreadCount += account.folders[1].unreadCount;
+ }
+ Store.set('accounts', accounts);
+ });
}
};
diff --git a/StoreListener.js b/StoreListener.js
new file mode 100644
index 0000000..b34403b
--- /dev/null
+++ b/StoreListener.js
@@ -0,0 +1,39 @@
+const React = require('react');
+const Store = require('./Store.js');
+
+// "react-redux connect()"-like example
+var StoreListener = React.createClass({
+ componentDidMount: function()
+ {
+ Store.on(this.update);
+ },
+ componentWillUnmount: function()
+ {
+ Store.un(this.update);
+ },
+ update: function()
+ {
+ var newState = this.props.mapStateToProps(Store.data);
+ for (var i in newState)
+ {
+ if (this.state[i] != newState[i])
+ {
+ this.setState(newState);
+ return;
+ }
+ }
+ },
+ getInitialState: function()
+ {
+ return { ...this.props.initial, ...this.props.mapStateToProps(Store.data) };
+ },
+ render: function()
+ {
+ return React.createElement(this.props.wrappedComponent, this.state);
+ }
+});
+
+module.exports = function(component, map, initial)
+{
+ return React.createElement(StoreListener, { wrappedComponent: component, mapStateToProps: map, initial: initial||{} });
+};
diff --git a/mail.js b/mail.js
index 8f0d413..69b06df 100644
--- a/mail.js
+++ b/mail.js
@@ -6,67 +6,11 @@ const MessageList = require('./MessageList.js');
const MessageView = require('./MessageView.js');
const TabPanel = require('./TabPanel.js');
const Store = require('./Store.js');
+const StoreListener = require('./StoreListener.js');
const AllDropdowns = require('./AllDropdowns.js');
window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame;
-var accounts = [
- {
- name: 'All Messages',
- accountId: null,
- unreadCount: 65,
- folders: [
- { name: 'Unread', icon: 'mail_unread', unreadCount: 65 },
- { name: 'Received', icon: 'mail_received', unreadCount: 65 },
- { name: 'Pinned', icon: 'mail_pinned' },
- { name: 'Outbox', icon: 'mail_outbox' },
- { name: 'Sent', icon: 'mail_sent' },
- { name: 'Drafts', icon: 'mail_drafts', unreadCount: 507 },
- { name: 'Spam', icon: 'mail_spam' },
- { name: 'Trash', icon: 'mail_trash', unreadCount: 423 },
- ],
- },
- {
- name: 'vitalif@mail.ru',
- accountId: 1,
- unreadCount: 48,
- warning: true,
- folders: [
- { name: 'Unread', icon: 'mail_unread', unreadCount: 48 },
- { name: 'INBOX', icon: 'folder', unreadCount: 48 },
- { name: 'TODO', icon: 'folder' },
- { name: 'Архив', icon: 'folder' },
- { name: 'Корзина', icon: 'mail_trash' },
- { name: 'Отправленные', icon: 'mail_sent' },
- { name: 'Спам', icon: 'mail_spam' },
- { name: 'Черновики', icon: 'mail_drafts' },
- { name: 'Pinned', icon: 'mail_pinned' },
- ],
- },
- {
- name: 'vitalif@yourcmc.ru',
- accountId: 2,
- unreadCount: 16,
- loading: true,
- folders: [
- { name: 'Unread', icon: 'mail_unread', unreadCount: 16 },
- { name: 'Drafts', icon: 'mail_drafts' },
- { name: 'HAM', icon: 'folder' },
- { name: 'INBOX', icon: 'folder', unreadCount: 16 },
- { name: 'intermedia_su', icon: 'folder' },
- { name: 'Sent', icon: 'mail_sent' },
- { name: 'SPAM', icon: 'mail_spam' },
- { name: 'TRASH', icon: 'mail_trash' },
- { name: 'Pinned', icon: 'mail_pinned' },
- ],
- }
-];
-
-var composeAccounts = [
- { name: 'Виталий Филиппов', email: 'vitalif@mail.ru' },
- { name: 'Vitaliy Filippov', email: 'vitalif@yourcmc.ru' }
-];
-
var msg2 = [];
msg2[5] = {
subject: 'кошку хочешь?))',
@@ -87,7 +31,7 @@ msg2[5] = {
} ]
};
-var listGroups = [ {
+Store.listGroups = [ {
name: 'TODAY',
messageCount: 10,
messages: [ {
@@ -109,7 +53,26 @@ Best regards,
\
messages: msg2
} ];
-var AllTabs = React.createClass({
+var AllTabs = StoreListener(TabPanel, function(data)
+{
+ return { tabs: [
+ {
+ className: data.layout,
+ noclose: true,
+ icon: 'mail_unread',
+ title: 'Unread (64)',
+ children: [ MessageList, MessageView ]
+ },
+ {
+ icon: 'mail_drafts',
+ i16: true,
+ title: 'Compose Message',
+ children: [ ComposeWindow ]
+ }
+ ] }
+});
+
+/*React.createClass({
componentDidMount: function()
{
Store.on('layout', this.setLayout);
@@ -150,29 +113,17 @@ var AllTabs = React.createClass({
},
render: function()
{
- return React.createElement(TabPanel, { tabs: [
- {
- className: this.state.layout,
- noclose: true,
- icon: 'mail_unread',
- title: 'Unread (64)',
- children: [
,
]
- },
- {
- icon: 'mail_drafts',
- i16: true,
- title: 'Compose Message',
- children:
- }
- ] });
+ return React.createElement();
}
-});
+});*/
ReactDOM.render(
{AllDropdowns()}
-
-
+ {StoreListener(FolderList, (data) => { return { accounts: data.accounts }; }, { progress: 33 })}
+ {AllTabs}
,
document.body
);
+
+Store.loadAccounts();
diff --git a/package.json b/package.json
index 9d40b93..65f4665 100644
--- a/package.json
+++ b/package.json
@@ -17,6 +17,7 @@
"babel-plugin-transform-es2015-block-scoping": "latest",
"babel-plugin-transform-es2015-classes": "latest",
"babel-plugin-transform-es2015-computed-properties": "latest",
+ "babel-plugin-transform-es2015-for-of": "latest",
"babel-plugin-transform-es2015-destructuring": "latest",
"babel-plugin-transform-es2015-shorthand-properties": "latest",
"babel-plugin-transform-object-rest-spread": "latest",
@@ -25,10 +26,12 @@
"react-dom": "latest",
"uglifyjs": "latest",
"uglifyify": "latest",
- "eslint": "latest"
+ "eslint": "latest",
+ "superagent": "latest"
},
"scripts": {
"compile": "browserify -t babelify -t uglifyify mail.js | uglifyjs -cm > mail.c.js",
+ "watch-dev": "watchify -t babelify mail.js -o mail.c.js",
"watch": "watchify -t babelify -t uglifyify mail.js -o 'uglifyjs -cm > mail.c.js'"
}
}