diff --git a/app.js b/app.js
index 3630b09..0bf0415 100644
--- a/app.js
+++ b/app.js
@@ -1,14 +1,8 @@
-import { TimerModel } from "./page/common"
-
App({
- globalData: {
- },
+ globalData: {},
onCreate(options) {
- console.log('app on create invoke')
- this.globalData.timerModel = new TimerModel()
},
onDestroy(options) {
- console.log('app on destroy invoke')
- }
-})
\ No newline at end of file
+ },
+});
diff --git a/app.json b/app.json
index 7861198..9f12516 100644
--- a/app.json
+++ b/app.json
@@ -1,12 +1,12 @@
{
- "configVersion": "v2",
+ "configVersion": "v3",
"app": {
"appId": 1032854,
"appName": "Timerr",
"appType": "app",
"version": {
- "code": 1,
- "name": "1.0.1"
+ "code": 2,
+ "name": "2.0.0"
},
"icon": "icon.png",
"vender": "zepp",
@@ -18,21 +18,22 @@
],
"runtime": {
"apiVersion": {
- "compatible": "2.0.0",
- "target": "2.0.0",
- "minVersion": "2.0.0"
+ "compatible": "3.0.0",
+ "target": "3.0.0",
+ "minVersion": "3.0"
}
},
+ "debug": false,
"targets": {
"trex": {
"module": {
"page": {
"pages": [
- "page/select_predefined/select_timer",
- "page/select_predefined/select_interval",
- "page/timer_progress/timer_progress",
- "page/create_timer/create_timer",
- "page/create_timer/create_interval"
+ "page/devices/trex/selection_pages/select_timer.page",
+ "page/devices/trex/selection_pages/select_interval.page",
+ "page/devices/trex/creation_pages/create_timer.page",
+ "page/devices/trex/creation_pages/create_interval.page",
+ "page/devices/trex/timer_progress/timer_progress.page"
]
}
},
diff --git a/assets/gt/.gitkeep b/assets/gt/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/assets/trex/gradient_w_1.png b/assets/trex/gradient_w_1.png
deleted file mode 100644
index dea7995..0000000
Binary files a/assets/trex/gradient_w_1.png and /dev/null differ
diff --git a/assets/trex/gradient_w_1_debug.png b/assets/trex/gradient_w_1_debug.png
deleted file mode 100644
index 022d34c..0000000
Binary files a/assets/trex/gradient_w_1_debug.png and /dev/null differ
diff --git a/assets/trex/gradient_w_2.png b/assets/trex/gradient_w_2.png
deleted file mode 100644
index d2d2aad..0000000
Binary files a/assets/trex/gradient_w_2.png and /dev/null differ
diff --git a/assets/trex/gradient_w_2_debug.png b/assets/trex/gradient_w_2_debug.png
deleted file mode 100644
index dec81ca..0000000
Binary files a/assets/trex/gradient_w_2_debug.png and /dev/null differ
diff --git a/global.d.ts b/global.d.ts
index fa22d93..ead47d2 100644
--- a/global.d.ts
+++ b/global.d.ts
@@ -1 +1 @@
-///
\ No newline at end of file
+///
diff --git a/jsconfig.json b/jsconfig.json
index 539d239..608d165 100644
--- a/jsconfig.json
+++ b/jsconfig.json
@@ -9,6 +9,6 @@
"**/node_modules/*"
],
"files": [
- "node_modules/@zeppos/device-types/index.d.ts"
+ "node_modules/@zeppos/device-types/dist/index.d.ts"
]
-}
\ No newline at end of file
+}
diff --git a/package.json b/package.json
index 0205ff5..3c24cfe 100644
--- a/package.json
+++ b/package.json
@@ -1,5 +1,5 @@
{
- "name": "empty",
+ "name": "timerr",
"version": "1.0.0",
"description": "",
"main": "app.js",
@@ -9,6 +9,9 @@
"author": "",
"license": "ISC",
"devDependencies": {
- "@zeppos/device-types": "^2.0.0"
+ "@zeppos/device-types": "^3.0.0"
+ },
+ "dependencies": {
+ "@zeppos/zml": "^0.0.9"
}
}
diff --git a/page/common.js b/page/common.js
deleted file mode 100644
index 2abde94..0000000
--- a/page/common.js
+++ /dev/null
@@ -1,91 +0,0 @@
-import {getText} from '@zos/i18n'
-
-export {getText}
-
-export const CONSTANTS = {
- seconds: {
- mili: 1000,
- min: 60,
- hour: 3600
- },
- i18n: {
- APP_NAME: 'appName',
- SELECT_TIMER_HEADER: 'select_timer',
- SELECT_INTERVAL_HEADER: 'select_interval',
- TIMER_PROGRESS_HEADER: 'timer_progress',
- CREATE_TIMER_HEADER: 'create_timer',
- CREATE_INTERVAL_HEADER: 'create_interval',
- UNIT_SECOND: 'unit_second',
- UNIT_MINUTE: 'unit_minute',
- UNIT_HOUR: 'unit_hour'
-
- },
- pages: {
- SELECT_TIMER: 'page/select_predefined/select_timer',
- SELECT_INTERVAL: 'page/select_predefined/select_interval',
- TIMER_PROGRESS: 'page/timer_progress/timer_progress',
- CREATE_TIMER: 'page/create_timer/create_timer',
- CREATE_INTERVAL: 'page/create_timer/create_interval'
- },
- img: {
- // bottom rectangle buttons
- PLUS: 'plus_button.png',
- PLUS_PRESSED: 'plus_button_pressed.png',
- CONFIRM: 'confirm_button.png',
- CONFIRM_PRESSED: 'confirm_button_pressed.png',
- STOP: 'stop_button.png',
- STOP_PRESSED: 'stop_button_pressed.png',
-
- // circle buttons
- CLOCK_BUTTON: 'clock_button.png',
- CLOCK_BUTTON_PRESSED: 'clock_button_pressed.png',
- CANCEL: 'cancel_button.png',
- CANCEL_PRESSED: 'cancel_button_pressed.png',
- PAUSE: 'pause_button.png',
- PAUSE_PRESSED: 'pause_button_pressed.png',
- RESUME: 'resume_button.png',
- RESUME_PRESSED: 'resume_button_pressed.png',
-
- // create new timer
- GRADIENT_BG_UP: 'gradient_w_1.png',
- GRADIENT_BG_BOTTOM: 'gradient_w_2.png'
- }
-}
-
-export class Unit {
- constructor(code, text) {
- this.code = code
- this.text = text
- }
-}
-
-export const Units = {
- SEC: new Unit('SEC', getText('unit_second')),
- MIN: new Unit('MIN', getText('unit_minute')),
- HOUR: new Unit('HOUR', getText('unit_hour'))
-}
-
-export class Timer {
- constructor(value, unit, valueSeconds = 0, args = {}) {
- this.value = value
- this.unit = unit
- this.valueSeconds = valueSeconds
- this.img = CONSTANTS.img.CLOCK_BUTTON
- this.img_pressed = CONSTANTS.img.CLOCK_BUTTON_PRESSED
- const {displayName} = args
- this.displayName = displayName
- }
-
- getDisplayName() {
- return !this.displayName ? this.value + ' ' + this.unit.text : this.displayName
- }
-}
-
-export class TimerModel {
- constructor() {
- this.timer
- this.interval
- }
-}
-
-export const zeroPad = (num, places = 2) => String(num).padStart(places, '0')
\ No newline at end of file
diff --git a/page/common/common.layout.js b/page/common/common.layout.js
new file mode 100644
index 0000000..778a55e
--- /dev/null
+++ b/page/common/common.layout.js
@@ -0,0 +1,65 @@
+import {getDeviceInfo} from '@zos/device'
+import {align, text_style} from '@zos/ui'
+import {getText} from '@zos/i18n';
+
+export const {width: DEVICE_WIDTH, height: DEVICE_HEIGHT} = getDeviceInfo()
+
+export const COLORS = {
+ // see https://www.figma.com/design/bY5cr0QN41npTOTO642Did/Zepp-OS-3.0-Library-Circular-(Community)?node-id=31-3&node-type=canvas
+ SYS: {
+ BUTTON: 0x515151,
+ BUTTON_PRESSED: 0x313131,
+ BUTTON_HIGHLIGHT: 0x0986D4,
+ BUTTON_HIGHLIGHT_PRESSED: 0x234F7C,
+ HIGHLIGHT: 0x0986D4,
+ HIGHLIGHT_DISABLED: 0x10283F,
+ PAGE_BACKGROUND: 0x000000
+ },
+ TEXT: {
+ BUTTON: 0xFFFFFF,
+ LINK: 0x059AF7,
+ TITLE: 0xFFFFFF,
+ WARNING: 0xD14221,
+ SUBTITLE: 0xB2B2B2
+ },
+ SECONDARY: {
+ _01: 0x03B5AA,
+ _02: 0x7B9E89,
+ _03: 0x399E5A,
+ _18: 0xAA2F2F,
+ _20: 0x9B3642
+ }
+}
+
+// STYLES
+export const PAGE_HEADERS = {
+ HEADER_STYLE(pageName) {
+ return {
+ color: COLORS.TEXT.TITLE,
+ align_h: align.CENTER_H,
+ align_v: align.CENTER_V,
+ text_style: text_style.NONE,
+ text: getText(pageName)
+ }
+ }
+}
+
+export const BUTTONS = {
+ STANDARD_BOTTOM_BUTTON_STYLE(src, pressedSrc) {
+ return {
+ x: 0,
+ normal_src: src,
+ press_src: pressedSrc
+ }
+ },
+ STANDARD_BOTTOM_BUTTON_STYLE_WITH_HANDLER(src, pressedSrc, handler) {
+ return {
+ x: 0,
+ normal_src: src,
+ press_src: pressedSrc,
+ click_func: (button) => {
+ handler(button)
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/page/common/creation_pages/create_timer.page.template.js b/page/common/creation_pages/create_timer.page.template.js
new file mode 100644
index 0000000..347bb5e
--- /dev/null
+++ b/page/common/creation_pages/create_timer.page.template.js
@@ -0,0 +1,137 @@
+import {createWidget, widget} from '@zos/ui'
+import {formatNumberForPicker} from '../../../utils';
+import {getText} from '@zos/i18n';
+import {CONSTANTS} from '../../constants/constants';
+import {log as Logger} from '@zos/utils';
+import {TimeSpan} from '../../data/models'
+import {LocalStorage} from '@zos/storage'
+
+let hh = 0
+let mm = 0
+let ss = 0
+const logger = Logger.getLogger('timerr');
+const storage = new LocalStorage()
+
+function CreationPage(args) {
+ const {
+ //data
+ storageKey,
+ pageName,
+ nextPageUrl,
+
+ //style
+ headerStyle,
+ containerStyle,
+
+ //handlers
+ nextPageRoutingFunction
+ } = args
+
+ Page({
+ onInit() {
+ },
+ build() {
+ this.initValues()
+ let viewContainer = createWidget(widget.VIEW_CONTAINER, containerStyle)
+ this.renderTimerDisplay(viewContainer)
+ this.renderHeader(viewContainer);
+ },
+ onDestroy() {
+ },
+ initValues() {
+ hh = storage.getItem(`${pageName}.hh`, 0) ?? 0
+ mm = storage.getItem(`${pageName}.mm`, 0) ?? 0
+ ss = storage.getItem(`${pageName}.ss`, 0) ?? 0
+ logger.debug('initial picker values:',
+ ` ${pageName}.hh: `, hh,
+ ` ${pageName}.mm: `, mm,
+ ` ${pageName}.ss: `, ss)
+ },
+ renderTimerDisplay(viewContainer) {
+ this.selectTime(viewContainer)
+ },
+ renderHeader(viewContainer) {
+ viewContainer.createWidget(widget.TEXT, headerStyle)
+ createWidget(widget.TEXT, headerStyle)
+ },
+ selectTime(viewContainer) {
+ viewContainer.createWidget(widget.WIDGET_PICKER, {
+ title: '',
+ nb_of_columns: 3,
+ init_col_index: 2,
+ data_config: [
+ {
+ data_array: new Array(24).fill(0).map((d, index) => formatNumberForPicker(index)),
+ support_loop: true,
+ init_val_index: hh,
+ connector: ':',
+ unit: getText(CONSTANTS.i18n.UNIT_HOUR)
+ },
+ {
+ data_array: new Array(60).fill(0).map((d, index) => formatNumberForPicker(index)),
+ support_loop: false,
+ init_val_index: mm,
+ connector: ':',
+ unit: getText(CONSTANTS.i18n.UNIT_MINUTE)
+ },
+ {
+ data_array: new Array(60).fill(0).map((d, index) => formatNumberForPicker(index)),
+ support_loop: false,
+ init_val_index: ss,
+ unit: getText(CONSTANTS.i18n.UNIT_SECOND)
+ }
+ ],
+ picker_cb: this.pickerCallback
+ });
+ },
+ pickerCallback(picker, event_type, column, valueIndex) {
+ function collectTimeSpans() {
+ let hourSec = new TimeSpan(getNumber(hh), CONSTANTS.timeUnits.HOUR).valueSeconds
+ let minSec = new TimeSpan(getNumber(mm), CONSTANTS.timeUnits.MIN).valueSeconds
+ let sec = new TimeSpan(getNumber(ss), CONSTANTS.timeUnits.SEC).valueSeconds
+ return new TimeSpan(sec + minSec + hourSec, CONSTANTS.timeUnits.SEC)
+ }
+
+ function getNumber(value) {
+ return (typeof value === 'number') ? value : 0;
+ }
+
+ function putInLocalStorage(storage, pageName, hh, mm, ss) {
+ logger.debug('save picker values:',
+ ` ${pageName}.hh: `, hh,
+ ` ${pageName}.mm: `, mm,
+ ` ${pageName}.ss: `, ss)
+ storage.setItem(`${pageName}.hh`, hh)
+ storage.setItem(`${pageName}.mm`, mm)
+ storage.setItem(`${pageName}.ss`, ss)
+ }
+
+ function savePikerValues(timeSpan) {
+ // remember selected picker values for future
+ putInLocalStorage(storage, pageName, hh, mm, ss)
+ logger.debug('select ' + storageKey + ' : ' + timeSpan.valueSeconds)
+ getApp()._options.globalData[storageKey] = timeSpan
+ }
+
+ if (event_type === 1) {
+ switch (column) {
+ case 0:
+ hh = valueIndex
+ break;
+ case 1:
+ mm = valueIndex
+ break;
+ case 2:
+ ss = valueIndex
+ break;
+ }
+ } else if (event_type === 2) {
+ let timeSpan = collectTimeSpans();
+ savePikerValues(timeSpan)
+ nextPageRoutingFunction({url: nextPageUrl})
+ }
+ }
+ })
+}
+
+export default CreationPage
\ No newline at end of file
diff --git a/page/common/selection_pages/select_timer.page.template.js b/page/common/selection_pages/select_timer.page.template.js
new file mode 100644
index 0000000..c2aadc7
--- /dev/null
+++ b/page/common/selection_pages/select_timer.page.template.js
@@ -0,0 +1,70 @@
+import {createWidget, event, prop, widget} from '@zos/ui';
+import {log as Logger} from '@zos/utils';
+import {vibroCallback} from '../../../utils/index'
+
+const logger = Logger.getLogger('timerr');
+
+function SelectionPage(args) {
+ const {
+ //data
+ storageKey,
+ predefinedSpans,
+ columnsNumber,
+ creationPageUrl,
+ nextPageUrl,
+
+ //style
+ headerStyle,
+ containerStyle,
+ addButtonStyle,
+ timerButtonStyleFunction,
+
+ //handlers
+ creationPageRoutingFunction,
+ nextPageRoutingFunction
+ } = args
+
+ Page({
+ onInit() {
+ },
+ build() {
+ let viewContainer = createWidget(widget.VIEW_CONTAINER, containerStyle)
+ this.renderHeader(viewContainer);
+ this.renderDefaultSpans(viewContainer, predefinedSpans)
+ this.renderCreateButton()
+ },
+ onDestroy() {
+ },
+ renderHeader(viewContainer) {
+ viewContainer.createWidget(widget.TEXT, headerStyle)
+ },
+ renderDefaultSpans(viewContainer, predefinedSpans) {
+ for (let i = 0, row = 0, column = 0; i < predefinedSpans.length; i++) {
+ if (column === columnsNumber) {
+ column = 0
+ row++
+ }
+ let timeSpan = predefinedSpans[i]
+ let timeSpanButtonStyle = timerButtonStyleFunction(timeSpan, row, column++, vibroCallback((button) => {
+ this.saveSelectedValue(button)
+ nextPageRoutingFunction({url: nextPageUrl})
+ }));
+ let timerButton = viewContainer.createWidget(widget.BUTTON, timeSpanButtonStyle)
+ timerButton.setProperty(prop.DATASET, {timeSpan: timeSpan})
+ }
+ },
+ renderCreateButton() {
+ let createButton = createWidget(widget.BUTTON, addButtonStyle)
+ createButton.addEventListener(event.CLICK_DOWN, vibroCallback(() => {
+ creationPageRoutingFunction({url: creationPageUrl})
+ }))
+ },
+ saveSelectedValue(button) {
+ let timeSpan = button.getProperty(prop.DATASET).timeSpan;
+ logger.debug('select ' + storageKey + ' : ' + timeSpan.valueSeconds)
+ getApp()._options.globalData[storageKey] = timeSpan
+ }
+ });
+}
+
+export default SelectionPage
diff --git a/page/common/timer_progress/timer_progress.page.template.js b/page/common/timer_progress/timer_progress.page.template.js
new file mode 100644
index 0000000..4025363
--- /dev/null
+++ b/page/common/timer_progress/timer_progress.page.template.js
@@ -0,0 +1,188 @@
+import {back} from '@zos/router';
+import {createWidget, deleteWidget, prop, widget} from '@zos/ui';
+import {log as Logger} from '@zos/utils';
+import {CONSTANTS} from '../../constants/constants';
+import {pauseDropWristScreenOff, pausePalmScreenOff, resetDropWristScreenOff, resetPalmScreenOff} from '@zos/display'
+import {doLongVibro, formatNumberForPicker as _00, startVibration, stopVibration, vibroCallback} from '../../../utils/index'
+import {Time} from '@zos/sensor';
+
+const logger = Logger.getLogger('timerr')
+const MILLI = 1_000
+const PROCESS_DELAY_MS = 200
+const TIME = new Time()
+
+function TimerProgressPage(args) {
+ const {
+ //style
+ headerStyle,
+ remainingTimeStyleFunction,
+ cancelButtonStyleFunction,
+ pauseButtonStyleFunction,
+ resumeButtonStyleFunction,
+ stopButtonStyleFunction,
+ canvasLayoutStyle,
+ timerDisplayTextAccentColors,
+
+ //
+ createTimerProgressBarFunction
+ } = args
+
+ Page({
+ onInit() {
+ },
+ build() {
+ this.processes = []
+ this.timerSeconds = getApp()._options.globalData[CONSTANTS.session.timer].valueSeconds
+ this.intervalSeconds = getApp()._options.globalData[CONSTANTS.session.interval].valueSeconds
+ logger.debug('start with timer : ' + this.timerSeconds)
+ logger.debug('start with interval : ' + this.intervalSeconds)
+
+ this.pauseScreenOff()
+ this.renderWidgets()
+
+ this.start = TIME.getTime()
+ this.end = this.start + secondsToMillis(this.timerSeconds + 1)
+ this.remainingSeconds = getRemainingSeconds(this.end)
+ this.startTimer()
+ },
+ onDestroy() {
+ stopVibration()
+ this.resetScreenOff()
+ },
+ pauseScreenOff() {
+ const duration = {
+ duration: 0
+ }
+ pausePalmScreenOff(duration)
+ pauseDropWristScreenOff(duration)
+ },
+ resetScreenOff() {
+ resetPalmScreenOff()
+ resetDropWristScreenOff()
+ },
+ renderWidgets() {
+ this.canvas = createWidget(widget.CANVAS, canvasLayoutStyle)
+ this.updateTimerProgressBar(0)
+ createWidget(widget.TEXT, headerStyle)
+ this.timerDisplay = createWidget(widget.TEXT, remainingTimeStyleFunction(getRemainingTimeText(this.timerSeconds)))
+ this.cancelButton = this.createCancelButton(cancelButtonStyleFunction(vibroCallback(() => back())))
+ this.pauseButton = this.createPauseButton()
+ },
+ updateTimerProgressBar(progress) {
+ this.canvas.clear(canvasLayoutStyle)
+ createTimerProgressBarFunction(this.canvas, progress)
+ },
+ createCancelButton(options) {
+ return createWidget(widget.BUTTON, options)
+ },
+ createPauseButton() {
+ return createWidget(widget.BUTTON, pauseButtonStyleFunction(vibroCallback((button) => {
+ this.stopProcesses()
+ this.pause = TIME.getTime()
+ this.resumeButton = this.createResumeButton()
+ deleteWidget(button)
+ })))
+ },
+ createResumeButton() {
+ return createWidget(widget.BUTTON, resumeButtonStyleFunction(vibroCallback((button) => {
+ this.pauseButton = this.createPauseButton()
+ const pauseTime = TIME.getTime() - this.pause
+ this.end += pauseTime
+ this.lastReminderTime += pauseTime
+ this.startTimer()
+ deleteWidget(button)
+ })))
+ },
+ startTimer() {
+ logger.debug('start time: ', this.start, ' end time:', this.end)
+
+ const process = setInterval(() => {
+ const remainingSeconds = getRemainingSeconds(this.end)
+ this.setTimerDisplayText(getRemainingTimeText(remainingSeconds))
+ if (remainingSeconds === 0) {
+ this.stopProcesses()
+ this.deleteAdditionalButtons()
+ this.createCancelButton(stopButtonStyleFunction(vibroCallback(() => back())))
+ this.startTimerDisplayBlinking()
+ startVibration()
+ } else {
+ this.notifyOnInterval(remainingSeconds)
+ }
+ if (this.remainingSeconds != remainingSeconds) {
+ this.remainingSeconds = remainingSeconds
+ this.updateTimerProgressBar(getProgress(remainingSeconds, this.timerSeconds))
+ }
+ }, PROCESS_DELAY_MS)
+ this.processes.push(process)
+ },
+ setTimerDisplayText(textValue) {
+ this.timerDisplay.setProperty(prop.MORE, {
+ text: textValue
+ })
+ },
+ switchTimerDisplayColor(isWarning) {
+ this.timerDisplay.setProperty(prop.MORE, {
+ color: isWarning ? timerDisplayTextAccentColors[1] : timerDisplayTextAccentColors[0]
+ })
+ },
+ stopProcesses() {
+ this.processes.forEach(i => clearInterval(i))
+ },
+ deleteAdditionalButtons() {
+ deleteWidget(this.cancelButton)
+ deleteWidget(this.pauseButton)
+ deleteWidget(this.resumeButton)
+ },
+ startTimerDisplayBlinking() {
+ let switcher = true
+ let interval = setInterval(() => {
+ this.switchTimerDisplayColor(switcher)
+ switcher = !switcher
+ }, PROCESS_DELAY_MS)
+ this.processes.push(interval)
+ },
+ notifyOnInterval() {
+ if (this.intervalSeconds > 0) {
+ if (this.lastReminderTime) {
+ const now = TIME.getTime()
+ if (now - this.lastReminderTime >= secondsToMillis(this.intervalSeconds)) {
+ doLongVibro()
+ this.switchTimerDisplayColor(true)
+ this.lastReminderTime = now
+ } else {
+ this.switchTimerDisplayColor(false)
+ }
+ } else {
+ this.lastReminderTime = this.start
+ }
+ }
+ }
+ })
+}
+
+function getProgress(remainingSeconds, totalSeconds) {
+ if (remainingSeconds <= 0) {
+ return 100
+ }
+ return Math.min(100, Math.floor((totalSeconds - remainingSeconds) / totalSeconds * 100))
+}
+
+function getRemainingSeconds(endTime) {
+ return Math.floor(Math.max(0, endTime - TIME.getTime()) / MILLI)
+}
+
+function getRemainingTimeText(valueSeconds) {
+ const remainingHours = Math.floor(valueSeconds / CONSTANTS.timeUnits.HOUR.toSeconds())
+ const remainingMinutes = Math.floor(valueSeconds % CONSTANTS.timeUnits.HOUR.toSeconds() / CONSTANTS.timeUnits.MIN.toSeconds())
+ const remainingSeconds = valueSeconds % CONSTANTS.timeUnits.MIN.toSeconds()
+ if (remainingHours > 0) {
+ return `${_00(remainingHours)}:${_00(remainingMinutes)}:${_00(remainingSeconds)}`
+ }
+ return `${_00(remainingMinutes)}:${_00(remainingSeconds)}`
+}
+
+function secondsToMillis(seconds) {
+ return seconds * MILLI
+}
+
+export default TimerProgressPage
diff --git a/page/constants/constants.js b/page/constants/constants.js
new file mode 100644
index 0000000..ec6a638
--- /dev/null
+++ b/page/constants/constants.js
@@ -0,0 +1,45 @@
+import {Hour, Minute, Page, Second} from '../data/models'
+
+export const CONSTANTS = {
+ session: {
+ timer: 'timer',
+ interval: 'interval',
+ },
+ timeUnits: {
+ SEC: new Second(),
+ MIN: new Minute(),
+ HOUR: new Hour()
+ },
+ i18n: {
+ APP_NAME: 'appName',
+ UNIT_SECOND: 'unit_second',
+ UNIT_MINUTE: 'unit_minute',
+ UNIT_HOUR: 'unit_hour'
+ },
+ pages: {
+ SELECT_TIMER: new Page('select_timer', 'selection_pages/select_timer.page'),
+ SELECT_INTERVAL: new Page('select_interval', 'selection_pages/select_interval.page'),
+ CREATE_TIMER: new Page('create_timer', 'creation_pages/create_timer.page'),
+ CREATE_INTERVAL: new Page('create_interval', 'creation_pages/create_interval.page'),
+ TIMER_PROGRESS: new Page('timer_progress', 'timer_progress/timer_progress.page'),
+ },
+ images: {
+ // bottom rectangle buttons
+ PLUS: 'plus_button.png',
+ PLUS_PRESSED: 'plus_button_pressed.png',
+ CONFIRM: 'confirm_button.png',
+ CONFIRM_PRESSED: 'confirm_button_pressed.png',
+ STOP: 'stop_button.png',
+ STOP_PRESSED: 'stop_button_pressed.png',
+
+ // circle buttons
+ CLOCK_BUTTON: 'clock_button.png',
+ CLOCK_BUTTON_PRESSED: 'clock_button_pressed.png',
+ CANCEL: 'cancel_button.png',
+ CANCEL_PRESSED: 'cancel_button_pressed.png',
+ PAUSE: 'pause_button.png',
+ PAUSE_PRESSED: 'pause_button_pressed.png',
+ RESUME: 'resume_button.png',
+ RESUME_PRESSED: 'resume_button_pressed.png',
+ }
+}
diff --git a/page/create_timer/create_interval.js b/page/create_timer/create_interval.js
deleted file mode 100644
index d2d4b70..0000000
--- a/page/create_timer/create_interval.js
+++ /dev/null
@@ -1,13 +0,0 @@
-import {replace} from '@zos/router'
-
-import {CONSTANTS, getText} from '../common'
-import CreateNewTimerPage from './create_timer_template'
-
-CreateNewTimerPage({
- header: getText(CONSTANTS.i18n.CREATE_INTERVAL_HEADER),
- pageKey: 'create.interval',
- confirmHandler: function (timer) {
- getApp()._options.globalData.timerModel.interval = timer
- replace({url: CONSTANTS.pages.TIMER_PROGRESS})
- }
-})
diff --git a/page/create_timer/create_timer.js b/page/create_timer/create_timer.js
deleted file mode 100644
index f7eb00b..0000000
--- a/page/create_timer/create_timer.js
+++ /dev/null
@@ -1,13 +0,0 @@
-import {replace} from '@zos/router'
-
-import {CONSTANTS, getText} from '../common'
-import CreateNewTimerPage from './create_timer_template'
-
-CreateNewTimerPage({
- header: getText(CONSTANTS.i18n.CREATE_TIMER_HEADER),
- pageKey: 'create.timer',
- confirmHandler: function (timer) {
- getApp()._options.globalData.timerModel.timer = timer
- replace({url: CONSTANTS.pages.SELECT_INTERVAL})
- }
-})
diff --git a/page/create_timer/create_timer_template.js b/page/create_timer/create_timer_template.js
deleted file mode 100644
index fb2247e..0000000
--- a/page/create_timer/create_timer_template.js
+++ /dev/null
@@ -1,159 +0,0 @@
-import {Vibrator, VIBRATOR_SCENE_SHORT_LIGHT} from '@zos/sensor'
-import {localStorage} from '@zos/storage'
-import {createWidget, deleteWidget, event, prop, widget} from '@zos/ui'
-
-import {CONSTANTS, getText, Timer, Units, zeroPad} from '../common'
-import {COMMON, CREATE_TIMER} from '../style/style'
-
-const REEL_VALUES = []
-for (let i = 0; i < 60; i++) {
- REEL_VALUES.push({text: zeroPad(i, 2), src: '', value: i})
-}
-const REEL_TYPES = {HH: 'HH', MM: 'MM', SS: 'SS'}
-
-function CreateNewTimerPage(args) {
- const {
- header = getText(CONSTANTS.i18n.APP_NAME),
- headerStyle = COMMON.HEADER_STYLE(header),
- confirmButtonStyle = COMMON.STANDARD_BOTTOM_BUTTON_STYLE(CONSTANTS.img.CONFIRM, CONSTANTS.img.CONFIRM_PRESSED),
- confirmHandler,
- pageKey
- } = args
-
- Page({
- onInit() {
- },
- build() {
- this.hh = localStorage.getItem(`${pageKey}.hh`) ? localStorage.getItem(`${pageKey}.hh`) : 0
- this.mm = localStorage.getItem(`${pageKey}.mm`) ? localStorage.getItem(`${pageKey}.mm`) : 0
- this.ss = localStorage.getItem(`${pageKey}.ss`) ? localStorage.getItem(`${pageKey}.ss`) : 0
- this.vibro = new Vibrator()
- const header = createWidget(widget.TEXT, headerStyle)
- this.createConfirmButton()
- this.createTimerDisplay()
- },
- onDestroy() {
- this.vibro && this.vibro.stop()
- },
- createTimerDisplay() {
- this.createDisplayTextHH()
- this.createDisplayTextMM()
- this.createDisplayTextSS()
- },
- createDisplayTextHH() {
- const hhDisplayText = createWidget(widget.TEXT, CREATE_TIMER.DISPLAY_TEXT(this.hh, 0))
- const title = createWidget(widget.TEXT, CREATE_TIMER.DISPLAY_TEXT_SUB(getText(CONSTANTS.i18n.UNIT_HOUR), 0))
- hhDisplayText.addEventListener(event.CLICK_DOWN, (e) => {
- deleteWidget(hhDisplayText)
- deleteWidget(title)
- this.resetActiveReel()
- this.activeReel = this.createReelHH()
- })
- },
- createDisplayTextMM() {
- const mmDisplayText = createWidget(widget.TEXT, CREATE_TIMER.DISPLAY_TEXT(this.mm, 1))
- const title = createWidget(widget.TEXT, CREATE_TIMER.DISPLAY_TEXT_SUB(getText(CONSTANTS.i18n.UNIT_MINUTE), 1))
- mmDisplayText.addEventListener(event.CLICK_DOWN, (e) => {
- deleteWidget(mmDisplayText)
- deleteWidget(title)
- this.resetActiveReel()
- this.activeReel = this.createReelMM()
- })
- },
- createDisplayTextSS() {
- const ssDisplayText = createWidget(widget.TEXT, CREATE_TIMER.DISPLAY_TEXT(this.ss, 2))
- const title = createWidget(widget.TEXT, CREATE_TIMER.DISPLAY_TEXT_SUB(getText(CONSTANTS.i18n.UNIT_SECOND), 2))
- ssDisplayText.addEventListener(event.CLICK_DOWN, (e) => {
- deleteWidget(ssDisplayText)
- deleteWidget(title)
- this.resetActiveReel()
- this.activeReel = this.createReelSS()
- })
- },
- resetActiveReel() {
- if (this.activeReel) {
- deleteWidget(this.activeReel.reel)
- deleteWidget(this.activeReel.gradient.up)
- deleteWidget(this.activeReel.gradient.bottom)
- switch (this.activeReel.type) {
- case REEL_TYPES.HH:
- this.createDisplayTextHH()
- break
- case REEL_TYPES.MM:
- this.createDisplayTextMM()
- break
- case REEL_TYPES.SS:
- this.createDisplayTextSS()
- break
- }
- }
- },
- createReelHH() {
- const data = [REEL_VALUES[23]].concat(REEL_VALUES.slice(0, 23))
- return {
- reel: this.createReelWidget(data, 0, this.hh, (list, index) => {
- this.hh = this.getValueFromCycleList(list, index)
- }),
- gradient: this.createGradients(0),
- type: REEL_TYPES.HH
- }
- },
- createReelMM() {
- const data = [REEL_VALUES[59]].concat(REEL_VALUES.slice(0, 59))
- return {
- reel: this.createReelWidget(data, 1, this.mm, (list, index) => {
- this.mm = this.getValueFromCycleList(list, index)
- }),
- gradient: this.createGradients(1),
- type: REEL_TYPES.MM
- }
- },
- createReelSS() {
- const data = [REEL_VALUES[59]].concat(REEL_VALUES.slice(0, 59))
- return {
- reel: this.createReelWidget(data, 2, this.ss, (list, index) => {
- this.ss = this.getValueFromCycleList(list, index)
- }),
- gradient: this.createGradients(2),
- type: REEL_TYPES.SS
- }
- },
- createReelWidget(data, position, listTop, handler) {
- const reelWidget = createWidget(widget.CYCLE_IMAGE_TEXT_LIST, CREATE_TIMER.REEL_STILE(data, position, handler))
- reelWidget.setProperty(prop.LIST_TOP, listTop)
- return reelWidget
- },
- createGradients(position) {
- const up = createWidget(widget.IMG, CREATE_TIMER.GRADIENT_UP(position))
- const bottom = createWidget(widget.IMG, CREATE_TIMER.GRADIENT_BOTTOM(position))
- return {up: up, bottom: bottom}
- },
- createConfirmButton() {
- const button = createWidget(widget.BUTTON, confirmButtonStyle)
- button.addEventListener(event.CLICK_DOWN, (e) => {
- this.doVibro()
- confirmHandler(this.getTimerObject())
- this.saveTimer()
- })
- },
- getValueFromCycleList(list, index) {
- return index === 0 ? 0 : list[index].value + 1
- },
- getTimerObject() {
- const valueSeconds = this.hh * CONSTANTS.seconds.hour + this.mm * CONSTANTS.seconds.min + this.ss
- return new Timer(0, Units.SEC, valueSeconds)
- },
- saveTimer() {
- localStorage.setItem(`${pageKey}.hh`, this.hh)
- localStorage.setItem(`${pageKey}.mm`, this.mm)
- localStorage.setItem(`${pageKey}.ss`, this.ss)
- },
- doVibro() {
- this.vibro.stop()
- this.vibro.setMode(VIBRATOR_SCENE_SHORT_LIGHT)
- this.vibro.start()
- }
- })
-}
-
-export default CreateNewTimerPage
\ No newline at end of file
diff --git a/page/data/models.js b/page/data/models.js
new file mode 100644
index 0000000..c84c9e5
--- /dev/null
+++ b/page/data/models.js
@@ -0,0 +1,85 @@
+import {getText} from '@zos/i18n';
+import {log as Logger} from '@zos/utils';
+
+const logger = Logger.getLogger('timerr');
+
+export class Page {
+ constructor(name, url) {
+ this.name = name
+ this.url = url
+ }
+
+ getUrl(deviceFamily) {
+ let url = 'page/devices/' + deviceFamily + '/' + this.url
+ return url
+ }
+}
+
+export class TimeUnit {
+ constructor(code, text) {
+ this.code = code;
+ this.text = text;
+ }
+
+ toSeconds() {
+ throw new Error('not implemented')
+ }
+}
+
+export class Second extends TimeUnit {
+
+ constructor() {
+ super('SEC', getText('unit_second'));
+ }
+
+ toSeconds() {
+ return 1;
+ }
+}
+
+export class Minute extends TimeUnit {
+ constructor() {
+ super('MIN', getText('unit_minute'));
+ }
+
+ toSeconds() {
+ return 60;
+ }
+}
+
+export class Hour extends TimeUnit {
+ constructor() {
+ super('HOUR', getText('unit_hour'));
+ }
+
+ toSeconds() {
+ return 60 * 60;
+ }
+}
+
+export class TimeSpan {
+
+ constructor(value, unit, img = null, imgPressed = null) {
+ this.value = value;
+ this.unit = unit;
+ this.valueSeconds = value * unit.toSeconds();
+ this.img = img
+ this.imgPressed = imgPressed
+ }
+
+ getDisplayName() {
+ return this.value + ' ' + this.unit.text
+ }
+}
+
+export class ZeroSpan extends TimeSpan {
+
+ constructor(unit, img, imgPressed) {
+ super(0, unit, img, imgPressed)
+ }
+
+ getDisplayName() {
+ return '-'
+ }
+}
+
diff --git a/page/devices/gt/.gitkeep b/page/devices/gt/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/page/devices/trex/creation_pages/create_interval.page.js b/page/devices/trex/creation_pages/create_interval.page.js
new file mode 100644
index 0000000..f8d402b
--- /dev/null
+++ b/page/devices/trex/creation_pages/create_interval.page.js
@@ -0,0 +1,22 @@
+import CreationPage from '../../../common/creation_pages/create_timer.page.template'
+import {replace} from '@zos/router';
+import {CONSTANTS} from '../../../constants/constants';
+import * as layout from './creation.page.layout';
+import {log as Logger} from '@zos/utils';
+
+const logger = Logger.getLogger('timerr');
+
+let pageName = CONSTANTS.pages.CREATE_INTERVAL.name;
+CreationPage({
+ //data
+ storageKey: CONSTANTS.session.interval,
+ pageName: pageName,
+ nextPageUrl: CONSTANTS.pages.TIMER_PROGRESS.getUrl(layout.DEVICE_FAMILY),
+
+ //style
+ headerStyle: layout.HEADER_STYLE(pageName),
+ containerStyle: layout.STANDARD_CONTAINER_STYLE,
+
+ //handlers
+ nextPageRoutingFunction: replace
+})
\ No newline at end of file
diff --git a/page/devices/trex/creation_pages/create_timer.page.js b/page/devices/trex/creation_pages/create_timer.page.js
new file mode 100644
index 0000000..1561024
--- /dev/null
+++ b/page/devices/trex/creation_pages/create_timer.page.js
@@ -0,0 +1,22 @@
+import CreationPage from '../../../common/creation_pages/create_timer.page.template'
+import {replace} from '@zos/router';
+import {CONSTANTS} from '../../../constants/constants';
+import * as layout from './creation.page.layout';
+import {log as Logger} from '@zos/utils';
+
+const logger = Logger.getLogger('timerr');
+
+let pageName = CONSTANTS.pages.CREATE_TIMER.name;
+CreationPage({
+ //data
+ storageKey: CONSTANTS.session.timer,
+ pageName: pageName,
+ nextPageUrl: CONSTANTS.pages.SELECT_INTERVAL.getUrl(layout.DEVICE_FAMILY),
+
+ //style
+ headerStyle: layout.HEADER_STYLE(pageName),
+ containerStyle: layout.STANDARD_CONTAINER_STYLE,
+
+ //handlers
+ nextPageRoutingFunction: replace
+})
\ No newline at end of file
diff --git a/page/devices/trex/creation_pages/creation.page.layout.js b/page/devices/trex/creation_pages/creation.page.layout.js
new file mode 100644
index 0000000..2d061b4
--- /dev/null
+++ b/page/devices/trex/creation_pages/creation.page.layout.js
@@ -0,0 +1,3 @@
+import {BUTTONS, DEVICE_FAMILY, HEADER_STYLE, STANDARD_CONTAINER_STYLE} from '../trex.layout'
+
+export {BUTTONS, DEVICE_FAMILY, HEADER_STYLE, STANDARD_CONTAINER_STYLE}
diff --git a/page/devices/trex/selection_pages/select_interval.page.js b/page/devices/trex/selection_pages/select_interval.page.js
new file mode 100644
index 0000000..a43639a
--- /dev/null
+++ b/page/devices/trex/selection_pages/select_interval.page.js
@@ -0,0 +1,47 @@
+import {replace} from '@zos/router'
+
+import {TimeSpan, ZeroSpan} from '../../../data/models'
+import {CONSTANTS} from '../../../constants/constants'
+import SelectionPage from '../../../common/selection_pages/select_timer.page.template';
+import * as layout from './selection.page.layout';
+import {log as Logger} from '@zos/utils';
+
+const logger = Logger.getLogger('timerr');
+
+const predefinedSpans = [
+ new ZeroSpan(CONSTANTS.timeUnits.SEC, CONSTANTS.images.CLOCK_BUTTON, CONSTANTS.images.CLOCK_BUTTON_PRESSED),
+ new TimeSpan(5, CONSTANTS.timeUnits.SEC, CONSTANTS.images.CLOCK_BUTTON, CONSTANTS.images.CLOCK_BUTTON_PRESSED),
+ new TimeSpan(10, CONSTANTS.timeUnits.SEC, CONSTANTS.images.CLOCK_BUTTON, CONSTANTS.images.CLOCK_BUTTON_PRESSED),
+ new TimeSpan(30, CONSTANTS.timeUnits.SEC, CONSTANTS.images.CLOCK_BUTTON, CONSTANTS.images.CLOCK_BUTTON_PRESSED),
+ new TimeSpan(1, CONSTANTS.timeUnits.MIN, CONSTANTS.images.CLOCK_BUTTON, CONSTANTS.images.CLOCK_BUTTON_PRESSED),
+ new TimeSpan(2, CONSTANTS.timeUnits.MIN, CONSTANTS.images.CLOCK_BUTTON, CONSTANTS.images.CLOCK_BUTTON_PRESSED),
+ new TimeSpan(3, CONSTANTS.timeUnits.MIN, CONSTANTS.images.CLOCK_BUTTON, CONSTANTS.images.CLOCK_BUTTON_PRESSED),
+ new TimeSpan(5, CONSTANTS.timeUnits.MIN, CONSTANTS.images.CLOCK_BUTTON, CONSTANTS.images.CLOCK_BUTTON_PRESSED),
+ new TimeSpan(10, CONSTANTS.timeUnits.MIN, CONSTANTS.images.CLOCK_BUTTON, CONSTANTS.images.CLOCK_BUTTON_PRESSED),
+ new TimeSpan(15, CONSTANTS.timeUnits.MIN, CONSTANTS.images.CLOCK_BUTTON, CONSTANTS.images.CLOCK_BUTTON_PRESSED),
+ new TimeSpan(20, CONSTANTS.timeUnits.MIN, CONSTANTS.images.CLOCK_BUTTON, CONSTANTS.images.CLOCK_BUTTON_PRESSED)
+]
+
+SelectionPage({
+ //data
+ storageKey: CONSTANTS.session.interval,
+ columnsNumber: layout.PREDEFINED_SPAN_COLUMNS_NUMBER,
+ predefinedSpans: predefinedSpans,
+ creationPageUrl: CONSTANTS.pages.CREATE_INTERVAL.getUrl(layout.DEVICE_FAMILY),
+ nextPageUrl: CONSTANTS.pages.TIMER_PROGRESS.getUrl(layout.DEVICE_FAMILY),
+ //style
+ headerStyle: layout.HEADER_STYLE(CONSTANTS.pages.SELECT_INTERVAL.name),
+ containerStyle: layout.STANDARD_CONTAINER_WITH_BOTTOM_BUTTON_STYLE,
+ addButtonStyle: layout.BUTTONS.STANDARD_BOTTOM_BUTTON_STYLE(CONSTANTS.images.PLUS, CONSTANTS.images.PLUS_PRESSED),
+ timerButtonStyleFunction: layout.TIME_SPAN_BUTTON_STYLE_FUNCTION,
+
+ //handlers
+ creationPageRoutingFunction: replace,
+ nextPageRoutingFunction: replace,
+ selectTimerHandler: function (button) {
+ replace({url: CONSTANTS.pages.TIMER_PROGRESS.getUrl(layout.DEVICE_FAMILY)})
+ },
+ addButtonHandler: function () {
+ replace({url: CONSTANTS.pages.CREATE_INTERVAL.getUrl(layout.DEVICE_FAMILY)})
+ }
+})
diff --git a/page/devices/trex/selection_pages/select_timer.page.js b/page/devices/trex/selection_pages/select_timer.page.js
new file mode 100644
index 0000000..0247f4f
--- /dev/null
+++ b/page/devices/trex/selection_pages/select_timer.page.js
@@ -0,0 +1,47 @@
+import {push} from '@zos/router'
+
+import {TimeSpan} from '../../../data/models'
+import {CONSTANTS} from '../../../constants/constants'
+import SelectionPage from '../../../common/selection_pages/select_timer.page.template';
+import * as layout from './selection.page.layout';
+import {log as Logger} from '@zos/utils';
+
+const logger = Logger.getLogger('timerr');
+
+const predefinedSpans = [
+ new TimeSpan(30, CONSTANTS.timeUnits.SEC, CONSTANTS.images.CLOCK_BUTTON, CONSTANTS.images.CLOCK_BUTTON_PRESSED),
+ new TimeSpan(1, CONSTANTS.timeUnits.MIN, CONSTANTS.images.CLOCK_BUTTON, CONSTANTS.images.CLOCK_BUTTON_PRESSED),
+ new TimeSpan(2, CONSTANTS.timeUnits.MIN, CONSTANTS.images.CLOCK_BUTTON, CONSTANTS.images.CLOCK_BUTTON_PRESSED),
+ new TimeSpan(3, CONSTANTS.timeUnits.MIN, CONSTANTS.images.CLOCK_BUTTON, CONSTANTS.images.CLOCK_BUTTON_PRESSED),
+ new TimeSpan(5, CONSTANTS.timeUnits.MIN, CONSTANTS.images.CLOCK_BUTTON, CONSTANTS.images.CLOCK_BUTTON_PRESSED),
+ new TimeSpan(10, CONSTANTS.timeUnits.MIN, CONSTANTS.images.CLOCK_BUTTON, CONSTANTS.images.CLOCK_BUTTON_PRESSED),
+ new TimeSpan(15, CONSTANTS.timeUnits.MIN, CONSTANTS.images.CLOCK_BUTTON, CONSTANTS.images.CLOCK_BUTTON_PRESSED),
+ new TimeSpan(20, CONSTANTS.timeUnits.MIN, CONSTANTS.images.CLOCK_BUTTON, CONSTANTS.images.CLOCK_BUTTON_PRESSED),
+ new TimeSpan(30, CONSTANTS.timeUnits.MIN, CONSTANTS.images.CLOCK_BUTTON, CONSTANTS.images.CLOCK_BUTTON_PRESSED),
+ new TimeSpan(1, CONSTANTS.timeUnits.HOUR, CONSTANTS.images.CLOCK_BUTTON, CONSTANTS.images.CLOCK_BUTTON_PRESSED)
+]
+
+SelectionPage({
+ //data
+ storageKey: CONSTANTS.session.timer,
+ columnsNumber: layout.PREDEFINED_SPAN_COLUMNS_NUMBER,
+ predefinedSpans: predefinedSpans,
+ creationPageUrl: CONSTANTS.pages.CREATE_TIMER.getUrl(layout.DEVICE_FAMILY),
+ nextPageUrl: CONSTANTS.pages.SELECT_INTERVAL.getUrl(layout.DEVICE_FAMILY),
+
+ //style
+ headerStyle: layout.HEADER_STYLE(CONSTANTS.pages.SELECT_TIMER.name),
+ containerStyle: layout.STANDARD_CONTAINER_WITH_BOTTOM_BUTTON_STYLE,
+ addButtonStyle: layout.BUTTONS.STANDARD_BOTTOM_BUTTON_STYLE(CONSTANTS.images.PLUS, CONSTANTS.images.PLUS_PRESSED),
+ timerButtonStyleFunction: layout.TIME_SPAN_BUTTON_STYLE_FUNCTION,
+
+ //handlers
+ creationPageRoutingFunction: push,
+ nextPageRoutingFunction: push,
+ selectTimerHandler: function (button) {
+ push({url: CONSTANTS.pages.SELECT_INTERVAL.getUrl(layout.DEVICE_FAMILY)})
+ },
+ addButtonHandler: function () {
+ push({url: CONSTANTS.pages.CREATE_TIMER.getUrl(layout.DEVICE_FAMILY)})
+ }
+})
diff --git a/page/devices/trex/selection_pages/selection.page.layout.js b/page/devices/trex/selection_pages/selection.page.layout.js
new file mode 100644
index 0000000..284f507
--- /dev/null
+++ b/page/devices/trex/selection_pages/selection.page.layout.js
@@ -0,0 +1,27 @@
+import {px} from '@zos/utils';
+import {BUTTONS, DEVICE_FAMILY, HEADER_STYLE, STANDARD_CONTAINER_WITH_BOTTOM_BUTTON_STYLE} from '../trex.layout'
+
+const PREDEFINED_SPAN_COLUMNS_NUMBER = 2
+
+// SELECT TIMERS, INTERVALS
+const cell_size = px(200)
+const timer_size = px(170)
+const cell_padding_x = px(38)
+const cell_padding_y = px(57)
+export function TIME_SPAN_BUTTON_STYLE_FUNCTION(timer, row, column, handler) {
+ return {
+ x: column * cell_size + cell_padding_x,
+ y: row * cell_size + cell_padding_y * 2,
+ w: timer_size,
+ h: timer_size,
+ text: timer.getDisplayName(),
+ text_size: px(30),
+ normal_src: timer.img,
+ press_src: timer.imgPressed,
+ click_func: (button) => {
+ handler(button)
+ }
+ }
+}
+
+export {BUTTONS, HEADER_STYLE, PREDEFINED_SPAN_COLUMNS_NUMBER, DEVICE_FAMILY, STANDARD_CONTAINER_WITH_BOTTOM_BUTTON_STYLE}
diff --git a/page/devices/trex/timer_progress/timer_progress.page.js b/page/devices/trex/timer_progress/timer_progress.page.js
new file mode 100644
index 0000000..6102426
--- /dev/null
+++ b/page/devices/trex/timer_progress/timer_progress.page.js
@@ -0,0 +1,53 @@
+import TimerProgressPage from '../../../common/timer_progress/timer_progress.page.template'
+import * as layout from './timer_progress.page.layout';
+import {log as Logger} from '@zos/utils';
+import {CONSTANTS} from '../../../constants/constants';
+import {COLORS} from '../../../common/common.layout';
+
+const logger = Logger.getLogger('timerr');
+
+TimerProgressPage({
+ //data
+
+ //style
+ headerStyle: layout.HEADER_STYLE(CONSTANTS.pages.TIMER_PROGRESS.name),
+ remainingTimeStyleFunction: layout.REMAINING_TIME_STYLE_FUNCTION,
+ cancelButtonStyleFunction: layout.CANCEL_BUTTON_FUNCTION,
+ pauseButtonStyleFunction: layout.PAUSE_BUTTON_FUNCTION,
+ resumeButtonStyleFunction: layout.RESUME_BUTTON_FUNCTION,
+ stopButtonStyleFunction: layout.STOP_BUTTON_FUNCTION,
+ canvasLayoutStyle: layout.TIMER_PROGRESS_CIRCLE.CANVAS_LAYOUT_STYLE,
+ timerDisplayTextAccentColors: [COLORS.TEXT.TITLE, COLORS.TEXT.WARNING],
+
+ //handlers
+ createTimerProgressBarFunction: createTimerProgressCircle
+})
+
+function createTimerProgressCircle(canvas, progress) {
+ const tickWidth = layout.TIMER_PROGRESS_CIRCLE.TICKS.W
+ const tickLength = layout.TIMER_PROGRESS_CIRCLE.TICKS.H
+ const tickHalfWidth = tickWidth / 2;
+ canvas.setPaint({
+ line_width: tickWidth
+ })
+ const numTicks = layout.TIMER_PROGRESS_CIRCLE.TICKS.TOTAL
+ const radius = layout.TIMER_PROGRESS_CIRCLE.CIRCLE.RADIUS;
+ const centerX = radius + tickHalfWidth;
+ const centerY = radius + tickHalfWidth;
+ let pastTicks = Math.min(120, Math.max(0, numTicks / 100 * progress))
+ for (let i = 0; i < numTicks; i++) {
+ const angle = layout.TIMER_PROGRESS_CIRCLE.CIRCLE.TICK_ANGLE_FUNCTION(i);
+
+ let startX = centerX + (radius - tickHalfWidth) * Math.cos(angle);
+ let startY = centerY + (radius - tickHalfWidth) * Math.sin(angle);
+ let endX = centerX + (radius - tickLength) * Math.cos(angle);
+ let endY = centerY + (radius - tickLength) * Math.sin(angle);
+ canvas.drawLine({
+ x1: startX,
+ y1: startY,
+ x2: endX,
+ y2: endY,
+ color: i < pastTicks ? COLORS.SYS.HIGHLIGHT_DISABLED : COLORS.SYS.HIGHLIGHT
+ })
+ }
+}
\ No newline at end of file
diff --git a/page/devices/trex/timer_progress/timer_progress.page.layout.js b/page/devices/trex/timer_progress/timer_progress.page.layout.js
new file mode 100644
index 0000000..952bb41
--- /dev/null
+++ b/page/devices/trex/timer_progress/timer_progress.page.layout.js
@@ -0,0 +1,98 @@
+import {px} from '@zos/utils';
+import {align, text_style} from '@zos/ui'
+import {
+ BUTTONS,
+ DEVICE_FAMILY,
+ DEVICE_HEIGHT,
+ DEVICE_WIDTH,
+ HEADER_STYLE as COMMON_HEADER_STYLE,
+ STANDARD_CONTAINER_STYLE
+} from '../trex.layout'
+import {COLORS} from '../../../common/common.layout';
+import {CONSTANTS} from '../../../constants/constants';
+
+export function HEADER_STYLE(pageName) {
+ let style = COMMON_HEADER_STYLE(pageName)
+ style.y = px(style.y + 50)
+ return style
+}
+
+const timer_display_size = 70
+const circle_button_size = 116
+
+export function REMAINING_TIME_STYLE_FUNCTION(initialValue) {
+ return {
+ x: 0,
+ y: px(DEVICE_HEIGHT / 2 - timer_display_size / 2),
+ w: DEVICE_WIDTH,
+ h: timer_display_size,
+ color: COLORS.TEXT.TITLE,
+ text_size: px(60),
+ align_h: align.CENTER_H,
+ align_v: align.CENTER_V,
+ text_style: text_style.NONE,
+ text: initialValue
+ }
+}
+
+export function CANCEL_BUTTON_FUNCTION(handler) {
+ return {
+ x: px(DEVICE_WIDTH / 2 - circle_button_size - 10),
+ y: px(DEVICE_HEIGHT / 2 + 40),
+ w: circle_button_size,
+ h: circle_button_size,
+ normal_src: CONSTANTS.images.CANCEL,
+ press_src: CONSTANTS.images.CANCEL_PRESSED,
+ click_func: (button) => {
+ handler(button)
+ }
+ }
+}
+
+export function PAUSE_BUTTON_FUNCTION(handler) {
+ return {
+ x: px(DEVICE_WIDTH / 2 + 10),
+ y: px(DEVICE_HEIGHT / 2 + 40),
+ w: circle_button_size,
+ h: circle_button_size,
+ normal_src: CONSTANTS.images.PAUSE,
+ press_src: CONSTANTS.images.PAUSE_PRESSED,
+ click_func: (button) => {
+ handler(button)
+ }
+ }
+}
+
+export function RESUME_BUTTON_FUNCTION(handler) {
+ let style = PAUSE_BUTTON_FUNCTION(handler)
+ style.normal_src = CONSTANTS.images.RESUME
+ style.press_src = CONSTANTS.images.PAUSE_PRESSED
+ return style
+}
+
+export function STOP_BUTTON_FUNCTION(handler) {
+ return BUTTONS.STANDARD_BOTTOM_BUTTON_STYLE_WITH_HANDLER(CONSTANTS.images.STOP, CONSTANTS.images.STOP_PRESSED, handler)
+}
+
+const tickWidth = 4
+const tickHeight = 25
+export const TIMER_PROGRESS_CIRCLE = {
+ CANVAS_LAYOUT_STYLE: {
+ x: 0,
+ y: 0,
+ w: px(DEVICE_WIDTH),
+ h: px(DEVICE_HEIGHT)
+ },
+ TICKS: {
+ W: px(tickWidth),
+ H: px(tickHeight),
+ TOTAL: 120,
+ COLOR_ACTIVE: COLORS.SYS.HIGHLIGHT,
+ COLOR_IN_ACTIVE: COLORS.SYS.HIGHLIGHT_DISABLED
+ },
+ CIRCLE: {
+ RADIUS: (DEVICE_WIDTH - tickWidth) / 2,
+ TICK_ANGLE_FUNCTION: (i) => (-i * 3 + 90) * Math.PI / 180
+ }
+}
+export {BUTTONS, DEVICE_FAMILY, STANDARD_CONTAINER_STYLE, DEVICE_HEIGHT, DEVICE_WIDTH}
diff --git a/page/devices/trex/trex.layout.js b/page/devices/trex/trex.layout.js
new file mode 100644
index 0000000..97ba7d4
--- /dev/null
+++ b/page/devices/trex/trex.layout.js
@@ -0,0 +1,50 @@
+import {px} from '@zos/utils';
+import {BUTTONS as BUTTONS_COMMON, DEVICE_HEIGHT, DEVICE_WIDTH, PAGE_HEADERS as PAGE_HEADERS_COMMON} from '../../common/common.layout';
+
+export const DEVICE_FAMILY = 'trex'
+export const STANDARD_BUTTON_SIZE = px(88)
+
+export const STANDARD_CONTAINER_STYLE = {
+ x: 0,
+ y: 0,
+ w: DEVICE_WIDTH,
+ h: DEVICE_HEIGHT,
+ scroll_enable: 0
+}
+export const STANDARD_CONTAINER_WITH_BOTTOM_BUTTON_STYLE = {
+ x: 0,
+ y: 0,
+ w: DEVICE_WIDTH,
+ h: DEVICE_HEIGHT - STANDARD_BUTTON_SIZE,
+ scroll_enable: 1
+}
+
+export function HEADER_STYLE(pageName) {
+ let style = PAGE_HEADERS_COMMON.HEADER_STYLE(pageName)
+ style.x = DEVICE_WIDTH / 5
+ style.y = px(40)
+ style.w = DEVICE_WIDTH * 3 / 5
+ style.h = px(40)
+ style.text_size = px(35)
+ return style
+}
+
+export const BUTTONS = {
+ setSpatialParamsForBottomButton(style) {
+ style.y = DEVICE_HEIGHT - STANDARD_BUTTON_SIZE
+ style.w = DEVICE_WIDTH
+ style.h = STANDARD_BUTTON_SIZE
+ },
+ STANDARD_BOTTOM_BUTTON_STYLE(src, pressedSrc) {
+ let style = BUTTONS_COMMON.STANDARD_BOTTOM_BUTTON_STYLE(src, pressedSrc)
+ this.setSpatialParamsForBottomButton(style);
+ return style
+ },
+ STANDARD_BOTTOM_BUTTON_STYLE_WITH_HANDLER(src, pressedSrc, handler) {
+ let style = BUTTONS_COMMON.STANDARD_BOTTOM_BUTTON_STYLE_WITH_HANDLER(src, pressedSrc, handler)
+ this.setSpatialParamsForBottomButton(style);
+ return style
+ }
+}
+
+export {DEVICE_HEIGHT, DEVICE_WIDTH}
\ No newline at end of file
diff --git a/page/i18n/ru-RU.po b/page/i18n/ru-RU.po
index f41cb2f..1717299 100644
--- a/page/i18n/ru-RU.po
+++ b/page/i18n/ru-RU.po
@@ -18,7 +18,6 @@ msgstr "час"
msgid "timer_progress"
msgstr "Обратный отсчет"
-msgstr "час"
msgid "create_timer"
msgstr "Новый таймер"
diff --git a/page/select_predefined/select_interval.js b/page/select_predefined/select_interval.js
deleted file mode 100644
index e71fee0..0000000
--- a/page/select_predefined/select_interval.js
+++ /dev/null
@@ -1,31 +0,0 @@
-import {prop} from '@zos/ui'
-import {replace} from '@zos/router'
-
-import {CONSTANTS, getText, Timer, Units} from '../common'
-import SelectPredefinedTimerPage from './select_predefined_template'
-
-const standardTimers = [
- new Timer(0, Units.SEC, 0, {displayName: '-'}),
- new Timer(5, Units.SEC, 5),
- new Timer(10, Units.SEC, 10),
- new Timer(30, Units.SEC, 30),
- new Timer(1, Units.MIN, 1 * CONSTANTS.seconds.min),
- new Timer(2, Units.MIN, 2 * CONSTANTS.seconds.min),
- new Timer(3, Units.MIN, 3 * CONSTANTS.seconds.min),
- new Timer(5, Units.MIN, 5 * CONSTANTS.seconds.min),
- new Timer(10, Units.MIN, 10 * CONSTANTS.seconds.min),
- new Timer(15, Units.MIN, 15 * CONSTANTS.seconds.min),
- new Timer(20, Units.MIN, 20 * CONSTANTS.seconds.min)
-]
-
-SelectPredefinedTimerPage({
- header: getText(CONSTANTS.i18n.SELECT_INTERVAL_HEADER),
- timersList: standardTimers,
- timerHandler: function (button) {
- getApp()._options.globalData.timerModel.interval = button.getProperty(prop.DATASET).timer
- replace({url: CONSTANTS.pages.TIMER_PROGRESS})
- },
- addButtonHandler: function () {
- replace({url: CONSTANTS.pages.CREATE_INTERVAL})
- }
-})
\ No newline at end of file
diff --git a/page/select_predefined/select_predefined_template.js b/page/select_predefined/select_predefined_template.js
deleted file mode 100644
index bd1bf73..0000000
--- a/page/select_predefined/select_predefined_template.js
+++ /dev/null
@@ -1,67 +0,0 @@
-import {Vibrator, VIBRATOR_SCENE_SHORT_LIGHT} from '@zos/sensor'
-import {createWidget, event, prop, widget} from '@zos/ui'
-
-import {CONSTANTS, getText} from '../common'
-import {COMMON, SELECT_PREDEFINED} from '../style/style'
-
-function SelectPredefinedTimerPage(args) {
- const {
- header = getText(CONSTANTS.i18n.APP_NAME),
- headerStyle = COMMON.HEADER_STYLE(header),
- containerStyle = SELECT_PREDEFINED.TIMERS_CONTAINER_STYLE,
- addButtonStyle = COMMON.STANDARD_BOTTOM_BUTTON_STYLE(CONSTANTS.img.PLUS, CONSTANTS.img.PLUS_PRESSED),
- timerHandler,
- timersList,
- addButtonHandler
- } = args
-
- Page({
- onInit() {
- },
-
- build() {
- this.vibro = new Vibrator()
- const viewContainer = createWidget(widget.VIEW_CONTAINER, containerStyle)
- const header = viewContainer.createWidget(widget.TEXT, headerStyle)
- this.renderDefaultTimers(viewContainer, timersList)
- this.createAddButton()
- },
-
- onDestroy() {
- this.vibro && this.vibro.stop()
- },
-
- doVibro() {
- this.vibro.stop()
- this.vibro.setMode(VIBRATOR_SCENE_SHORT_LIGHT)
- this.vibro.start()
- },
- wrapWithVibro(fun) {
- return arg => {
- this.doVibro()
- fun(arg)
- }
- },
- renderDefaultTimers(container, timers) {
- for (let i = 0, row = 0, column = 0; i < timers.length; i++) {
- if (column === 2) {
- column = 0
- row++
- }
- let timer = timers[i]
- const timerButton = container.createWidget(widget.BUTTON,
- SELECT_PREDEFINED.TIMER_BUTTON_STYLE(timer, row, column++, this.wrapWithVibro(timerHandler)))
- timerButton.setProperty(prop.DATASET, {timer: timer})
- }
- },
- createAddButton() {
- const addButton = createWidget(widget.BUTTON, addButtonStyle)
- addButton.addEventListener(event.CLICK_DOWN, (e) => {
- this.doVibro()
- addButtonHandler()
- })
- }
- })
-}
-
-export default SelectPredefinedTimerPage
diff --git a/page/select_predefined/select_timer.js b/page/select_predefined/select_timer.js
deleted file mode 100644
index 3d663cd..0000000
--- a/page/select_predefined/select_timer.js
+++ /dev/null
@@ -1,31 +0,0 @@
-import {prop} from '@zos/ui'
-import {push} from '@zos/router'
-
-import {CONSTANTS, getText, Timer, Units} from '../common'
-import SelectPredefinedTimerPage from './select_predefined_template'
-
-const standardTimers = [
- new Timer(30, Units.SEC, 30),
- new Timer(1, Units.MIN, 1 * CONSTANTS.seconds.min),
- new Timer(2, Units.MIN, 2 * CONSTANTS.seconds.min),
- new Timer(3, Units.MIN, 3 * CONSTANTS.seconds.min),
- new Timer(5, Units.MIN, 5 * CONSTANTS.seconds.min),
- new Timer(10, Units.MIN, 10 * CONSTANTS.seconds.min),
- new Timer(15, Units.MIN, 15 * CONSTANTS.seconds.min),
- new Timer(20, Units.MIN, 20 * CONSTANTS.seconds.min),
- new Timer(30, Units.MIN, 30 * CONSTANTS.seconds.min),
- new Timer(1, Units.HOUR, 1 * CONSTANTS.seconds.hour)
-]
-
-SelectPredefinedTimerPage({
- header: getText(CONSTANTS.i18n.SELECT_TIMER_HEADER),
- timersList: standardTimers,
- timerHandler: function (button) {
- getApp()._options.globalData.timerModel.timer = button.getProperty(prop.DATASET).timer
- push({url: CONSTANTS.pages.SELECT_INTERVAL})
- },
- addButtonHandler: function () {
- push({url: CONSTANTS.pages.CREATE_TIMER})
- }
-})
-
diff --git a/page/style/style.js b/page/style/style.js
deleted file mode 100644
index 6605d8e..0000000
--- a/page/style/style.js
+++ /dev/null
@@ -1,246 +0,0 @@
-import {getDeviceInfo} from '@zos/device'
-import {align, text_style} from '@zos/ui'
-import {CONSTANTS, zeroPad} from '../common'
-
-// COMMON
-const standard_button_size = 88
-export const {width: DEVICE_WIDTH, height: DEVICE_HEIGHT} = getDeviceInfo()
-export const COLORS = {
- SYS: {
- BUTTON: 0x515151,
- BUTTON_PRESSED: 0x313131,
- BUTTON_HIGHLIGHT: 0x0986D4,
- BUTTON_HIGHLIGHT_PRESSED: 0x234F7C,
- HIGHLIGHT: 0x0986D4,
- HIGHLIGHT_DISABLED: 0x10283F,
- PAGE_BACKGROUND: 0x000000
- },
- TEXT: {
- BUTTON: 0xFFFFFF,
- LINK: 0x059AF7,
- TITLE: 0xFFFFFF,
- WARNING: 0xD14221,
- SUBTITLE: 0xB2B2B2
- },
- SECONDARY: {
- _01: 0x03B5AA,
- _02: 0x7B9E89,
- _03: 0x399E5A,
- _18: 0xAA2F2F,
- _20: 0x9B3642
- }
-}
-export const COMMON = {
- HEADER_STYLE(header) {
- return {
- x: DEVICE_WIDTH / 5,
- y: 40,
- w: DEVICE_WIDTH * 3 / 5,
- h: 40,
- color: COLORS.TEXT.TITLE,
- text_size: 35,
- align_h: align.CENTER_H,
- align_v: align.CENTER_V,
- text_style: text_style.NONE,
- text: header
- }
- },
- HEADER_STYLE_Y(header, y) {
- return {
- x: DEVICE_WIDTH / 5,
- y: y,
- w: DEVICE_WIDTH * 3 / 5,
- h: 40,
- color: COLORS.TEXT.TITLE,
- text_size: 35,
- align_h: align.CENTER_H,
- align_v: align.CENTER_V,
- text_style: text_style.NONE,
- text: header
- }
- },
- STANDARD_BOTTOM_BUTTON_STYLE(src, pressedSrc) {
- return {
- x: 0,
- y: DEVICE_HEIGHT - standard_button_size,
- w: DEVICE_WIDTH,
- h: standard_button_size,
- normal_src: src,
- press_src: pressedSrc
- }
- },
- STANDARD_BOTTOM_BUTTON_STYLE_ACTION(src, pressedSrc, handler) {
- return {
- x: 0,
- y: DEVICE_HEIGHT - standard_button_size,
- w: DEVICE_WIDTH,
- h: standard_button_size,
- normal_src: src,
- press_src: pressedSrc,
- click_func: (button) => {
- handler(button)
- }
- }
- }
-}
-
-// SELECT TIMERS, INTERVALS
-const cell_size = 200
-const timer_size = 170
-const cell_padding_x = 38
-const cell_padding_y = 57
-export const SELECT_PREDEFINED = {
- TIMER_BUTTON_STYLE(timer, row, column, handler) {
- return {
- x: column * cell_size + cell_padding_x,
- y: row * cell_size + cell_padding_y * 2,
- w: timer_size,
- h: timer_size,
- text: timer.getDisplayName(),
- text_size: 30,
- normal_src: timer.img,
- press_src: timer.img_pressed,
- click_func: (button) => {
- handler(button)
- }
- }
- },
- TIMERS_CONTAINER_STYLE: {
- x: 0,
- y: 0,
- w: DEVICE_WIDTH,
- h: DEVICE_HEIGHT - standard_button_size
- }
-}
-
-// TIMER PROGRESS
-const timer_display_size = 70
-const circle_button_size = 116
-export const TIMER_PROGRESS = {
- TIMER_DISPLAY_STYLE(initialValue) {
- return {
- x: 0,
- y: DEVICE_HEIGHT / 2 - timer_display_size / 2,
- w: DEVICE_WIDTH,
- h: timer_display_size,
- color: COLORS.TEXT.TITLE,
- text_size: 60,
- align_h: align.CENTER_H,
- align_v: align.CENTER_V,
- text_style: text_style.NONE,
- text: initialValue
- }
- },
- TIMER_PROGRESS_CIRCLE: {
- radius: 210,
- center_x: 217,
- center_y: 216,
- bars_step: 4,
- bar_width: 4,
- bar_height: 25,
- bar_color: COLORS.SYS.HIGHLIGHT,
- bar_color_processed: COLORS.SYS.HIGHLIGHT_DISABLED
- },
- CANCEL_BUTTON(handler) {
- return {
- x: DEVICE_WIDTH / 2 - circle_button_size - 10,
- y: DEVICE_HEIGHT / 2 + 40,
- w: circle_button_size,
- h: circle_button_size,
- normal_src: CONSTANTS.img.CANCEL,
- press_src: CONSTANTS.img.CANCEL_PRESSED,
- click_func: (button) => {
- handler(button)
- }
- }
- },
- PAUSE_RESUME_BUTTON(src, pressSrc, handler) {
- return {
- x: DEVICE_WIDTH / 2 + 10,
- y: DEVICE_HEIGHT / 2 + 40,
- w: circle_button_size,
- h: circle_button_size,
- normal_src: src,
- press_src: pressSrc,
- click_func: (button) => {
- handler(button)
- }
- }
- }
-}
-
-// CREATE NEW TIMER
-const create_timer_text_size = 95
-const reel_padding_y = 80
-const reel_padding_x = 60
-const reel_w = 111
-const reel_h = 265
-const gradient_h = 64
-export const CREATE_TIMER = {
- REEL_STILE(dataList, position, handler) {
- return {
- x: reel_padding_x + position * reel_w,
- y: reel_padding_y,
- w: reel_w,
- h: reel_h,
- data_array: dataList,
- data_size: dataList.length,
- item_height: 90,
- item_bg_color: COLORS.SYS.PAGE_BACKGROUND,
-
- item_text_align_v: align.CENTER_V,
- item_text_color: COLORS.SYS.HIGHLIGHT,
- item_text_size: create_timer_text_size,
- item_click_func: (list, index) => {
- handler(dataList, index)
- },
- item_focus_change_func: (list, index, isFocus) => {
- if (isFocus) {
- handler(dataList, index)
- }
- }
- }
- },
- GRADIENT_UP(position) {
- return {
- x: reel_padding_x + position * reel_w,
- y: reel_padding_y,
- w: reel_w,
- src: CONSTANTS.img.GRADIENT_BG_UP
- }
- },
- GRADIENT_BOTTOM(position) {
- return {
- x: reel_padding_x + position * reel_w,
- y: reel_padding_y + reel_h - gradient_h,
- w: reel_w,
- src: CONSTANTS.img.GRADIENT_BG_BOTTOM
- }
- },
- DISPLAY_TEXT(value, position) {
- return {
- x: reel_padding_x + position * reel_w,
- y: reel_padding_y,
- w: reel_w,
- h: reel_h,
- color: COLORS.TEXT.TITLE,
- text_size: create_timer_text_size,
- align_h: align.CENTER_H,
- align_v: align.CENTER_V,
- text: zeroPad(value)
- }
- },
- DISPLAY_TEXT_SUB(text, position) {
- return {
- x: reel_padding_x + position * reel_w,
- y: reel_padding_y + create_timer_text_size * 1.9,
- w: reel_w,
- h: 50,
- color: COLORS.TEXT.SUBTITLE,
- text_size: 30,
- align_h: align.CENTER_H,
- align_v: align.CENTER_V,
- text: text
- }
- }
-}
\ No newline at end of file
diff --git a/page/timer_progress/timer_progress.js b/page/timer_progress/timer_progress.js
deleted file mode 100644
index 91716fa..0000000
--- a/page/timer_progress/timer_progress.js
+++ /dev/null
@@ -1,219 +0,0 @@
-import {back} from '@zos/router'
-import {createWidget, deleteWidget, prop, widget} from '@zos/ui'
-import {Time, Vibrator, VIBRATOR_SCENE_DURATION_LONG, VIBRATOR_SCENE_SHORT_LIGHT, VIBRATOR_SCENE_TIMER} from '@zos/sensor'
-import {pausePalmScreenOff, resetPalmScreenOff} from '@zos/display'
-
-import {CONSTANTS, getText, zeroPad} from '../common'
-import {COLORS, COMMON, TIMER_PROGRESS} from '../style/style'
-
-const INTERVAL_MS = 200
-
-Page({
- onInit() {
- },
- build() {
- this.vibro = new Vibrator()
- this.time = new Time()
- this.processes = {
- intervals: [],
- timeouts: []
- }
- pausePalmScreenOff({
- duration: 0
- })
- this.buildUI()
- },
-
- onDestroy() {
- this.stopProcesses()
- this.vibro && this.vibro.stop()
- resetPalmScreenOff()
- },
-
- buildUI() {
- const header = createWidget(widget.TEXT, COMMON.HEADER_STYLE_Y(getText(CONSTANTS.i18n.TIMER_PROGRESS_HEADER), 70))
- this.timer = getApp()._options.globalData.timerModel.timer
- this.interval = getApp()._options.globalData.timerModel.interval
- this.timerDisplay = createWidget(widget.TEXT, TIMER_PROGRESS.TIMER_DISPLAY_STYLE(getTimerDisplayValue(this.timer.valueSeconds)))
- this.cancelButton = this.createCancelButton()
- this.pauseButton = this.createPauseButton()
- this.bars = createTimerProgressCircle()
-
- this.start = this.time.getTime()
- this.end = this.start + CONSTANTS.seconds.mili + this.timer.valueSeconds * CONSTANTS.seconds.mili
- this.startTimerProcess()
- },
-
- stopProcesses() {
- this.processes.intervals.forEach(i => clearInterval(i))
- this.processes.timeouts.forEach(t => clearTimeout(t))
- },
-
- startTimerProcess() {
- const process = setInterval(() => {
- const remainingSeconds = this.getRemainingSeconds()
- this.setDisplayValue(remainingSeconds)
- this.colorBars(remainingSeconds)
- if (remainingSeconds === 0) {
- this.stopProcesses()
- this.startBlinkInterval()
- this.createStopButton()
- this.deleteAdditionalButtons()
- this.doVibro(VIBRATOR_SCENE_TIMER)
- } else {
- this.notifyOnInterval(remainingSeconds)
- }
- }, INTERVAL_MS)
- this.processes.intervals.push(process)
- },
-
- startBlinkInterval() {
- let switcher = true
- let interval = setInterval(() => {
- this.switchTimerDisplayColor(switcher)
- switcher = !switcher
- }, 200);
- this.processes.intervals.push(interval)
- return interval
- },
-
- notifyOnInterval() {
- if (this.interval.valueSeconds > 0) {
- if (this.lastReminder) {
- const now = this.time.getTime()
- if (now - this.lastReminder >= this.interval.valueSeconds * CONSTANTS.seconds.mili) {
- this.doVibro(VIBRATOR_SCENE_DURATION_LONG)
- this.switchTimerDisplayColor(true)
- this.lastReminder = now
- } else {
- this.switchTimerDisplayColor(false)
- }
- } else {
- this.lastReminder = this.start
- }
- }
- },
-
- switchTimerDisplayColor(isWarning) {
- this.timerDisplay.setProperty(prop.MORE, {
- color: isWarning ? COLORS.TEXT.WARNING : COLORS.TEXT.TITLE
- })
- },
-
- setDisplayValue(seconds) {
- this.timerDisplay.setProperty(prop.MORE, {
- text: getTimerDisplayValue(seconds)
- })
- },
-
- colorBars(remainingSeconds) {
- const progress = Math.min(100, 100 - Math.floor(100 * remainingSeconds / this.timer.valueSeconds))
- for (let i = 0; i < progress; i++) {
- const bar = this.bars[i].bar
- const props = this.bars[i].props
- if (!props.processed) {
- bar.setProperty(prop.MORE, {
- x: props.x,
- y: props.y,
- w: props.w,
- h: props.h,
- color: TIMER_PROGRESS.TIMER_PROGRESS_CIRCLE.bar_color_processed
- })
- props.processed = true
- }
- }
- },
-
- doVibro(scene = VIBRATOR_SCENE_SHORT_LIGHT) {
- this.vibro.stop()
- this.vibro.setMode(scene)
- this.vibro.start()
- },
-
- createStopButton() {
- return createWidget(widget.BUTTON,
- COMMON.STANDARD_BOTTOM_BUTTON_STYLE_ACTION(CONSTANTS.img.STOP, CONSTANTS.img.STOP_PRESSED, (arg) => {
- back()
- }))
- },
-
- createCancelButton() {
- return createWidget(widget.BUTTON, TIMER_PROGRESS.CANCEL_BUTTON((arg) => {
- this.doVibro(VIBRATOR_SCENE_SHORT_LIGHT)
- back()
- }))
- },
-
- createPauseButton() {
- return createWidget(widget.BUTTON,
- TIMER_PROGRESS.PAUSE_RESUME_BUTTON(CONSTANTS.img.PAUSE, CONSTANTS.img.PAUSE_PRESSED, (button) => {
- this.doVibro(VIBRATOR_SCENE_SHORT_LIGHT)
- this.stopProcesses()
- this.pause = this.time.getTime()
- this.resumeButton = this.createResumeButton()
- deleteWidget(button)
- }))
- },
-
- createResumeButton() {
- return createWidget(widget.BUTTON,
- TIMER_PROGRESS.PAUSE_RESUME_BUTTON(CONSTANTS.img.RESUME, CONSTANTS.img.RESUME_PRESSED, (button) => {
- this.doVibro(VIBRATOR_SCENE_SHORT_LIGHT)
- const pauseTime = this.time.getTime() - this.pause
- this.end += pauseTime
- this.lastReminder += pauseTime
- this.startTimerProcess()
- this.pauseButton = this.createPauseButton()
- deleteWidget(button)
- }))
- },
-
- deleteAdditionalButtons() {
- deleteWidget(this.cancelButton)
- deleteWidget(this.pauseButton)
- deleteWidget(this.resumeButton)
- },
-
- getRemainingSeconds() {
- return Math.floor(Math.max(0, this.end - this.time.getTime()) / CONSTANTS.seconds.mili)
- }
-})
-
-function createTimerProgressCircle() {
- let bars = {}
- let angle = 360
-
- for (let i = 0; i < 100; i += 1) {
- if (angle === 0) {
- angle = 180
- }
- const circleProps = TIMER_PROGRESS.TIMER_PROGRESS_CIRCLE
- const x = circleProps.center_x + circleProps.radius * Math.cos((-90 - i * 3.6) * Math.PI / 180)
- const y = circleProps.center_y + circleProps.radius * Math.sin((-90 - i * 3.6) * Math.PI / 180)
- const bar = createWidget(widget.FILL_RECT, {
- x: x,
- y: y,
- w: circleProps.bar_width,
- h: circleProps.bar_height,
- color: circleProps.bar_color,
- angle: angle
- })
- bars[i] = {bar: bar, props: {x: x, y: y, w: circleProps.bar_width, h: circleProps.bar_height, processed: false}}
- angle -= 3.6
- }
- return bars
-}
-
-function getTimerDisplayValue(valueSeconds) {
- const timerHours = Math.floor(valueSeconds / CONSTANTS.seconds.hour)
- const timerMinutes = Math.floor(valueSeconds % CONSTANTS.seconds.hour / CONSTANTS.seconds.min)
- const timerSeconds = valueSeconds % CONSTANTS.seconds.min
- if (timerHours > 0) {
- return `${_00(timerHours)}:${_00(timerMinutes)}:${_00(timerSeconds)}`
- }
- return `${_00(timerMinutes)}:${_00(timerSeconds)}`
-}
-
-function _00(value) {
- return zeroPad(value, 2)
-}
\ No newline at end of file
diff --git a/readme/02_new_timer.png b/readme/02_new_timer.png
index d9ed246..0ab362d 100644
Binary files a/readme/02_new_timer.png and b/readme/02_new_timer.png differ
diff --git a/readme/04_new_interval.png b/readme/04_new_interval.png
index 90e331f..ad8aefd 100644
Binary files a/readme/04_new_interval.png and b/readme/04_new_interval.png differ
diff --git a/readme/05_countdown.png b/readme/05_countdown.png
index cacad61..35417d8 100644
Binary files a/readme/05_countdown.png and b/readme/05_countdown.png differ
diff --git a/utils/index.js b/utils/index.js
new file mode 100644
index 0000000..7edae72
--- /dev/null
+++ b/utils/index.js
@@ -0,0 +1,46 @@
+import {Vibrator, VIBRATOR_SCENE_DURATION_LONG, VIBRATOR_SCENE_SHORT_LIGHT, VIBRATOR_SCENE_TIMER} from '@zos/sensor';
+import {log as Logger} from '@zos/utils';
+
+const logger = Logger.getLogger('timerr');
+const VIBRO = new Vibrator()
+
+export function assets(type) {
+ return (path) => type + '/' + path;
+}
+
+export function doShortVibro() {
+ logger.debug('* * * * short vibro * * * *')
+ VIBRO.stop()
+ VIBRO.setMode(VIBRATOR_SCENE_DURATION_LONG)
+ VIBRO.start(VIBRATOR_SCENE_DURATION_LONG)
+}
+
+export function doLongVibro() {
+ logger.debug('* * * * long vibro * * * *')
+ VIBRO.stop()
+ VIBRO.setMode(VIBRATOR_SCENE_SHORT_LIGHT)
+ VIBRO.start(VIBRATOR_SCENE_SHORT_LIGHT)
+}
+
+export function startVibration() {
+ logger.debug('* * * * endless vibro * * * *')
+ VIBRO.stop()
+ VIBRO.setMode(VIBRATOR_SCENE_TIMER)
+ VIBRO.start(VIBRATOR_SCENE_TIMER)
+}
+
+export function stopVibration() {
+ logger.debug('- - - - stop vibro - - - -')
+ VIBRO.stop()
+}
+
+export function vibroCallback(callback) {
+ return arg => {
+ doShortVibro()
+ callback(arg)
+ }
+}
+
+export function formatNumberForPicker(number, places = 2) {
+ return String(number).padStart(places, '0')
+}
\ No newline at end of file