aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/services/tabs
diff options
context:
space:
mode:
authorLibravatar Stefan Malzner <stefan@adlk.io>2017-10-13 12:29:40 +0200
committerLibravatar Stefan Malzner <stefan@adlk.io>2017-10-13 12:29:40 +0200
commit58cda9cc7fb79ca9df6746de7f9662bc08dc156a (patch)
tree1211600c2a5d3b5f81c435c6896618111a611720 /src/components/services/tabs
downloadferdium-app-58cda9cc7fb79ca9df6746de7f9662bc08dc156a.tar.gz
ferdium-app-58cda9cc7fb79ca9df6746de7f9662bc08dc156a.tar.zst
ferdium-app-58cda9cc7fb79ca9df6746de7f9662bc08dc156a.zip
initial commit
Diffstat (limited to 'src/components/services/tabs')
-rw-r--r--src/components/services/tabs/TabBarSortableList.js44
-rw-r--r--src/components/services/tabs/TabItem.js136
-rw-r--r--src/components/services/tabs/Tabbar.js77
3 files changed, 257 insertions, 0 deletions
diff --git a/src/components/services/tabs/TabBarSortableList.js b/src/components/services/tabs/TabBarSortableList.js
new file mode 100644
index 000000000..c0a68d1a5
--- /dev/null
+++ b/src/components/services/tabs/TabBarSortableList.js
@@ -0,0 +1,44 @@
1import React from 'react';
2import { observer } from 'mobx-react';
3import { SortableContainer } from 'react-sortable-hoc';
4
5import TabItem from './TabItem';
6import { ctrlKey } from '../../../environment';
7
8export default SortableContainer(observer(({
9 services,
10 setActive,
11 reload,
12 toggleNotifications,
13 deleteService,
14 disableService,
15 openSettings,
16}) => (
17 <ul
18 className="tabs"
19 >
20 {services.map((service, index) => (
21 <TabItem
22 key={service.id}
23 clickHandler={() => setActive({ serviceId: service.id })}
24 service={service}
25 index={index}
26 shortcutIndex={index + 1}
27 reload={() => reload({ serviceId: service.id })}
28 toggleNotifications={() => toggleNotifications({ serviceId: service.id })}
29 deleteService={() => deleteService({ serviceId: service.id })}
30 disableService={() => disableService({ serviceId: service.id })}
31 openSettings={openSettings}
32 />
33 ))}
34 <li>
35 <button
36 className="sidebar__add-service"
37 onClick={() => openSettings({ path: 'recipes' })}
38 data-tip={`Add new service (${ctrlKey}+N)`}
39 >
40 <span className="mdi mdi-plus" />
41 </button>
42 </li>
43 </ul>
44)));
diff --git a/src/components/services/tabs/TabItem.js b/src/components/services/tabs/TabItem.js
new file mode 100644
index 000000000..9e03d2e21
--- /dev/null
+++ b/src/components/services/tabs/TabItem.js
@@ -0,0 +1,136 @@
1import { remote } from 'electron';
2import React, { Component } from 'react';
3import { defineMessages, intlShape } from 'react-intl';
4import PropTypes from 'prop-types';
5import { observer } from 'mobx-react';
6import classnames from 'classnames';
7import { SortableElement } from 'react-sortable-hoc';
8
9import ServiceModel from '../../../models/Service';
10import { ctrlKey } from '../../../environment';
11
12const { Menu } = remote;
13
14const messages = defineMessages({
15 reload: {
16 id: 'tabs.item.reload',
17 defaultMessage: '!!!Reload',
18 },
19 edit: {
20 id: 'tabs.item.edit',
21 defaultMessage: '!!!Edit',
22 },
23 disableNotifications: {
24 id: 'tabs.item.disableNotifications',
25 defaultMessage: '!!!Disable notifications',
26 },
27 enableNotifications: {
28 id: 'tabs.item.enableNotification',
29 defaultMessage: '!!!Enable notifications',
30 },
31 disableService: {
32 id: 'tabs.item.disableService',
33 defaultMessage: '!!!Disable Service',
34 },
35 deleteService: {
36 id: 'tabs.item.deleteService',
37 defaultMessage: '!!!Delete Service',
38 },
39});
40
41@observer
42class TabItem extends Component {
43 static propTypes = {
44 service: PropTypes.instanceOf(ServiceModel).isRequired,
45 clickHandler: PropTypes.func.isRequired,
46 shortcutIndex: PropTypes.number.isRequired,
47 reload: PropTypes.func.isRequired,
48 toggleNotifications: PropTypes.func.isRequired,
49 openSettings: PropTypes.func.isRequired,
50 deleteService: PropTypes.func.isRequired,
51 disableService: PropTypes.func.isRequired,
52 };
53
54 static contextTypes = {
55 intl: intlShape,
56 };
57
58 render() {
59 const {
60 service,
61 clickHandler,
62 shortcutIndex,
63 reload,
64 toggleNotifications,
65 deleteService,
66 disableService,
67 openSettings,
68 } = this.props;
69 const { intl } = this.context;
70
71
72 const menuTemplate = [{
73 label: service.name || service.recipe.name,
74 enabled: false,
75 }, {
76 type: 'separator',
77 }, {
78 label: intl.formatMessage(messages.reload),
79 click: reload,
80 }, {
81 label: intl.formatMessage(messages.edit),
82 click: () => openSettings({
83 path: `services/edit/${service.id}`,
84 }),
85 }, {
86 type: 'separator',
87 }, {
88 label: service.isNotificationEnabled
89 ? intl.formatMessage(messages.disableNotifications)
90 : intl.formatMessage(messages.enableNotifications),
91 click: () => toggleNotifications(),
92 }, {
93 label: intl.formatMessage(messages.disableService),
94 click: () => disableService(),
95 }, {
96 type: 'separator',
97 }, {
98 label: intl.formatMessage(messages.deleteService),
99 click: () => deleteService(),
100 }];
101 const menu = Menu.buildFromTemplate(menuTemplate);
102
103 return (
104 <li
105 className={classnames({
106 'tab-item': true,
107 'is-active': service.isActive,
108 'has-custom-icon': service.hasCustomIcon,
109 })}
110 onClick={clickHandler}
111 onContextMenu={() => menu.popup(remote.getCurrentWindow())}
112 data-tip={`${service.name} ${shortcutIndex <= 9 ? `(${ctrlKey}+${shortcutIndex})` : ''}`}
113 >
114 <img
115 src={service.icon}
116 className="tab-item__icon"
117 alt=""
118 />
119 {service.unreadDirectMessageCount > 0 && (
120 <span className="tab-item__message-count">
121 {service.unreadDirectMessageCount}
122 </span>
123 )}
124 {service.unreadIndirectMessageCount > 0
125 && service.unreadDirectMessageCount === 0
126 && service.isIndirectMessageBadgeEnabled && (
127 <span className="tab-item__message-count is-indirect">
128
129 </span>
130 )}
131 </li>
132 );
133 }
134}
135
136export default SortableElement(TabItem);
diff --git a/src/components/services/tabs/Tabbar.js b/src/components/services/tabs/Tabbar.js
new file mode 100644
index 000000000..fdb2c0a59
--- /dev/null
+++ b/src/components/services/tabs/Tabbar.js
@@ -0,0 +1,77 @@
1import React, { Component } from 'react';
2import PropTypes from 'prop-types';
3import { observer, PropTypes as MobxPropTypes } from 'mobx-react';
4
5import TabBarSortableList from './TabBarSortableList';
6
7@observer
8export default class TabBar extends Component {
9 static propTypes = {
10 services: MobxPropTypes.arrayOrObservableArray.isRequired,
11 setActive: PropTypes.func.isRequired,
12 openSettings: PropTypes.func.isRequired,
13 enableToolTip: PropTypes.func.isRequired,
14 disableToolTip: PropTypes.func.isRequired,
15 reorder: PropTypes.func.isRequired,
16 reload: PropTypes.func.isRequired,
17 toggleNotifications: PropTypes.func.isRequired,
18 deleteService: PropTypes.func.isRequired,
19 updateService: PropTypes.func.isRequired,
20 }
21
22 onSortEnd = ({ oldIndex, newIndex }) => {
23 const {
24 enableToolTip,
25 reorder,
26 } = this.props;
27
28 enableToolTip();
29 reorder({ oldIndex, newIndex });
30 };
31
32 disableService = ({ serviceId }) => {
33 const { updateService } = this.props;
34
35 if (serviceId) {
36 updateService({
37 serviceId,
38 serviceData: {
39 isEnabled: false,
40 },
41 redirect: false,
42 });
43 }
44 }
45
46 render() {
47 const {
48 services,
49 setActive,
50 openSettings,
51 disableToolTip,
52 reload,
53 toggleNotifications,
54 deleteService,
55 } = this.props;
56
57 return (
58 <div>
59 <TabBarSortableList
60 services={services}
61 setActive={setActive}
62 onSortEnd={this.onSortEnd}
63 onSortStart={disableToolTip}
64 reload={reload}
65 toggleNotifications={toggleNotifications}
66 deleteService={deleteService}
67 disableService={this.disableService}
68 openSettings={openSettings}
69 distance={20}
70 axis="y"
71 lockAxis="y"
72 helperClass="is-reordering"
73 />
74 </div>
75 );
76 }
77}