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