-
-
From
-
-
+ return (
+
+
+
+
+
+
From
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
+
);
}
-});
+}
-module.exports = StoreListener(ComposeWindow, (data) => { return { accounts: data.accounts }; });
+export default StoreListener(ComposeWindow, (data) => { return { accounts: data.accounts }; });
diff --git a/DropDownBase.js b/DropDownBase.js
index b8ce57c..6ce8923 100644
--- a/DropDownBase.js
+++ b/DropDownBase.js
@@ -1,35 +1,13 @@
-function getOffset(elem)
-{
- if (elem.getBoundingClientRect)
- {
- var box = elem.getBoundingClientRect();
- var body = document.body;
- var docElem = document.documentElement;
- var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop;
- var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft;
- var clientTop = docElem.clientTop || body.clientTop || 0;
- var clientLeft = docElem.clientLeft || body.clientLeft || 0;
- var top = box.top + scrollTop - clientTop;
- var left = box.left + scrollLeft - clientLeft;
- return { top: Math.round(top), left: Math.round(left) };
- }
- else
- {
- var top = 0, left = 0;
- while(elem)
- {
- top = top + parseInt(elem.offsetTop);
- left = left + parseInt(elem.offsetLeft);
- elem = elem.offsetParent;
- }
- return { top: top, left: left };
- }
-}
+import React from 'react';
-var DropDownBase = module.exports = {
- instances: {},
- currentVisible: null,
- componentDidMount: function()
+export default class DropDownBase extends React.PureComponent
+{
+ static instances = {};
+ static currentVisible = null;
+
+ state = { visible: false, top: 0, left: 0, calloutLeft: null, selectedItem: -1 };
+
+ componentDidMount()
{
if (!DropDownBase.setBodyListener)
{
@@ -38,36 +16,38 @@ var DropDownBase = module.exports = {
DropDownBase.setBodyListener = true;
}
DropDownBase.instances[this.props.id] = this;
- },
- hideAll: function()
+ }
+
+ static hideAll()
{
for (var i in DropDownBase.instances)
DropDownBase.instances[i].hide();
- },
- repositionCurrent: function()
+ }
+
+ static repositionCurrent()
{
if (DropDownBase.currentVisible)
DropDownBase.currentVisible[0].showAt(DropDownBase.currentVisible[1], DropDownBase.currentVisible[0].onClose);
- },
- componentWillUnmount: function()
+ }
+
+ componentWillUnmount()
{
delete DropDownBase.instances[this.props.id];
if (DropDownBase.currentVisible[0] == this)
DropDownBase.currentVisible = null;
- },
- getInitialState: function()
- {
- return { visible: false, top: 0, left: 0, calloutLeft: null, selectedItem: -1 };
- },
- onClick: function(ev)
+ }
+
+ onClick = (ev) =>
{
ev.stopPropagation();
- },
- isVisible: function()
+ }
+
+ isVisible = () =>
{
return this.state.visible;
- },
- hide: function()
+ }
+
+ hide = () =>
{
this.setState({ visible: false });
DropDownBase.currentVisible = null;
@@ -76,8 +56,9 @@ var DropDownBase = module.exports = {
this.onClose();
delete this.onClose;
}
- },
- showAt: function(el, onClose)
+ }
+
+ showAt = (el, onClose) =>
{
if (this.onClose && this.onClose != onClose)
{
@@ -108,4 +89,32 @@ var DropDownBase = module.exports = {
this.refs.dd.focus();
this.onClose = onClose;
}
-};
+}
+
+function getOffset(elem)
+{
+ if (elem.getBoundingClientRect)
+ {
+ var box = elem.getBoundingClientRect();
+ var body = document.body;
+ var docElem = document.documentElement;
+ var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop;
+ var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft;
+ var clientTop = docElem.clientTop || body.clientTop || 0;
+ var clientLeft = docElem.clientLeft || body.clientLeft || 0;
+ var top = box.top + scrollTop - clientTop;
+ var left = box.left + scrollLeft - clientLeft;
+ return { top: Math.round(top), left: Math.round(left) };
+ }
+ else
+ {
+ var top = 0, left = 0;
+ while(elem)
+ {
+ top = top + parseInt(elem.offsetTop);
+ left = left + parseInt(elem.offsetLeft);
+ elem = elem.offsetParent;
+ }
+ return { top: top, left: left };
+ }
+}
diff --git a/DropDownButton.js b/DropDownButton.js
index 4570bde..6dff8b9 100644
--- a/DropDownButton.js
+++ b/DropDownButton.js
@@ -1,16 +1,21 @@
-const React = require('react');
-const DropDownBase = require('./DropDownBase.js');
+import React from 'react';
-var DropDownButton = module.exports = React.createClass({
- componentDidUpdate: function(prevProps, prevState)
+import DropDownBase from './DropDownBase.js';
+
+export default class DropDownButton extends React.PureComponent
+{
+ state = { pressed: false, checked: false }
+
+ componentDidUpdate(prevProps, prevState)
{
if (prevProps.hidden && !this.props.hidden &&
DropDownBase.instances[this.props.dropdownId].isVisible())
{
DropDownBase.instances[this.props.dropdownId].showAt(this.refs.btn, this.unpress);
}
- },
- render: function()
+ }
+
+ render()
{
return
: null}
- },
- getInitialState: function()
- {
- return { pressed: false, checked: false };
- },
- toggle: function()
+ }
+
+ toggle = () =>
{
if (!this.state.pressed)
{
@@ -35,12 +37,14 @@ var DropDownButton = module.exports = React.createClass({
else
DropDownBase.instances[this.props.dropdownId].hide();
this.setState({ pressed: !this.state.pressed });
- },
- unpress: function()
+ }
+
+ unpress = () =>
{
this.setState({ pressed: false });
- },
- onClickButton: function(ev)
+ }
+
+ onClickButton = (ev) =>
{
if (this.props.whole || this.props.checkable && this.state.pressed)
this.toggle();
@@ -53,10 +57,11 @@ var DropDownButton = module.exports = React.createClass({
else if (this.props.onClick)
this.props.onClick();
ev.stopPropagation();
- },
- onClickDown: function(ev)
+ }
+
+ onClickDown = (ev) =>
{
this.toggle();
ev.stopPropagation();
}
-});
+}
diff --git a/DropDownMenu.js b/DropDownMenu.js
index e063b26..3018646 100644
--- a/DropDownMenu.js
+++ b/DropDownMenu.js
@@ -1,13 +1,12 @@
-const React = require('react');
-const DropDownBase = require('./DropDownBase.js');
+import React from 'react';
-var DropDownMenu = module.exports = React.createClass({
- mixins: [ DropDownBase ],
- getInitialState: function()
- {
- return { items: this.props.items };
- },
- render: function()
+import DropDownBase from './DropDownBase.js';
+
+export default class DropDownMenu extends DropDownBase
+{
+ state = { items: this.props.items }
+
+ render()
{
var sel = this.state.selectedItem;
return
- },
- onMouseOver: function(ev)
+ }
+
+ onMouseOver = (ev) =>
{
var t = ev.target;
while ((t && t != this.refs.dd) && (!t.className || t.className.substr(0, 4) != 'item'))
t = t.parentNode;
if (t && t != this.refs.dd)
this.setState({ selectedItem: parseInt(t.getAttribute('data-index')) });
- },
- onKeyDown: function(ev)
+ }
+
+ onKeyDown = (ev) =>
{
if (ev.keyCode == 40 || ev.keyCode == 38)
{
@@ -50,14 +51,16 @@ var DropDownMenu = module.exports = React.createClass({
this.clickItem();
ev.preventDefault();
ev.stopPropagation();
- },
- clickItem: function(ev)
+ }
+
+ clickItem = (ev) =>
{
- },
- myOnClick: function(ev)
+ }
+
+ myOnClick = (ev) =>
{
if (ev.target.getAttribute('data-index'))
this.clickItem();
this.onClick(ev);
}
-});
+}
diff --git a/FolderList.js b/FolderList.js
index 2a2280f..c7f05f8 100644
--- a/FolderList.js
+++ b/FolderList.js
@@ -1,15 +1,18 @@
-const React = require('react');
-const AccountFolders = require('./AccountFolders.js');
-const DropDownButton = require('./DropDownButton.js');
-const Store = require('./Store.js');
-const StoreListener = require('./StoreListenerClass.js');
-const MailProgress = require('./MailProgress.js');
+import React from 'react';
+import AccountFolders from './AccountFolders.js';
+import DropDownButton from './DropDownButton.js';
+import Store from './Store.js';
+import StoreListener from './StoreListener.js';
+import MailProgress from './MailProgress.js';
-var FolderList = React.createClass({
- render: function()
+class FolderList extends React.PureComponent
+{
+ state = { selectedAccount: -1, selectedFolder: -1 }
+
+ render()
{
var self = this;
- return
+ return (
@@ -24,13 +27,15 @@ var FolderList = React.createClass({
})}
-
- },
- onClickCheckSend: function()
+
)
+ }
+
+ onClickCheckSend = () =>
{
Store.startResync();
- },
- onSelectFolder: function(accIndex, folderIndex)
+ }
+
+ onSelectFolder = (accIndex, folderIndex) =>
{
var acc = this.props.accounts[accIndex];
var folder = this.props.accounts[accIndex].folders[folderIndex];
@@ -42,11 +47,7 @@ var FolderList = React.createClass({
Store.loadFolder({ accountId: acc.accountId, folderType: folder.type });
}
this.setState({ selectedAccount: accIndex, selectedFolder: folderIndex });
- },
- getInitialState: function()
- {
- return { selectedAccount: -1, selectedFolder: -1 };
}
-});
+}
-module.exports = StoreListener(FolderList, (data) => { return { accounts: data.accounts, progressText: data.progressText }; });
+export default StoreListener(FolderList, (data) => { return { accounts: data.accounts, progressText: data.progressText }; });
diff --git a/I18n.js b/I18n.js
index c51757e..8561c14 100644
--- a/I18n.js
+++ b/I18n.js
@@ -1,4 +1,4 @@
-module.exports = function(msg)
+export default function(msg)
{
return msg;
}
diff --git a/ListSortSettings.js b/ListSortSettings.js
index f356d58..0f497ff 100644
--- a/ListSortSettings.js
+++ b/ListSortSettings.js
@@ -1,7 +1,8 @@
-const React = require('react');
+import React from 'react';
-var ListSortSettings = module.exports = React.createClass({
- render: function()
+export default class ListSortSettings extends React.PureComponent
+{
+ render()
{
return
}
-});
+}
diff --git a/ListSortSettingsWindow.js b/ListSortSettingsWindow.js
index 393bdf5..d645277 100644
--- a/ListSortSettingsWindow.js
+++ b/ListSortSettingsWindow.js
@@ -1,10 +1,13 @@
-const React = require('react');
-const DropDownBase = require('./DropDownBase.js');
-const ListSortSettings = require('./ListSortSettings.js');
+import React from 'react';
-var ListSortSettingsWindow = module.exports = React.createClass({
- mixins: [ DropDownBase ],
- render: function()
+import DropDownBase from './DropDownBase.js';
+import ListSortSettings from './ListSortSettings.js';
+
+export default class ListSortSettingsWindow extends DropDownBase
+{
+ state = { checksVisible: false }
+
+ render()
{
var sort = this.props.override ? this.props.sorting : this.props.defaultSorting;
return
Show Duplicates
- },
- getInitialState: function()
- {
- return { checksVisible: false };
- },
- expandChecks: function()
+ }
+
+ expandChecks = () =>
{
this.setState({ checksVisible: !this.state.checksVisible });
}
-});
+}
diff --git a/ListWithSelection.js b/ListWithSelection.js
index a02aaf8..3f49bb9 100644
--- a/ListWithSelection.js
+++ b/ListWithSelection.js
@@ -1,18 +1,24 @@
-// Common selection mixin
-var ListWithSelection = module.exports = {
+import React from 'react';
+
+// Common "list with selection" component
+
+export default class ListWithSelection extends React.PureComponent
+{
// requires to override methods: this.deleteSelected(), this.getPageSize(), this.getItemOffset(index), this.getTotalItems()
- getInitialState: function()
+ constructor(props)
{
- return {
- selected: {}
- };
- },
- isSelected: function(i)
+ super(props);
+ this.state = this.state||{};
+ this.state.selected = {};
+ }
+
+ isSelected(i)
{
return this.state.selected[i] || this.state.selected.begin !== undefined &&
this.state.selected.begin <= i && this.state.selected.end >= i;
- },
- onListKeyDown: function(ev)
+ }
+
+ onListKeyDown = (ev) =>
{
if (!this.getTotalItems())
return;
@@ -74,8 +80,9 @@ var ListWithSelection = module.exports = {
else
this.selectOne(nsel);
}
- },
- selectTo: function(ns)
+ }
+
+ selectTo(ns)
{
if (this.lastSel === undefined)
return this.selectOne(ns);
@@ -93,8 +100,9 @@ var ListWithSelection = module.exports = {
this.curSel = ns;
if (this.onSelectCurrent)
this.onSelectCurrent(ns);
- },
- selectOne: function(ns)
+ }
+
+ selectOne(ns)
{
var sel = {};
sel[ns] = true;
@@ -103,8 +111,9 @@ var ListWithSelection = module.exports = {
this.curSel = ns;
if (this.onSelectCurrent)
this.onSelectCurrent(ns);
- },
- onListItemClick: function(ev)
+ }
+
+ onListItemClick = (ev) =>
{
var t = ev.target;
while (t && !t.getAttribute('data-i'))
@@ -127,4 +136,4 @@ var ListWithSelection = module.exports = {
this.selectOne(ns);
}
}
-};
+}
diff --git a/MailProgress.js b/MailProgress.js
index 4c6c3fc..6c44811 100644
--- a/MailProgress.js
+++ b/MailProgress.js
@@ -1,7 +1,7 @@
-const StoreListener = require('./StoreListenerClass.js');
-const ProgressBar = require('./ProgressBar.js');
+import StoreListener from './StoreListener.js';
+import ProgressBar from './ProgressBar.js';
-module.exports = StoreListener(ProgressBar, function(data)
+export default StoreListener(ProgressBar, function(data)
{
return { text: data.progressText, progress: data.progressPercent };
});
diff --git a/MailSettingsWindow.js b/MailSettingsWindow.js
index d4e18f6..64c9cf0 100644
--- a/MailSettingsWindow.js
+++ b/MailSettingsWindow.js
@@ -1,12 +1,12 @@
-const React = require('react');
-const DropDownBase = require('./DropDownBase.js');
-const ListSortSettings = require('./ListSortSettings.js');
-const Store = require('./Store.js');
-const StoreListener = require('./StoreListener.js');
+import React from 'react';
+import DropDownBase from './DropDownBase.js';
+import ListSortSettings from './ListSortSettings.js';
+import Store from './Store.js';
+import StoreListener from './StoreListener.js';
-var MailSettingsWindow = React.createClass({
- mixins: [ DropDownBase ],
- render: function()
+class MailSettingsWindow extends DropDownBase
+{
+ render()
{
return
@@ -35,20 +35,22 @@ var MailSettingsWindow = React.createClass({
- },
- switchLayout: function(ev)
+ }
+
+ switchLayout = (ev) =>
{
var t = ev.target.nodeName == 'A' ? ev.target : ev.target.parentNode;
var l = / mail-(\S+)/.exec(t.className)[1];
Store.set('layout', l);
- },
- showQuickReply: function()
+ }
+
+ showQuickReply = () =>
{
Store.set('quickReply', !this.props.quickReply);
}
-});
+}
-module.exports = StoreListener(
+export default StoreListener(
MailSettingsWindow,
(data) => { return { layout: data.layout, quickReply: data.quickReply }; },
{
diff --git a/MessageList.js b/MessageList.js
index 5b472f1..33cfd47 100644
--- a/MessageList.js
+++ b/MessageList.js
@@ -1,13 +1,15 @@
-const React = require('react');
-const DropDownButton = require('./DropDownButton.js');
-const ListWithSelection = require('./ListWithSelection.js');
-const Store = require('./Store.js');
-const StoreListener = require('./StoreListener.js');
-const Util = require('./Util.js');
+import React from 'react';
+import DropDownButton from './DropDownButton.js';
+import ListWithSelection from './ListWithSelection.js';
+import Store from './Store.js';
+import StoreListener from './StoreListener.js';
+import Util from './Util.js';
-var MessageInList = React.createClass({
- msgClasses: { unread: 'unread', unseen: 'unseen', answered: 'replied', flagged: 'pinned', sent: 'sent' },
- render: function()
+class MessageInList extends React.PureComponent
+{
+ msgClasses = { unread: 'unread', unseen: 'unseen', answered: 'replied', flagged: 'pinned', sent: 'sent' }
+
+ render()
{
var msg = this.props.msg;
return
}
-});
+}
// TODO: expand/collapse days
-var MessageList = React.createClass({
- mixins: [ ListWithSelection ],
- _preloadSize: 20,
- _pageSize: 50,
- getInitialState: function()
- {
- return {
- firstDayTop: 0,
- firstDay: this.props.groups && this.props.groups[0] && this.props.groups[0].name || null
- };
- },
- componentWillReceiveProps: function(nextProps)
+class MessageList extends ListWithSelection
+{
+ _preloadSize = 20
+ _pageSize = 50
+ state = {
+ ...this.state,
+ firstDayTop: 0,
+ firstDay: this.props.groups && this.props.groups[0] && this.props.groups[0].name || null
+ }
+
+ componentWillReceiveProps(nextProps)
{
this.setFirstDayFromProps(nextProps);
- },
+ }
+
// Main virtual scroll detector method
- setFirstDayFromProps: function(props)
+ setFirstDayFromProps(props)
{
var groups = props.groups;
var messages = props.messages;
@@ -118,16 +120,19 @@ var MessageList = React.createClass({
Store.loadMessages(loadFirst, loadFirstEnd-loadFirst);
if (loadFirstEnd < loadLastStart && loadLastStart < loadLast)
Store.loadMessages(loadLastStart, loadLast-loadLastStart);
- },
- changeFirstDay: function(ev)
+ }
+
+ changeFirstDay = (ev) =>
{
this.setFirstDayFromProps(this.props);
- },
- deleteSelected: function()
+ }
+
+ deleteSelected = () =>
{
- },
- onSelectCurrent: function(index)
+ }
+
+ onSelectCurrent = (index) =>
{
var self = this;
var total = 0, p, msg, idx;
@@ -155,8 +160,9 @@ var MessageList = React.createClass({
break;
}
}
- },
- getTotalItems: function()
+ }
+
+ getTotalItems = () =>
{
var total = -1; // do not count first-day as item
for (var i = 0; i < (this.props.groups||[]).length; i++)
@@ -164,12 +170,14 @@ var MessageList = React.createClass({
total += 1+this.props.groups[i].messageCount;
}
return total;
- },
- getPageSize: function()
+ }
+
+ getPageSize = () =>
{
return Math.floor(this.refs.scroll.offsetHeight / (this.props.layout == 'message-on-right' ? 60 : 30));
- },
- getItemOffset: function(index)
+ }
+
+ getItemOffset = (index) =>
{
var n = 0, top = 0, p;
var h = (this.props.layout == 'message-on-right' ? 60 : 30);
@@ -185,28 +193,32 @@ var MessageList = React.createClass({
top += (i > 0 ? 30 : 0) + h*this.props.groups[i].messageCount;
}
return [ top, index == p && i > 0 ? 30 : h ];
- },
- getScrollPaddingTop: function()
+ }
+
+ getScrollPaddingTop = () =>
{
return this.refs.title.offsetHeight;
- },
- getMessages: function(grp, start, end)
+ }
+
+ getMessages = (grp, start, end) =>
{
var a = this.props.messages.slice(grp.start+start, grp.start+end);
for (var i = 0; i < end-start; i++)
if (!a[i])
a[i] = null;
return a;
- },
- onSearchTextChange: function(event)
+ }
+
+ onSearchTextChange = (event) =>
{
var s = event.target.value;
this.setState({ searchText: s });
if (this._searchTimeout)
clearTimeout(this._searchTimeout);
this._searchTimeout = setTimeout(function() { Store.search(s) }, 300);
- },
- render: function()
+ }
+
+ render()
{
var self = this;
var total = 0;
@@ -270,18 +282,20 @@ var MessageList = React.createClass({
})}