poi-plugin-milk 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.idea/jsLibraryMappings.xml +6 -0
- package/.idea/misc.xml +81 -0
- package/.idea/modules.xml +8 -0
- package/.idea/poi-plugin-anchorage-repair.iml +12 -0
- package/.idea/workspace.xml +397 -0
- package/C/357/200/272UsersAdministratorAppDataRoamingpoipluginsnode_modulespoi-plugin-anchorage-repair +226 -0
- package/C/357/200/272UsersAdministratorAppDataRoamingpoipluginsnode_modulespoi-plugin-anchorage-repairindex2.js +226 -0
- package/LICENSE +21 -0
- package/README-CN.MD +53 -0
- package/README.MD +66 -0
- package/assets/style.css +55 -0
- package/i18n/en-US.json +1 -0
- package/i18n/ja-JP.json +24 -0
- package/i18n/ko-KR.json +12 -0
- package/i18n/zh-CN.json +24 -0
- package/i18n/zh-TW.json +24 -0
- package/index.js +234 -0
- package/index.js.map +1 -0
- package/package.json +43 -0
- package/parts/candidates.js +169 -0
- package/parts/candidates.js.map +1 -0
- package/parts/countup-timer.js +122 -0
- package/parts/countup-timer.js.map +1 -0
- package/parts/factor.js +32 -0
- package/parts/factor.js.map +1 -0
- package/parts/fleet-list.js +324 -0
- package/parts/fleet-list.js.map +1 -0
- package/parts/functions.js +90 -0
- package/parts/functions.js.map +1 -0
- package/parts/ship-row.js +141 -0
- package/parts/ship-row.js.map +1 -0
package/i18n/zh-CN.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Anchorage repair": "泊地修理",
|
|
3
|
+
"Akashi not flagship": "明石不是旗舰/野崎不是旗舰二舰",
|
|
4
|
+
"Not ready": "未就绪",
|
|
5
|
+
"Capacity: %s": "可修理数量: %s",
|
|
6
|
+
"Please return to HQ screen to make timer refreshed.": "请回到母港画面以重置计时器。",
|
|
7
|
+
"Ship": "舰娘",
|
|
8
|
+
"HP": "耐久",
|
|
9
|
+
"Akashi Time": "明石修理时间",
|
|
10
|
+
"Per HP": "单位修理时间",
|
|
11
|
+
"Estimated repaired": "预计已回复",
|
|
12
|
+
"fleet in expedition": "舰队远征中",
|
|
13
|
+
"Elapsed:": "计时器:",
|
|
14
|
+
"Repairing": "正在修理",
|
|
15
|
+
"Akashi loves you!": "明石爱你哦!",
|
|
16
|
+
"flagship in dock": "旗舰入渠中",
|
|
17
|
+
"anchorage repair completed": "泊地修理完毕",
|
|
18
|
+
"A plugin to help in Akashi's anchorage repair arrangement": "明石泊地修理助手",
|
|
19
|
+
"Docking": "入渠中",
|
|
20
|
+
"Total time required": "泊地修理总耗时",
|
|
21
|
+
"Time required for 1 HP recovery": "每回复一点耐久所用泊地修理时间",
|
|
22
|
+
"Estimated HP recovery since last refresh": "从上次刷新之后的预计耐久回复量",
|
|
23
|
+
"Candidates": "适格者"
|
|
24
|
+
}
|
package/i18n/zh-TW.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Anchorage repair": "泊地修理",
|
|
3
|
+
"Akashi not flagship": "明石不是旗艦",
|
|
4
|
+
"Not ready": "未就緒",
|
|
5
|
+
"Capacity: %s": "可修理數量: %s",
|
|
6
|
+
"Please return to HQ screen to make timer refreshed.": "請回到母港畫面以重置計時器。",
|
|
7
|
+
"Ship": "艦娘",
|
|
8
|
+
"HP": "耐久",
|
|
9
|
+
"Akashi Time": "明石修理時間",
|
|
10
|
+
"Per HP": "單位修理時間",
|
|
11
|
+
"Estimated repaired": "預計已回復",
|
|
12
|
+
"fleet in expedition": "艦隊遠征中",
|
|
13
|
+
"Elapsed:": "計時器:",
|
|
14
|
+
"Repairing": "正在修理",
|
|
15
|
+
"Akashi loves you!": "明石愛你哦!",
|
|
16
|
+
"flagship in dock": "旗艦入渠中",
|
|
17
|
+
"anchorage repair completed": "泊地修理完畢",
|
|
18
|
+
"A plugin to help in Akashi's anchorage repair arrangement": "明石泊地修理助手",
|
|
19
|
+
"Docking": "入渠中",
|
|
20
|
+
"Total time required": "泊地修理總耗時",
|
|
21
|
+
"Time required for 1 HP recovery": "每回復一點耐久所用泊地修理時間",
|
|
22
|
+
"Estimated HP recovery since last refresh": "從上次刷新之後的預計耐久回復量",
|
|
23
|
+
"Candidates": "適格者"
|
|
24
|
+
}
|
package/index.js
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.switchPluginPath = exports.reactClass = undefined;
|
|
7
|
+
|
|
8
|
+
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
|
9
|
+
|
|
10
|
+
// Import selectors defined in poi
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
var _react = require('react');
|
|
14
|
+
|
|
15
|
+
var _react2 = _interopRequireDefault(_react);
|
|
16
|
+
|
|
17
|
+
var _reactRedux = require('react-redux');
|
|
18
|
+
|
|
19
|
+
var _reselect = require('reselect');
|
|
20
|
+
|
|
21
|
+
var _lodash = require('lodash');
|
|
22
|
+
|
|
23
|
+
var _lodash2 = _interopRequireDefault(_lodash);
|
|
24
|
+
|
|
25
|
+
var _path = require('path');
|
|
26
|
+
|
|
27
|
+
var _reactBootstrap = require('react-bootstrap');
|
|
28
|
+
|
|
29
|
+
var _selectors = require('views/utils/selectors');
|
|
30
|
+
|
|
31
|
+
var _functions = require('./parts/functions');
|
|
32
|
+
|
|
33
|
+
var _fleetList = require('./parts/fleet-list');
|
|
34
|
+
|
|
35
|
+
var _fleetList2 = _interopRequireDefault(_fleetList);
|
|
36
|
+
|
|
37
|
+
var _candidates = require('./parts/candidates');
|
|
38
|
+
|
|
39
|
+
var _candidates2 = _interopRequireDefault(_candidates);
|
|
40
|
+
|
|
41
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
42
|
+
|
|
43
|
+
const { i18n, getStore } = window;
|
|
44
|
+
const __ = i18n['poi-plugin-anchorage-repair'].__.bind(i18n['poi-plugin-anchorage-repair']);
|
|
45
|
+
|
|
46
|
+
const AKASHI_ID = [182, 187]; // akashi and kai ID in $ships
|
|
47
|
+
const SRF_ID = 86; // Ship Repair Facility ID in $slotitems
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
// check a fleet status, returns information related to anchorage repair
|
|
51
|
+
const fleetAkashiConv = (fleet, $ships, ships, equips, repairId) => {
|
|
52
|
+
const pickKey = ['api_id', 'api_ship_id', 'api_lv', 'api_nowhp', 'api_maxhp', 'api_ndock_time','api_cond'];
|
|
53
|
+
|
|
54
|
+
let canRepair = false;
|
|
55
|
+
let akashiFlagship = false;
|
|
56
|
+
let repairCount = 0;
|
|
57
|
+
const inExpedition = _lodash2.default.get(fleet, 'api_mission.0') && true;
|
|
58
|
+
const flagShipInRepair = _lodash2.default.includes(repairId, _lodash2.default.get(fleet, 'api_ship.0', -1));
|
|
59
|
+
const flagship = ships[_lodash2.default.get(fleet, 'api_ship.0', -1)];
|
|
60
|
+
|
|
61
|
+
if (flagship != null) {
|
|
62
|
+
akashiFlagship = _lodash2.default.includes(AKASHI_ID, flagship.api_ship_id);
|
|
63
|
+
repairCount = _lodash2.default.filter(flagship.api_slot, item => _lodash2.default.get(equips, `${item}.api_slotitem_id`, -1) === SRF_ID).length;
|
|
64
|
+
repairCount += akashiFlagship ? 2 : 0;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
canRepair = akashiFlagship && !inExpedition && !flagShipInRepair;
|
|
68
|
+
|
|
69
|
+
const repairDetail = _lodash2.default.map(_lodash2.default.filter(fleet.api_ship, shipId => shipId > 0), (shipId, index) => {
|
|
70
|
+
if (shipId === -1) return false; // break, LODASH ONLY
|
|
71
|
+
|
|
72
|
+
const ship = _lodash2.default.pick(ships[shipId], pickKey);
|
|
73
|
+
|
|
74
|
+
const constShip = _lodash2.default.pick($ships[ship.api_ship_id], ['api_name', 'api_stype']);
|
|
75
|
+
|
|
76
|
+
return _extends({}, ship, constShip, {
|
|
77
|
+
cond:ship.api_cond,
|
|
78
|
+
estimate: (0, _functions.akashiEstimate)(ship),
|
|
79
|
+
timePerHP: (0, _functions.getTimePerHP)(ship.api_lv, constShip.api_stype),
|
|
80
|
+
inRepair: _lodash2.default.includes(repairId, ship.api_id),
|
|
81
|
+
availableSRF: index < repairCount
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
var repairStatus = 0
|
|
86
|
+
if(canRepair){
|
|
87
|
+
repairStatus = 1;
|
|
88
|
+
}else{
|
|
89
|
+
var flagshipa = _lodash2.default.get(fleet, 'api_ship.0', -1)
|
|
90
|
+
var secondshipa = _lodash2.default.get(fleet, 'api_ship.1', -1)
|
|
91
|
+
var flagshipid = ships[flagshipa]?ships[flagshipa].api_ship_id:-1;
|
|
92
|
+
var secondshipid = ships[secondshipa]?ships[secondshipa].api_ship_id:-1;
|
|
93
|
+
|
|
94
|
+
if(flagshipid==996||flagshipid==1002||secondshipid==996||secondshipid==1002
|
|
95
|
+
//||flagshipid==357||secondshipid==357 //没有野崎,用初月改测试
|
|
96
|
+
){
|
|
97
|
+
repairStatus = 2;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
//console.log("cc:"+flagshipid)
|
|
101
|
+
canRepair = repairStatus;
|
|
102
|
+
//console.log("cc2:"+secondshipid)
|
|
103
|
+
return {
|
|
104
|
+
api_id: fleet.api_id || -1,
|
|
105
|
+
shipId: fleet.api_ship || [],
|
|
106
|
+
canRepair,
|
|
107
|
+
akashiFlagship,
|
|
108
|
+
inExpedition,
|
|
109
|
+
flagShipInRepair,
|
|
110
|
+
repairCount,
|
|
111
|
+
repairDetail
|
|
112
|
+
};
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
// selectors
|
|
116
|
+
|
|
117
|
+
const repairIdSelector = (0, _reselect.createSelector)([_selectors.repairsSelector], repair => _lodash2.default.map(repair, dock => dock.api_ship_id));
|
|
118
|
+
|
|
119
|
+
const constShipsSelector = state => state.const.$ships || {};
|
|
120
|
+
|
|
121
|
+
const fleetsAkashiSelector = (0, _reselect.createSelector)([constShipsSelector, _selectors.fleetsSelector, _selectors.shipsSelector, _selectors.equipsSelector, repairIdSelector], ($ships, fleets, ships, equips, repairId) => ({ fleets: _lodash2.default.map(fleets, fleet => fleetAkashiConv(fleet, $ships, ships, equips, repairId)) })
|
|
122
|
+
|
|
123
|
+
// React
|
|
124
|
+
|
|
125
|
+
);const reactClass = exports.reactClass = (0, _reactRedux.connect)((0, _selectors.createDeepCompareArraySelector)([fleetsAkashiSelector, _selectors.miscSelector], (data, { canNotify }) => _extends({}, data, {
|
|
126
|
+
canNotify
|
|
127
|
+
})))(class PluginAnchorageRepair extends _react.Component {
|
|
128
|
+
|
|
129
|
+
constructor(props) {
|
|
130
|
+
super(props);
|
|
131
|
+
|
|
132
|
+
this.handleSelectTab = key => {
|
|
133
|
+
this.setState({ activeTab: key });
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
this.handleSort = index => () => {
|
|
137
|
+
this.setState({
|
|
138
|
+
sortIndex: index
|
|
139
|
+
});
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
this.state = {
|
|
143
|
+
activeTab: 1,
|
|
144
|
+
sortIndex: 0
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
render() {
|
|
149
|
+
return _react2.default.createElement(
|
|
150
|
+
'div',
|
|
151
|
+
{ id: 'anchorage-repair' },
|
|
152
|
+
_react2.default.createElement('link', { rel: 'stylesheet', href: (0, _path.join)(__dirname, 'assets', 'style.css') }),
|
|
153
|
+
_react2.default.createElement(
|
|
154
|
+
_reactBootstrap.Tabs,
|
|
155
|
+
{ activeKey: this.state.activeTab, onSelect: this.handleSelectTab, id: 'anchorage-tabs' },
|
|
156
|
+
_lodash2.default.map(this.props.fleets, (fleet, index) => _react2.default.createElement(
|
|
157
|
+
_reactBootstrap.Tab,
|
|
158
|
+
{
|
|
159
|
+
eventKey: fleet.api_id,
|
|
160
|
+
title: fleet.api_id,
|
|
161
|
+
key: `anchorage-tab-${index}`,
|
|
162
|
+
tabClassName: fleet.canRepair ? 'can-repair' : ''
|
|
163
|
+
},
|
|
164
|
+
_react2.default.createElement(_fleetList2.default, { fleet: fleet })
|
|
165
|
+
)),
|
|
166
|
+
_react2.default.createElement(
|
|
167
|
+
_reactBootstrap.Tab,
|
|
168
|
+
{
|
|
169
|
+
className: 'candidate-pane',
|
|
170
|
+
eventKey: -1,
|
|
171
|
+
title: __('Candidates')
|
|
172
|
+
},
|
|
173
|
+
_react2.default.createElement(_candidates2.default, { handleSort: this.handleSort, sortIndex: this.state.sortIndex })
|
|
174
|
+
)
|
|
175
|
+
)
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/*
|
|
181
|
+
|
|
182
|
+
The following APIs are called in order when a fleet returns from expedition:
|
|
183
|
+
|
|
184
|
+
- api_req_mission/result
|
|
185
|
+
- api_port/port
|
|
186
|
+
|
|
187
|
+
As anchorage repair pops up conditionally on the latter one,
|
|
188
|
+
it also prevents other plugins' auto-switch mechanism on
|
|
189
|
+
tracking api_req_mission/result calls.
|
|
190
|
+
|
|
191
|
+
The problem is solved by applying a lock upon expedition returns
|
|
192
|
+
and ignoring the immediately followed api_port/port call.
|
|
193
|
+
|
|
194
|
+
*/
|
|
195
|
+
);let expedReturnLock = null;
|
|
196
|
+
const clearExpedReturnLock = () => {
|
|
197
|
+
if (expedReturnLock !== null) {
|
|
198
|
+
clearTimeout(expedReturnLock);
|
|
199
|
+
expedReturnLock = null;
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
const switchPluginPath = exports.switchPluginPath = [{
|
|
204
|
+
path: '/kcsapi/api_port/port',
|
|
205
|
+
valid: () => {
|
|
206
|
+
if (expedReturnLock !== null) {
|
|
207
|
+
/*
|
|
208
|
+
this is the immediately followed api_port/port call
|
|
209
|
+
after an expedition returning event.
|
|
210
|
+
*/
|
|
211
|
+
clearExpedReturnLock();
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const { fleets = [], ships = {}, equips = {}, repairs = [] } = getStore('info') || {};
|
|
216
|
+
const $ships = getStore('const.$ships');
|
|
217
|
+
const repairId = repairs.map(dock => dock.api_ship_id);
|
|
218
|
+
|
|
219
|
+
const result = fleets.map(fleet => fleetAkashiConv(fleet, $ships, ships, equips, repairId));
|
|
220
|
+
return result.some(fleet => fleet.canRepair && fleet.repairDetail.some(ship => ship.estimate > 0));
|
|
221
|
+
}
|
|
222
|
+
}, {
|
|
223
|
+
path: '/kcsapi/api_req_mission/result',
|
|
224
|
+
valid: () => {
|
|
225
|
+
clearExpedReturnLock();
|
|
226
|
+
expedReturnLock = setTimeout(clearExpedReturnLock,
|
|
227
|
+
/*
|
|
228
|
+
allow a window of 5 secnds before the lock
|
|
229
|
+
clears itself
|
|
230
|
+
*/
|
|
231
|
+
5000);
|
|
232
|
+
return false;
|
|
233
|
+
}
|
|
234
|
+
}];
|
package/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["index.es"],"names":["i18n","getStore","window","__","bind","AKASHI_ID","SRF_ID","fleetAkashiConv","fleet","$ships","ships","equips","repairId","pickKey","canRepair","akashiFlagship","repairCount","inExpedition","get","flagShipInRepair","includes","flagship","api_ship_id","filter","api_slot","item","length","repairDetail","map","api_ship","shipId","index","ship","pick","constShip","estimate","timePerHP","api_lv","api_stype","inRepair","api_id","availableSRF","repairIdSelector","repair","dock","constShipsSelector","state","const","fleetsAkashiSelector","fleets","reactClass","data","canNotify","PluginAnchorageRepair","constructor","props","handleSelectTab","key","setState","activeTab","handleSort","sortIndex","render","__dirname","expedReturnLock","clearExpedReturnLock","clearTimeout","switchPluginPath","path","valid","repairs","result","some","setTimeout"],"mappings":"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","file":"index.es","sourcesContent":["import React, { Component } from 'react'\nimport { connect } from 'react-redux'\nimport { createSelector } from 'reselect'\nimport _ from 'lodash'\nimport { join } from 'path'\nimport { Tabs, Tab } from 'react-bootstrap'\n\n// Import selectors defined in poi\nimport {\n fleetsSelector,\n shipsSelector,\n equipsSelector,\n repairsSelector,\n miscSelector,\n createDeepCompareArraySelector,\n} from 'views/utils/selectors'\n\nimport {\n akashiEstimate,\n getTimePerHP,\n} from './parts/functions'\nimport FleetList from './parts/fleet-list'\nimport Candidates from './parts/candidates'\n\nconst { i18n, getStore } = window\nconst __ = i18n['poi-plugin-anchorage-repair'].__.bind(i18n['poi-plugin-anchorage-repair'])\n\nconst AKASHI_ID = [182, 187] // akashi and kai ID in $ships\nconst SRF_ID = 86 // Ship Repair Facility ID in $slotitems\n\n\n// check a fleet status, returns information related to anchorage repair\nconst fleetAkashiConv = (fleet, $ships, ships, equips, repairId) => {\n const pickKey = ['api_id', 'api_ship_id', 'api_lv', 'api_nowhp', 'api_maxhp', 'api_ndock_time']\n\n let canRepair = false\n let akashiFlagship = false\n let repairCount = 0\n const inExpedition = _.get(fleet, 'api_mission.0') && true\n const flagShipInRepair = _.includes(repairId, _.get(fleet, 'api_ship.0', -1))\n const flagship = ships[_.get(fleet, 'api_ship.0', -1)]\n\n if (flagship != null) {\n akashiFlagship = _.includes(AKASHI_ID, flagship.api_ship_id)\n repairCount = _.filter(flagship.api_slot, item => _.get(equips, `${item}.api_slotitem_id`, -1) === SRF_ID).length\n repairCount += akashiFlagship ? 2 : 0\n }\n\n canRepair = akashiFlagship && !inExpedition && !flagShipInRepair\n\n const repairDetail = _.map(_.filter(fleet.api_ship, shipId => shipId > 0), (shipId, index) => {\n if (shipId === -1) return false // break, LODASH ONLY\n\n const ship = _.pick(ships[shipId], pickKey)\n\n const constShip = _.pick($ships[ship.api_ship_id], ['api_name', 'api_stype'])\n\n return {\n ...ship,\n ...constShip,\n estimate: akashiEstimate(ship),\n timePerHP: getTimePerHP(ship.api_lv, constShip.api_stype),\n inRepair: _.includes(repairId, ship.api_id),\n availableSRF: index < repairCount,\n }\n })\n\n return {\n api_id: fleet.api_id || -1,\n shipId: fleet.api_ship || [],\n canRepair,\n akashiFlagship,\n inExpedition,\n flagShipInRepair,\n repairCount,\n repairDetail,\n }\n}\n\n// selectors\n\nconst repairIdSelector = createSelector(\n [repairsSelector],\n repair => _.map(repair, dock => dock.api_ship_id)\n)\n\nconst constShipsSelector = state => state.const.$ships || {}\n\nconst fleetsAkashiSelector = createSelector(\n [\n constShipsSelector,\n fleetsSelector,\n shipsSelector,\n equipsSelector,\n repairIdSelector,\n ],\n ($ships, fleets, ships, equips, repairId) =>\n ({ fleets: _.map(fleets, fleet => fleetAkashiConv(fleet, $ships, ships, equips, repairId)) })\n\n)\n\n\n// React\n\nexport const reactClass = connect(\n createDeepCompareArraySelector([\n fleetsAkashiSelector,\n miscSelector,\n ], (data, { canNotify }) => ({\n ...data,\n canNotify,\n }))\n)(class PluginAnchorageRepair extends Component {\n\n constructor(props) {\n super(props)\n\n this.state = {\n activeTab: 1,\n sortIndex: 0,\n }\n }\n\n handleSelectTab = (key) => {\n this.setState({ activeTab: key })\n }\n\n handleSort = index => () => {\n this.setState({\n sortIndex: index,\n })\n }\n\n render() {\n return (\n <div id=\"anchorage-repair\">\n <link rel=\"stylesheet\" href={join(__dirname, 'assets', 'style.css')} />\n <Tabs activeKey={this.state.activeTab} onSelect={this.handleSelectTab} id=\"anchorage-tabs\">\n {\n _.map(this.props.fleets, (fleet, index) => (\n <Tab\n eventKey={fleet.api_id}\n title={fleet.api_id}\n key={`anchorage-tab-${index}`}\n tabClassName={fleet.canRepair ? 'can-repair' : ''}\n >\n <FleetList fleet={fleet} />\n </Tab>\n ))\n }\n <Tab\n className=\"candidate-pane\"\n eventKey={-1}\n title={__('Candidates')}\n >\n <Candidates handleSort={this.handleSort} sortIndex={this.state.sortIndex} />\n </Tab>\n </Tabs>\n </div>\n )\n }\n})\n\n\n/*\n\n The following APIs are called in order when a fleet returns from expedition:\n\n - api_req_mission/result\n - api_port/port\n\n As anchorage repair pops up conditionally on the latter one,\n it also prevents other plugins' auto-switch mechanism on\n tracking api_req_mission/result calls.\n\n The problem is solved by applying a lock upon expedition returns\n and ignoring the immediately followed api_port/port call.\n\n */\nlet expedReturnLock = null\nconst clearExpedReturnLock = () => {\n if (expedReturnLock !== null) {\n clearTimeout(expedReturnLock)\n expedReturnLock = null\n }\n}\n\nexport const switchPluginPath = [\n {\n path: '/kcsapi/api_port/port',\n valid: () => {\n if (expedReturnLock !== null) {\n /*\n this is the immediately followed api_port/port call\n after an expedition returning event.\n */\n clearExpedReturnLock()\n return false\n }\n\n const { fleets = [], ships = {}, equips = {}, repairs = [] } = getStore('info') || {}\n const $ships = getStore('const.$ships')\n const repairId = repairs.map(dock => dock.api_ship_id)\n\n const result = fleets.map(fleet => fleetAkashiConv(fleet, $ships, ships, equips, repairId))\n return result.some(fleet =>\n fleet.canRepair && fleet.repairDetail.some(ship => ship.estimate > 0))\n },\n },\n {\n path: '/kcsapi/api_req_mission/result',\n valid: () => {\n clearExpedReturnLock()\n expedReturnLock = setTimeout(\n clearExpedReturnLock,\n /*\n allow a window of 5 secnds before the lock\n clears itself\n */\n 5000\n )\n return false\n },\n },\n]\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "poi-plugin-milk",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Anchorage repair plugin for poi",
|
|
5
|
+
"main": "index.es",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/KagamiChan/plugin-anchorage-repair.git"
|
|
9
|
+
},
|
|
10
|
+
"author": {
|
|
11
|
+
"name": "かがみ",
|
|
12
|
+
"link": "https://github.com/kagamichan"
|
|
13
|
+
},
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"bugs": {
|
|
16
|
+
"url": "https://github.com/KagamiChan/plugin-anchorage-repair/issues"
|
|
17
|
+
},
|
|
18
|
+
"homepage": "https://github.com/KagamiChan/plugin-anchorage-repair#readme",
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"babel-eslint": "^7.2.3",
|
|
21
|
+
"babel-preset-es2017": "^6.24.1",
|
|
22
|
+
"eslint": "^3.19.0",
|
|
23
|
+
"eslint-config-airbnb": "^15.0.1",
|
|
24
|
+
"eslint-plugin-import": "^2.3.0",
|
|
25
|
+
"eslint-plugin-jsx-a11y": "^5.0.3",
|
|
26
|
+
"eslint-plugin-react": "^7.0.1",
|
|
27
|
+
"poi-util-transpile": "^7.6.0"
|
|
28
|
+
},
|
|
29
|
+
"poiPlugin": {
|
|
30
|
+
"title": "Anchorage repair",
|
|
31
|
+
"description": "A plugin to help in Akashi's anchorage repair arrangement",
|
|
32
|
+
"icon": "ti/anchor",
|
|
33
|
+
"priority": 9,
|
|
34
|
+
"apiVer": {
|
|
35
|
+
"6.99.99": "0.1.0",
|
|
36
|
+
"7.5.99": "0.4.5",
|
|
37
|
+
"7.7.99": "0.4.8"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"chroma-js": "^1.3.4"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
|
8
|
+
|
|
9
|
+
var _react = require('react');
|
|
10
|
+
|
|
11
|
+
var _react2 = _interopRequireDefault(_react);
|
|
12
|
+
|
|
13
|
+
var _reselect = require('reselect');
|
|
14
|
+
|
|
15
|
+
var _reactRedux = require('react-redux');
|
|
16
|
+
|
|
17
|
+
var _fp = require('lodash/fp');
|
|
18
|
+
|
|
19
|
+
var _fp2 = _interopRequireDefault(_fp);
|
|
20
|
+
|
|
21
|
+
var _lodash = require('lodash');
|
|
22
|
+
|
|
23
|
+
var _reactVirtualized = require('react-virtualized');
|
|
24
|
+
|
|
25
|
+
var _reactBootstrap = require('react-bootstrap');
|
|
26
|
+
|
|
27
|
+
var _reactFontawesome = require('react-fontawesome');
|
|
28
|
+
|
|
29
|
+
var _reactFontawesome2 = _interopRequireDefault(_reactFontawesome);
|
|
30
|
+
|
|
31
|
+
var _chromaJs = require('chroma-js');
|
|
32
|
+
|
|
33
|
+
var _chromaJs2 = _interopRequireDefault(_chromaJs);
|
|
34
|
+
|
|
35
|
+
var _selectors = require('views/utils/selectors');
|
|
36
|
+
|
|
37
|
+
var _tools = require('views/utils/tools');
|
|
38
|
+
|
|
39
|
+
var _functions = require('./functions');
|
|
40
|
+
|
|
41
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
42
|
+
|
|
43
|
+
const { i18n } = window;
|
|
44
|
+
const __ = i18n['poi-plugin-anchorage-repair'].__.bind(i18n['poi-plugin-anchorage-repair']);
|
|
45
|
+
|
|
46
|
+
const sortable = ['HP', 'Akashi Time', 'Per HP'];
|
|
47
|
+
|
|
48
|
+
const getSortValue = sortIndex => ship => {
|
|
49
|
+
const direction = sortIndex % 2 ? -1 : 1;
|
|
50
|
+
|
|
51
|
+
switch (parseInt(sortIndex / 2, 10)) {
|
|
52
|
+
case 0:
|
|
53
|
+
return ship.api_nowhp / ship.api_maxhp * direction;
|
|
54
|
+
case 1:
|
|
55
|
+
return ship.akashi * direction;
|
|
56
|
+
case 2:
|
|
57
|
+
return ship.perHP * direction;
|
|
58
|
+
default:
|
|
59
|
+
return ship.api_id;
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const allFleetShipIdSelector = (0, _reselect.createSelector)([...[...new Array(4).keys()].map(fleetId => (0, _selectors.fleetShipsIdSelectorFactory)(fleetId))], (id1, id2, id3, id4) => [id1, id2, id3, id4]);
|
|
64
|
+
|
|
65
|
+
const shipFleetIdMapSelector = (0, _reselect.createSelector)([state => state.info.ships, allFleetShipIdSelector], (ships, fleetIds) => (0, _lodash.mapValues)(ships, ship => (0, _lodash.findIndex)(fleetIds, fleetId => (0, _lodash.includes)(fleetId, ship.api_id))));
|
|
66
|
+
|
|
67
|
+
const repairIdSelector = (0, _reselect.createSelector)([_selectors.repairsSelector], repair => (0, _lodash.map)(repair, dock => dock.api_ship_id));
|
|
68
|
+
|
|
69
|
+
const candidateShipsSelector = sortIndex => (0, _reselect.createSelector)([state => state.info.ships, state => state.const.$ships, shipFleetIdMapSelector, repairIdSelector], (ships, $ships, shipFleetIdMap, repairIds) => _fp2.default.flow(_fp2.default.filter(ship => (0, _functions.akashiEstimate)(ship) > 0 && !(0, _lodash.includes)(repairIds, ship.api_id)), _fp2.default.map(ship => _extends({}, $ships[ship.api_ship_id], ship, {
|
|
70
|
+
akashi: (0, _functions.akashiEstimate)(ship),
|
|
71
|
+
perHP: (0, _functions.timePerHPCalc)(ship),
|
|
72
|
+
fleetId: shipFleetIdMap[ship.api_id]
|
|
73
|
+
})), _fp2.default.sortBy(ship => getSortValue(sortIndex)(ship)))(ships));
|
|
74
|
+
|
|
75
|
+
const getHPBackgroundColor = (nowhp, maxhp) => {
|
|
76
|
+
const percentage = nowhp / maxhp;
|
|
77
|
+
return percentage > 0.75 ? _chromaJs2.default.mix('rgb(253, 216, 53)', 'rgb(67, 160, 71)', (percentage - 0.75) / 0.25, 'lab').alpha(0.6).css() : _chromaJs2.default.mix('rgb(245, 124, 0)', 'rgb(253, 216, 53)', (percentage - 0.5) / 0.25, 'lab').alpha(0.6).css();
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
// console.log(
|
|
81
|
+
// chroma.mix('rgb(253, 216, 53)', 'rgb(67, 160, 71)', 0.5, 'lch').alpha(0.6).css(),
|
|
82
|
+
// chroma.mix('rgb(253, 216, 53)', 'rgb(67, 160, 71)', 0.5, 'rgb').alpha(0.6).css(),
|
|
83
|
+
// chroma.mix('rgb(253, 216, 53)', 'rgb(67, 160, 71)', 0.5, 'hsl').alpha(0.6).css(),
|
|
84
|
+
// chroma.mix('rgb(253, 216, 53)', 'rgb(67, 160, 71)', 0.5, 'lab').alpha(0.6).css(),
|
|
85
|
+
// )
|
|
86
|
+
// (nowhp / maxhp) > 0.75 ? 'rgba(67, 160, 71, 0.6)' : 'rgba(253, 216, 53, 0.6)'
|
|
87
|
+
|
|
88
|
+
const Candidates = (0, _reactRedux.connect)((state, { sortIndex = 0 }) => ({
|
|
89
|
+
ships: candidateShipsSelector(sortIndex)(state)
|
|
90
|
+
}))(class Candidates extends _react.Component {
|
|
91
|
+
constructor(...args) {
|
|
92
|
+
var _temp;
|
|
93
|
+
|
|
94
|
+
return _temp = super(...args), this.rowRenderer = ({ key, index, style }) => {
|
|
95
|
+
const { ships } = this.props;
|
|
96
|
+
const ship = ships[index];
|
|
97
|
+
const color = getHPBackgroundColor(ship.api_nowhp, ship.api_maxhp);
|
|
98
|
+
const percentage = Math.round(100 * ship.api_nowhp / ship.api_maxhp);
|
|
99
|
+
return _react2.default.createElement(
|
|
100
|
+
'div',
|
|
101
|
+
{
|
|
102
|
+
className: 'candidate-ship-item',
|
|
103
|
+
style: _extends({}, style, {
|
|
104
|
+
background: `linear-gradient(90deg, ${color} ${percentage}%, rgba(0, 0, 0, 0) 50%)`
|
|
105
|
+
}),
|
|
106
|
+
key: key
|
|
107
|
+
},
|
|
108
|
+
_react2.default.createElement(
|
|
109
|
+
'span',
|
|
110
|
+
{ className: 'ship-name' },
|
|
111
|
+
`Lv.${ship.api_lv} ${window.i18n.resources.__(ship.api_name)}${ship.fleetId < 0 ? '' : `/${ship.fleetId + 1}`}`
|
|
112
|
+
),
|
|
113
|
+
_react2.default.createElement(
|
|
114
|
+
'span',
|
|
115
|
+
{ style: { marginLeft: '1em' } },
|
|
116
|
+
`(${ship.api_nowhp} / ${ship.api_maxhp})`
|
|
117
|
+
),
|
|
118
|
+
_react2.default.createElement(
|
|
119
|
+
'span',
|
|
120
|
+
{ style: { marginLeft: '2em' } },
|
|
121
|
+
`${(0, _tools.resolveTime)(ship.akashi / 1000)} / ${(0, _tools.resolveTime)(ship.perHP / 1000)}`
|
|
122
|
+
)
|
|
123
|
+
);
|
|
124
|
+
}, _temp;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
render() {
|
|
128
|
+
const { ships, sortIndex } = this.props;
|
|
129
|
+
return _react2.default.createElement(
|
|
130
|
+
'div',
|
|
131
|
+
{
|
|
132
|
+
id: 'candidate-list'
|
|
133
|
+
},
|
|
134
|
+
_react2.default.createElement(
|
|
135
|
+
'div',
|
|
136
|
+
{ style: { marginBottom: '1ex' } },
|
|
137
|
+
_react2.default.createElement(
|
|
138
|
+
_reactBootstrap.ButtonGroup,
|
|
139
|
+
{ bsSize: 'small' },
|
|
140
|
+
[...new Array(6).keys()].map(index => _react2.default.createElement(
|
|
141
|
+
_reactBootstrap.Button,
|
|
142
|
+
{
|
|
143
|
+
key: index,
|
|
144
|
+
onClick: this.props.handleSort(index),
|
|
145
|
+
bsStyle: index === sortIndex ? 'success' : 'default'
|
|
146
|
+
},
|
|
147
|
+
__(sortable[parseInt(index / 2, 10)]),
|
|
148
|
+
_react2.default.createElement(_reactFontawesome2.default, { name: index % 2 === 0 ? 'arrow-up' : 'arrow-down' })
|
|
149
|
+
))
|
|
150
|
+
)
|
|
151
|
+
),
|
|
152
|
+
_react2.default.createElement(
|
|
153
|
+
_reactVirtualized.AutoSizer,
|
|
154
|
+
null,
|
|
155
|
+
({ height, width }) => _react2.default.createElement(_reactVirtualized.List, {
|
|
156
|
+
sortIndex: sortIndex,
|
|
157
|
+
height: height,
|
|
158
|
+
width: width,
|
|
159
|
+
rowHeight: 40,
|
|
160
|
+
rowCount: ships.length,
|
|
161
|
+
rowRenderer: this.rowRenderer
|
|
162
|
+
})
|
|
163
|
+
)
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
exports.default = Candidates;
|
|
169
|
+
module.exports = exports['default'];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["candidates.es"],"names":["i18n","window","__","bind","sortable","getSortValue","sortIndex","ship","direction","parseInt","api_nowhp","api_maxhp","akashi","perHP","api_id","allFleetShipIdSelector","Array","keys","map","fleetId","id1","id2","id3","id4","shipFleetIdMapSelector","state","info","ships","fleetIds","repairIdSelector","repair","dock","api_ship_id","candidateShipsSelector","const","$ships","shipFleetIdMap","repairIds","flow","filter","sortBy","getHPBackgroundColor","nowhp","maxhp","percentage","mix","alpha","css","Candidates","rowRenderer","key","index","style","props","color","Math","round","background","api_lv","resources","api_name","marginLeft","render","marginBottom","handleSort","height","width","length"],"mappings":"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","file":"candidates.es","sourcesContent":["import React, { Component } from 'react'\nimport { createSelector } from 'reselect'\nimport { connect } from 'react-redux'\nimport fp from 'lodash/fp'\nimport { mapValues, findIndex, includes, map } from 'lodash'\nimport { AutoSizer, List } from 'react-virtualized'\nimport { ButtonGroup, Button } from 'react-bootstrap'\nimport FA from 'react-fontawesome'\nimport chroma from 'chroma-js'\n\nimport { repairsSelector, fleetShipsIdSelectorFactory } from 'views/utils/selectors'\nimport { resolveTime } from 'views/utils/tools'\n\nimport { akashiEstimate, timePerHPCalc } from './functions'\n\nconst { i18n } = window\nconst __ = i18n['poi-plugin-anchorage-repair'].__.bind(i18n['poi-plugin-anchorage-repair'])\n\nconst sortable = [\n 'HP',\n 'Akashi Time',\n 'Per HP',\n]\n\nconst getSortValue = sortIndex => (ship) => {\n const direction = sortIndex % 2 ? -1 : 1\n\n switch (parseInt(sortIndex / 2, 10)) {\n case 0:\n return (ship.api_nowhp / ship.api_maxhp) * direction\n case 1:\n return ship.akashi * direction\n case 2:\n return ship.perHP * direction\n default:\n return ship.api_id\n }\n}\n\nconst allFleetShipIdSelector = createSelector(\n [\n ...[...new Array(4).keys()].map(fleetId => fleetShipsIdSelectorFactory(fleetId)),\n ],\n (id1, id2, id3, id4) => [id1, id2, id3, id4]\n)\n\nconst shipFleetIdMapSelector = createSelector(\n [\n state => state.info.ships,\n allFleetShipIdSelector,\n ], (ships, fleetIds) =>\n mapValues(ships, ship => findIndex(fleetIds, fleetId => includes(fleetId, ship.api_id)))\n)\n\nconst repairIdSelector = createSelector(\n [repairsSelector],\n repair => map(repair, dock => dock.api_ship_id)\n)\n\nconst candidateShipsSelector = sortIndex => createSelector(\n [\n state => state.info.ships,\n state => state.const.$ships,\n shipFleetIdMapSelector,\n repairIdSelector,\n ], (ships, $ships, shipFleetIdMap, repairIds) =>\n fp.flow(\n fp.filter(ship => akashiEstimate(ship) > 0 && !includes(repairIds, ship.api_id)),\n fp.map(ship => ({\n ...$ships[ship.api_ship_id],\n ...ship,\n akashi: akashiEstimate(ship),\n perHP: timePerHPCalc(ship),\n fleetId: shipFleetIdMap[ship.api_id],\n })),\n fp.sortBy(ship => getSortValue(sortIndex)(ship))\n )(ships)\n)\n\nconst getHPBackgroundColor = (nowhp, maxhp) => {\n const percentage = nowhp / maxhp\n return percentage > 0.75\n ? chroma.mix('rgb(253, 216, 53)', 'rgb(67, 160, 71)', (percentage - 0.75) / 0.25, 'lab').alpha(0.6).css()\n : chroma.mix('rgb(245, 124, 0)', 'rgb(253, 216, 53)', (percentage - 0.5) / 0.25, 'lab').alpha(0.6).css()\n}\n\n// console.log(\n// chroma.mix('rgb(253, 216, 53)', 'rgb(67, 160, 71)', 0.5, 'lch').alpha(0.6).css(),\n// chroma.mix('rgb(253, 216, 53)', 'rgb(67, 160, 71)', 0.5, 'rgb').alpha(0.6).css(),\n// chroma.mix('rgb(253, 216, 53)', 'rgb(67, 160, 71)', 0.5, 'hsl').alpha(0.6).css(),\n// chroma.mix('rgb(253, 216, 53)', 'rgb(67, 160, 71)', 0.5, 'lab').alpha(0.6).css(),\n// )\n // (nowhp / maxhp) > 0.75 ? 'rgba(67, 160, 71, 0.6)' : 'rgba(253, 216, 53, 0.6)'\n\nconst Candidates = connect(\n (state, { sortIndex = 0 }) => ({\n ships: candidateShipsSelector(sortIndex)(state),\n })\n)(class Candidates extends Component {\n\n rowRenderer = ({ key, index, style }) => {\n const { ships } = this.props\n const ship = ships[index]\n const color = getHPBackgroundColor(ship.api_nowhp, ship.api_maxhp)\n const percentage = Math.round((100 * ship.api_nowhp) / ship.api_maxhp)\n return (\n <div\n className=\"candidate-ship-item\"\n style={{\n ...style,\n background: `linear-gradient(90deg, ${color} ${percentage}%, rgba(0, 0, 0, 0) 50%)`,\n }}\n key={key}\n >\n <span className=\"ship-name\">\n { `Lv.${ship.api_lv} ${window.i18n.resources.__(ship.api_name)}${ship.fleetId < 0 ? '' : `/${ship.fleetId + 1}`}` }\n </span>\n <span style={{ marginLeft: '1em' }}>{`(${ship.api_nowhp} / ${ship.api_maxhp})`}</span>\n <span style={{ marginLeft: '2em' }}>{ `${resolveTime(ship.akashi / 1000)} / ${resolveTime(ship.perHP / 1000)}` }</span>\n </div>\n )\n }\n\n render() {\n const { ships, sortIndex } = this.props\n return (\n <div\n id=\"candidate-list\"\n >\n <div style={{ marginBottom: '1ex' }}>\n <ButtonGroup bsSize=\"small\">\n {\n [...new Array(6).keys()].map(index => (\n <Button\n key={index}\n onClick={this.props.handleSort(index)}\n bsStyle={index === sortIndex ? 'success' : 'default'}\n >\n {__(sortable[parseInt(index / 2, 10)])}<FA name={index % 2 === 0 ? 'arrow-up' : 'arrow-down'} />\n </Button>\n ))\n }\n </ButtonGroup>\n </div>\n <AutoSizer>\n {\n ({ height, width }) => (\n <List\n sortIndex={sortIndex}\n height={height}\n width={width}\n rowHeight={40}\n rowCount={ships.length}\n rowRenderer={this.rowRenderer}\n />\n )\n }\n </AutoSizer>\n </div>\n )\n }\n})\n\nexport default Candidates\n"]}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
var _react = require('react');
|
|
8
|
+
|
|
9
|
+
var _react2 = _interopRequireDefault(_react);
|
|
10
|
+
|
|
11
|
+
var _propTypes = require('prop-types');
|
|
12
|
+
|
|
13
|
+
var _propTypes2 = _interopRequireDefault(_propTypes);
|
|
14
|
+
|
|
15
|
+
var _tools = require('views/utils/tools');
|
|
16
|
+
|
|
17
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
18
|
+
|
|
19
|
+
class CountupTimer extends _react.Component {
|
|
20
|
+
constructor(props) {
|
|
21
|
+
super(props);
|
|
22
|
+
this.state = {
|
|
23
|
+
startTime: this.props.startTime
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
this.componentDidMount = () => {
|
|
27
|
+
this.startTick();
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
this.componentWillReceiveProps = nextProps => {
|
|
31
|
+
if (nextProps.countdownId !== this.props.countdownId) {
|
|
32
|
+
this.stopTick();
|
|
33
|
+
}
|
|
34
|
+
if (nextProps.startTime !== this.state.startTime) {
|
|
35
|
+
this.setState({ startTime: nextProps.startTime });
|
|
36
|
+
this.timeElapsed = this.constructor.getTimeElapsed(nextProps.startTime);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
this.shouldComponentUpdate = (nextProps, nextState) => nextProps.countdownId !== this.props.countdownId || nextState.startTime !== this.state.startTime;
|
|
41
|
+
|
|
42
|
+
this.componentDidUpdate = () => {
|
|
43
|
+
this.startTick // Doesn't matter if it didn't stop
|
|
44
|
+
();
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
this.componentWillUnmount = () => {
|
|
48
|
+
this.stopTick();
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
this.startTick = () => {
|
|
52
|
+
window.ticker.reg(this.props.countdownId, this.tick);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
this.stopTick = () => {
|
|
56
|
+
window.ticker.unreg(this.props.countdownId);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
this.tick = currentTime => {
|
|
60
|
+
// const actualElapsed = this.constructor.getTimeElapsed(this.state.startTime, currentTime)
|
|
61
|
+
// if (Math.abs(this.timeElapsed - actualElapsed) > 2) {
|
|
62
|
+
// this.timeElapsed = actualElapsed
|
|
63
|
+
// }
|
|
64
|
+
this.timeElapsed = this.constructor.getTimeElapsed(this.state.startTime, currentTime);
|
|
65
|
+
if (this.timeElapsed < 0) {
|
|
66
|
+
this.stopTick();
|
|
67
|
+
}
|
|
68
|
+
if (this.state.startTime >= 0) {
|
|
69
|
+
try {
|
|
70
|
+
if (this.textLabel) {
|
|
71
|
+
this.textLabel.textContent = (0, _tools.resolveTime)(this.timeElapsed) || (0, _tools.resolveTime)(0);
|
|
72
|
+
}
|
|
73
|
+
if (this.props.tickCallback) {
|
|
74
|
+
this.props.tickCallback(this.timeElapsed);
|
|
75
|
+
}
|
|
76
|
+
if (this.timeElapsed < 1 && this.props.startCallback) {
|
|
77
|
+
this.props.startCallback();
|
|
78
|
+
}
|
|
79
|
+
} catch (error) {
|
|
80
|
+
console.error(error.stack);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
this.timeElapsed += 1;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
this.timeElapsed = this.constructor.getTimeElapsed(this.props.startTime);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
render() {
|
|
90
|
+
return _react2.default.createElement(
|
|
91
|
+
'span',
|
|
92
|
+
{ ref: ref => {
|
|
93
|
+
this.textLabel = ref;
|
|
94
|
+
} },
|
|
95
|
+
(0, _tools.resolveTime)(this.timeElapsed)
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
exports.default = CountupTimer; // similar to CountdownTimer in 'views/components/main/parts/countdown-timer.es', but it counts up
|
|
100
|
+
|
|
101
|
+
CountupTimer.propTypes = {
|
|
102
|
+
countdownId: _propTypes2.default.string.isRequired, // UNIQUE ID to register to window.ticker
|
|
103
|
+
startTime: _propTypes2.default.number, // startTime in ms
|
|
104
|
+
tickCallback: _propTypes2.default.func, // callback function for each second
|
|
105
|
+
startCallback: _propTypes2.default.func // callback function when starting to count up
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
CountupTimer.getTimeElapsed = (startTime, currentTime = Date.now()) => {
|
|
109
|
+
if (startTime <= 0) {
|
|
110
|
+
return -1;
|
|
111
|
+
} else if (startTime > currentTime) {
|
|
112
|
+
return 0;
|
|
113
|
+
}
|
|
114
|
+
return Math.round((currentTime - startTime) / 1000);
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
CountupTimer.defaultProps = {
|
|
118
|
+
startTime: -1,
|
|
119
|
+
tickCallback: null,
|
|
120
|
+
startCallback: null
|
|
121
|
+
};
|
|
122
|
+
module.exports = exports['default'];
|