From e8ed1c0f79f97cab1577ecbbbc8e70ce93cf2adc Mon Sep 17 00:00:00 2001 From: Emily Barkley <149705329+EsBarkley@users.noreply.github.com> Date: Tue, 19 Nov 2024 23:35:37 -0700 Subject: [PATCH 01/28] Update app.json added a page path --- app/app.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/app.json b/app/app.json index f9fef8a..760e4e6 100644 --- a/app/app.json +++ b/app/app.json @@ -32,7 +32,10 @@ "default": { "module": { "page": { - "pages": ["page/index"] + "pages": [ + "page/index", + "page/permissionsPage" + ] }, "app-side": { "path": "app-side/index" From f5bcaab559363362f556eaa61c9d1d3aa0664606 Mon Sep 17 00:00:00 2001 From: Emily Barkley <149705329+EsBarkley@users.noreply.github.com> Date: Tue, 19 Nov 2024 23:36:35 -0700 Subject: [PATCH 02/28] Update index.js Updated the index to account for permissions and permission transfers --- app/page/index.js | 177 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 162 insertions(+), 15 deletions(-) diff --git a/app/page/index.js b/app/page/index.js index e22f982..d8fa8ac 100644 --- a/app/page/index.js +++ b/app/page/index.js @@ -1,21 +1,68 @@ -import { BasePage } from "@zeppos/zml/base-page"; +import { BasePage } from '@zeppos/zml/base-page'; import * as appService from "@zos/app-service"; import { queryPermission, requestPermission } from "@zos/app"; -import hmUI from "@zos/ui"; -import { START_BUTTON } from "zosLoader:./index.[pf].layout.js"; -import { STOP_BUTTON } from "./index.r.layout"; +import hmUI from '@zos/ui'; +import { push } from '@zos/router'; +import { Sleep } from '@zos/sensor'; // Import the Sleep module +import { START_BUTTON, SLEEP_BUTTON, PERMISSIONS_BUTTON, STOP_BUTTON } from 'zosLoader:./index.[pf].layout.js'; const permissions = ["device:os.bg_service"]; const service = "app-service/service"; const storage = getApp()._options.globalData.storage; +// Initialize the Sleep module +const sleep = new Sleep(); + +// Main page setup Page( BasePage({ state: { temp: null, + permissions: {}, }, - onInit() { - console.log("page onInit invoked"); + onInit(params) { + console.log("Index Page onInit invoked"); + + // Log the entire params object to see the received data + console.log("Received params:", params); + + // Check if params is a string and parse it as JSON + if (typeof params === 'string') { + try { + params = JSON.parse(params); // Convert string to object + console.log("Parsed params:", params); + } catch (error) { + console.error("Error parsing params:", error); + return; + } + } + + // Ensure params is an object with keys + if (params && typeof params === 'object' && Object.keys(params).length > 1) { + // Iterate through specific keys and store their values in state + const permissionKeys = [ + "sleepScore", "startEndTime", "deepSleepTime", + "totalSleepTime", "wakeStage", "remStage", + "lightStage", "deepStage" + ]; + + let permissions = {}; // Local object to store permissions + + permissionKeys.forEach(key => { + if (params.hasOwnProperty(key)) { + permissions[key] = params[key]; + console.log(`Permission: ${key}, Value: ${params[key]}`); + } + }); + + // Store the permissions in state + this.state.permissions = permissions; + console.log("Stored permissions:", this.state.permissions); + } else { + console.log("No permission data received or invalid format."); + } + + // Get token and store it in storage this.request({ method: "GET_TOKEN" }).then(res => { @@ -34,7 +81,7 @@ Page( build() { hmUI.createWidget(hmUI.widget.BUTTON, { ...START_BUTTON, - click_func: () => { + click_func: async () => { console.log("fetch button clicked"); const token = storage.getKey("token"); if (!token) { @@ -49,7 +96,7 @@ Page( if (checkPermissions()) { startAppService(token); } else { - console.log("permission denied"); + console.log("Permission denied"); } }, }); @@ -69,6 +116,21 @@ Page( }); }, }); + + hmUI.createWidget(hmUI.widget.BUTTON, { + ...SLEEP_BUTTON, + click_func: this.onClickSleepButton.bind(this) + }); + + hmUI.createWidget(hmUI.widget.BUTTON, { + ...PERMISSIONS_BUTTON, + click_func: () => { + console.log('Permissions button clicked'); + push({ + url: "page/permissionsPage", // No parameters passed here + }); + } + }); }, onDestroy() { @@ -91,10 +153,94 @@ Page( }); storage.setKey("token", req.params.value); } - } + }, + + onClickSleepButton() { + console.log('Sleep button pressed'); + + // Log the current state and permissions to see what data is available + console.log('Current state:', JSON.stringify(this.state)); + + // Access permissions from the state + if (this.state.permissions) { + Object.entries(this.state.permissions).forEach(([key, value]) => { + if (value === true) { + console.log(`Permission for ${key} is granted.`); + + // Actual data extraction based on the granted permission + switch (key) { + case "sleepScore": + // Get the sleep score using the `getInfo` method + this.getSleepInfo("score"); + break; + case "startEndTime": + // Get the start and end times (assuming `getInfo` provides this) + this.getSleepInfo("startTime"); + this.getSleepInfo("endTime"); + break; + case "deepSleepTime": + // Get the deep sleep time using `getInfo` + this.getSleepInfo("deepTime"); + break; + case "totalSleepTime": + // Get the total sleep time using `getInfo` + this.getSleepInfo("totalTime"); + break; + case "wakeStage": + // Get the wake stage using `getStageConstantObj` + this.getStageConstantObj("WAKE_STAGE"); + break; + case "remStage": + // Get the REM stage using `getStageConstantObj` + this.getStageConstantObj("REM_STAGE"); + break; + case "lightStage": + // Get the light sleep stage using `getStageConstantObj` + this.getStageConstantObj("LIGHT_STAGE"); + break; + case "deepStage": + // Get the deep sleep stage using `getStageConstantObj` + this.getStageConstantObj("DEEP_STAGE"); + break; + default: + console.log(`No action defined for permission: ${key}`); + } + } else { + console.log(`Permission for ${key} is denied.`); + } + }); + } else { + console.log("No permissions found in state."); + } + }, + + // Extract sleep info (getInfo method) + getSleepInfo(infoKey) { + // Using the ZeppOS Sleep module to fetch the sleep info + const info = sleep.getInfo(); + + if (info && info.hasOwnProperty(infoKey)) { + console.log(`${infoKey}: ${info[infoKey]}`); + } else { + console.log(`No data for ${infoKey}`); + } + }, + + // Extract stage constant + getStageConstantObj(stageKey) { + // Using the ZeppOS Sleep module to fetch stage constants + const sleepStageConstants = sleep.getStageConstantObj(); + + if (sleepStageConstants && sleepStageConstants.hasOwnProperty(stageKey)) { + console.log(`${stageKey}: ${sleepStageConstants[stageKey]}`); + } else { + console.log(`No data for ${stageKey}`); + } + }, }) ); +// Service-related functions const startAppService = (token) => { console.log("startAppService invoked"); console.log(`starting service: ${service}`); @@ -109,13 +255,14 @@ const startAppService = (token) => { }); }; -const checkPermissions = () => { - const [permissionResult] = queryPermission({ - permissions, - }); +// Asynchronous permission check +const checkPermissions = async () => { + // Query for permissions first + const [permissionResult] = queryPermission({ permissions }); + if (permissionResult === 2) { - console.log("permission previously allowed"); - return true; + console.log("Permission previously allowed"); + return true; // Permission granted } else { requestPermission({ permissions, From 9cfb44c0c1278a9c7ae22307af26486cef5117a3 Mon Sep 17 00:00:00 2001 From: Emily Barkley <149705329+EsBarkley@users.noreply.github.com> Date: Tue, 19 Nov 2024 23:37:43 -0700 Subject: [PATCH 03/28] Update index.r.layout.js Added the additional permission button --- app/page/index.r.layout.js | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/app/page/index.r.layout.js b/app/page/index.r.layout.js index 2612567..ae4da43 100644 --- a/app/page/index.r.layout.js +++ b/app/page/index.r.layout.js @@ -3,7 +3,7 @@ import { BUTTON_TEXT, BUTTON_TEXT_STOP, NORMAL_COLOR, PRESS_COLOR } from "../uti export const START_BUTTON = { x: px(60), - y: px(200), + y: px(300), w: px(360), h: px(80), text_size: px(36), @@ -13,6 +13,7 @@ export const START_BUTTON = { text: BUTTON_TEXT }; + export const STOP_BUTTON = { x: px(60), y: px(300), @@ -24,3 +25,27 @@ export const STOP_BUTTON = { press_color: PRESS_COLOR, text: BUTTON_TEXT_STOP }; + +export const SLEEP_BUTTON = { + x: px(50), + y: px(225), + w: px(200), + h: px(50), + text_size: px(25), + radius: px(12), + normal_color: 0xaa42ee, + press_color: 0xb964f0, + text: "Sleep Data" +}; + +export const PERMISSIONS_BUTTON = { + x: px(75), + y: px(100), + w: px(225), + h: px(50), + text_size: px(25), + radius: px(12), + normal_color: 0x0352fc, + press_color: 0x487ff7, + text: "Permission Data" +}; From bd28f327d42b102503d0e900fa901a6c73220142 Mon Sep 17 00:00:00 2001 From: Emily Barkley <149705329+EsBarkley@users.noreply.github.com> Date: Tue, 19 Nov 2024 23:38:38 -0700 Subject: [PATCH 04/28] Add files via upload Added the permissionsPage and the permissionsPage's layout file --- app/page/permissionsPage.js | 133 +++++++++++++++++++++++++++ app/page/permissionsPage.r.layout.js | 81 ++++++++++++++++ 2 files changed, 214 insertions(+) create mode 100644 app/page/permissionsPage.js create mode 100644 app/page/permissionsPage.r.layout.js diff --git a/app/page/permissionsPage.js b/app/page/permissionsPage.js new file mode 100644 index 0000000..9c06a2d --- /dev/null +++ b/app/page/permissionsPage.js @@ -0,0 +1,133 @@ +import hmUI from '@zos/ui'; +import { push } from '@zos/router'; +import { TOGGLE_OPTIONS, BACK_BUTTON } from 'zosLoader:./permissionsPage.[pf].layout.js'; +import { LocalStorage } from '@zos/storage'; // Import LocalStorage only once + +console.log("Navigated to the permissions page"); + +Page({ + state: { + message: "Permissions Page", + sleepScore: true, + startEndTime: true, + deepSleepTime: true, + totalSleepTime: true, + wakeStage: true, + remStage: true, + lightStage: true, + deepStage: true, + }, + + onInit() { + console.log("Permissions Page onInit invoked"); + this.localStorage = new LocalStorage(); // Initialize LocalStorage once + this.restoreToggleStates(); // Restore saved states when the page is initialized + }, + + build() { + console.log("Permissions Page Build Called"); + + // Display the main title + hmUI.createWidget(hmUI.widget.TEXT, { + text: this.state.message, + x: 100, + y: 20, + w: 200, + h: 50, + text_size: 24, + color: 0xFFFFFF, + align_h: hmUI.align.CENTER_H + }); + + // Create toggle switches with their corresponding names + TOGGLE_OPTIONS.forEach((option, index) => { + const checkedValue = this.state[option.key] !== undefined ? this.state[option.key] : true; + + // Create the switch widget for each option + hmUI.createWidget(hmUI.widget.SLIDE_SWITCH, { + x: option.x + 100, // Position the toggle switch slightly to the right + y: option.y, + w: option.w, + h: option.h, + checked: checkedValue, + color: 0xFFFFFF, // Text color for better visibility + text_size: px(16), // Smaller text size + checked_change_func: (slideSwitch, checked) => { + // Handle toggle change + this.handleToggleChange(option.key, checked); // Call the function for toggle change + } + }); + + // Create the label (name) for each toggle switch next to it + hmUI.createWidget(hmUI.widget.TEXT, { + text: option.label, + x: option.x, // Position the label next to the toggle + y: option.y + 5, // Adjust the Y position slightly to match the center of the toggle + w: px(100), // Adjust the width for the label + h: option.h, // Keep the same height as the toggle + text_size: px(16), // Smaller text size for the label + color: 0xFFFFFF, // Text color for better visibility + align_h: hmUI.align.LEFT, // Align the text to the left + }); + + console.log(`Created toggle widget and label for: ${option.label}`); + }); + + // Add the back button at the bottom of the page + hmUI.createWidget(hmUI.widget.BUTTON, { + ...BACK_BUTTON, + y: 500, // Adjust Y position for the back button + click_func: () => { + console.log("Back button clicked, preferences saved:"); + + // Log all the permissions and their state + TOGGLE_OPTIONS.forEach(option => { + const permissionState = this.state[option.key]; + console.log(`${option.label}: ${permissionState}`); + }); + + // Save permissions to localStorage + this.localStorage.setItem('userPermissions', JSON.stringify(this.state)); // Store the entire state + + // Log the params being passed to index.js + const paramsToPass = JSON.stringify(this.state); + console.log("Passing the following parameters to index.js: ", paramsToPass); + + // Pass the entire state through params when navigating to index.js + push({ + url: "page/index", + params: paramsToPass, // Pass the state as params + }); + }, + }); + }, + + onDestroy() { + console.log("Permissions Page onDestroy invoked"); + }, + + // Function to handle toggle change and save the state to localStorage + handleToggleChange(toggleId, isChecked) { + // Update the state when the switch is toggled + this.state[toggleId] = isChecked; + console.log(`${toggleId} tracking set to ${isChecked}`); + + // Store updated state to localStorage + this.localStorage.setItem(toggleId, isChecked.toString()); // Store state as a string + }, + + // Function to restore the toggle states from localStorage + restoreToggleStates() { + TOGGLE_OPTIONS.forEach(option => { + const toggleId = option.key; + + // Retrieve saved state from localStorage + const storedState = this.localStorage.getItem(toggleId); + if (storedState !== null) { + this.state[toggleId] = storedState === 'true'; // Convert string to boolean + } + + console.log(`Restored ${toggleId} state: ${this.state[toggleId]}`); + }); + } +}); diff --git a/app/page/permissionsPage.r.layout.js b/app/page/permissionsPage.r.layout.js new file mode 100644 index 0000000..bb3985b --- /dev/null +++ b/app/page/permissionsPage.r.layout.js @@ -0,0 +1,81 @@ +import { px } from "@zos/utils"; +import { BUTTON_TEXT, NORMAL_COLOR, PRESS_COLOR } from "../utils/constants"; + +export const TOGGLE_OPTIONS = [ + { + label: "Sleep Score", + key: "sleepScore", + x: px(100), + y: px(80), + w: px(200), + h: px(40), + }, + { + label: "Start & End Time", + key: "startEndTime", + x: px(100), + y: px(130), + w: px(200), + h: px(40), + }, + { + label: "Deep Sleep Time", + key: "deepSleepTime", + x: px(100), + y: px(180), + w: px(200), + h: px(40), + }, + { + label: "Total Sleep Time", + key: "totalSleepTime", + x: px(100), + y: px(230), + w: px(200), + h: px(40), + }, + { + label: "Wake Stage", + key: "wakeStage", + x: px(100), + y: px(280), + w: px(200), + h: px(40), + }, + { + label: "REM Stage", + key: "remStage", + x: px(100), + y: px(330), + w: px(200), + h: px(40), + }, + { + label: "Light Stage", + key: "lightStage", + x: px(100), + y: px(380), + w: px(200), + h: px(40), + }, + { + label: "Deep Stage", + key: "deepStage", + x: px(100), + y: px(430), + w: px(200), + h: px(40), + }, +]; + +export const BACK_BUTTON = { + x: px(150), + y: px(325), + w: px(200), + h: px(50), + text_size: px(25), + radius: px(12), + normal_color: NORMAL_COLOR, + press_color: PRESS_COLOR, + text: "Go Back" +}; From 32d839b08ad4569d45cde00fec2876b3dc1a93dc Mon Sep 17 00:00:00 2001 From: Emily Barkley <149705329+EsBarkley@users.noreply.github.com> Date: Sun, 24 Nov 2024 16:09:03 -0700 Subject: [PATCH 05/28] Update index.r.layout.js Changed the coordinates for the stop button --- app/page/index.r.layout.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/app/page/index.r.layout.js b/app/page/index.r.layout.js index ae4da43..62a6e15 100644 --- a/app/page/index.r.layout.js +++ b/app/page/index.r.layout.js @@ -1,16 +1,16 @@ import { px } from "@zos/utils"; import { BUTTON_TEXT, BUTTON_TEXT_STOP, NORMAL_COLOR, PRESS_COLOR } from "../utils/constants"; -export const START_BUTTON = { - x: px(60), - y: px(300), - w: px(360), - h: px(80), - text_size: px(36), +export const STOP_BUTTON = { + x: px(260), + y: px(175), + w: px(250), + h: px(60), + text_size: px(30), radius: px(12), normal_color: NORMAL_COLOR, press_color: PRESS_COLOR, - text: BUTTON_TEXT + text: BUTTON_TEXT_STOP }; From 375ff150eed2e7feb5ed1aa1dd17141b83ab2ffe Mon Sep 17 00:00:00 2001 From: Emil Date: Tue, 26 Nov 2024 03:08:41 -0700 Subject: [PATCH 06/28] Fix Prettier formatting --- app/app-service/google-api.js | 231 +++++++++++----------- app/app-service/service.js | 108 ++++++----- app/app-side/index.js | 30 +-- app/app.js | 10 +- app/app.json | 3 +- app/google-api-constants.example.js | 4 - app/page/index.js | 101 ++++++---- app/page/index.r.layout.js | 28 ++- app/page/permissionsPage.js | 276 ++++++++++++++------------- app/page/permissionsPage.r.layout.js | 162 ++++++++-------- app/page/rescuePlanPage.js | 143 ++++++++++++++ app/setting/index.js | 206 ++++++++++---------- app/utils/constants.js | 2 +- 13 files changed, 759 insertions(+), 545 deletions(-) delete mode 100644 app/google-api-constants.example.js create mode 100644 app/page/rescuePlanPage.js diff --git a/app/app-service/google-api.js b/app/app-service/google-api.js index 6588f77..64fe432 100644 --- a/app/app-service/google-api.js +++ b/app/app-service/google-api.js @@ -1,143 +1,152 @@ -import { GOOGLE_API_CLIENT_ID, GOOGLE_API_CLIENT_SECRET, GOOGLE_API_REDIRECT_URI } from "../google-api-constants"; +import { + GOOGLE_API_CLIENT_ID, + GOOGLE_API_CLIENT_SECRET, + GOOGLE_API_REDIRECT_URI, +} from "../google-api-constants"; /** - * Request Google Auth Data from Google API after receiving auth code + * Request Google Auth Data from Google API after receiving auth code * @param authResponse the auth code from Google API * @returns access token and other data for using API */ export const requestGoogleAuthData = async (authResponse) => { - const params = { - grant_type: 'authorization_code', - client_id: GOOGLE_API_CLIENT_ID, - client_secret: GOOGLE_API_CLIENT_SECRET, - redirect_uri: GOOGLE_API_REDIRECT_URI, - code: authResponse.code - }; + const params = { + grant_type: "authorization_code", + client_id: GOOGLE_API_CLIENT_ID, + client_secret: GOOGLE_API_CLIENT_SECRET, + redirect_uri: GOOGLE_API_REDIRECT_URI, + code: authResponse.code, + }; - const body = Object.keys(params) - .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`) - .join('&'); + const body = Object.keys(params) + .map( + (key) => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`, + ) + .join("&"); - // console.log(body) - const data = await fetch('https://oauth2.googleapis.com/token', { - method: 'POST', - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - }, - body: body, - }) - return await data.json(); -} + // console.log(body) + const data = await fetch("https://oauth2.googleapis.com/token", { + method: "POST", + headers: { + "Content-Type": "application/x-www-form-urlencoded", + }, + body: body, + }); + return await data.json(); +}; /** * Public-facing function to send data to Google Sheets - * + * * @param {*} accessToken access token from Google API * @param {*} data data to send to Google Sheets, as an object */ export const sendDataToGoogleSheets = (svc, accessToken, data) => { - // Format the data into headers and values + // Format the data into headers and values - // TODO: headers should be decided in internal function too - // i.e. only add headers if creating new file (not appending to an existing one) - const headers = [ - 'Record Time', - 'Last Heart Rate', - 'Resting Heart Rate', - // Daily Heart Rate broken down - 'Daily Heart Rate Maximum', - 'Daily Heart Rate Time', - 'Daily Heart Rate Time Zone', - 'Daily Heart Rate Value', - // Sleep Info broken down - 'Sleep Score', - 'Sleep Start Time', - 'Sleep End Time', - 'Sleep Deep Time', - 'Sleep Total Time', - // Sleep Stages broken down - 'Sleep Wake Stage', - 'Sleep REM Stage', - 'Sleep Light Stage', - 'Sleep Deep Stage', - ]; + // TODO: headers should be decided in internal function too + // i.e. only add headers if creating new file (not appending to an existing one) + const headers = [ + "Record Time", + "Last Heart Rate", + "Resting Heart Rate", + // Daily Heart Rate broken down + "Daily Heart Rate Maximum", + "Daily Heart Rate Time", + "Daily Heart Rate Time Zone", + "Daily Heart Rate Value", + // Sleep Info broken down + "Sleep Score", + "Sleep Start Time", + "Sleep End Time", + "Sleep Deep Time", + "Sleep Total Time", + // Sleep Stages broken down + "Sleep Wake Stage", + "Sleep REM Stage", + "Sleep Light Stage", + "Sleep Deep Stage", + ]; - // Parse the more complex objects - const heartRateSummary = data.heartRateSummary || {}; - const sleepInfo = data.sleepInfo || {}; - const sleepStages = data.sleepStageList || {}; + // Parse the more complex objects + const heartRateSummary = data.heartRateSummary || {}; + const sleepInfo = data.sleepInfo || {}; + const sleepStages = data.sleepStageList || {}; - const dataRow = [ - new Date(data.recordTime * 1000).toISOString(), - data.heartRateLast, - data.heartRateResting, - // Daily Heart Rate data - heartRateSummary.maximum?.maximum || 0, - heartRateSummary.maximum?.time || 0, - heartRateSummary.maximum?.time_zone || 0, - heartRateSummary.maximum?.hr_value || 0, - // Sleep Info data - sleepInfo.score || 0, - sleepInfo.startTime || 0, - sleepInfo.endTime || -1, - sleepInfo.deepTime || 0, - sleepInfo.totalTime || 0, - // Sleep Stages data - sleepStages.WAKE_STAGE || 0, - sleepStages.REM_STAGE || 0, - sleepStages.LIGHT_STAGE || 0, - sleepStages.DEEP_STAGE || 0, - ]; + const dataRow = [ + new Date(data.recordTime * 1000).toISOString(), + data.heartRateLast, + data.heartRateResting, + // Daily Heart Rate data + heartRateSummary.maximum?.maximum || 0, + heartRateSummary.maximum?.time || 0, + heartRateSummary.maximum?.time_zone || 0, + heartRateSummary.maximum?.hr_value || 0, + // Sleep Info data + sleepInfo.score || 0, + sleepInfo.startTime || 0, + sleepInfo.endTime || -1, + sleepInfo.deepTime || 0, + sleepInfo.totalTime || 0, + // Sleep Stages data + sleepStages.WAKE_STAGE || 0, + sleepStages.REM_STAGE || 0, + sleepStages.LIGHT_STAGE || 0, + sleepStages.DEEP_STAGE || 0, + ]; - // Combine headers and data - const formattedData = [headers, dataRow]; + // Combine headers and data + const formattedData = [headers, dataRow]; - return internalSendDataToGoogleSheets( - svc, - accessToken, - formattedData, - ).then(({ status, body }) => { - if (status == 200 && body?.updatedCells > 0) { - console.log('Successfully wrote to Google Sheets:', body); - return { message: `Successfully wrote ${body.updatedCells} cells.` }; - } - return Promise.reject({ message: 'Failed to write to Google Sheets', error: body }); - }) -} + return internalSendDataToGoogleSheets(svc, accessToken, formattedData).then( + ({ status, body }) => { + if (status == 200 && body?.updatedCells > 0) { + console.log("Successfully wrote to Google Sheets:", body); + return { message: `Successfully wrote ${body.updatedCells} cells.` }; + } + return Promise.reject({ + message: "Failed to write to Google Sheets", + error: body, + }); + }, + ); +}; /** * Internal function to send data to Google Sheets * Do not use directly * @param {*} accessToken access token from Google API * @param {*} values the data to send - * @returns + * @returns */ const internalSendDataToGoogleSheets = (svc, accessToken, values) => { - // TODO: spreadsheetId, location, isColumn should be decided in this function (probably not passed in) - // append vs new sheet - const spreadsheetId = '1e40yZOhM5_Wd5IQkwVJpPh23pohGgRiN3Ayp4fxYtzU'; // Replace with actual spreadsheet ID - const range = 'Sheet1!A1'; // specify cell A1 + // TODO: spreadsheetId, location, isColumn should be decided in this function (probably not passed in) + // append vs new sheet + const spreadsheetId = "1e40yZOhM5_Wd5IQkwVJpPh23pohGgRiN3Ayp4fxYtzU"; // Replace with actual spreadsheet ID + const range = "Sheet1!A1"; // specify cell A1 - const body = { - range, - values, - majorDimension: 'ROWS', - }; + const body = { + range, + values, + majorDimension: "ROWS", + }; - const url = `https://sheets.googleapis.com/v4/spreadsheets/${spreadsheetId}/values/${range}?valueInputOption=RAW`; - // const url = `https://sheets.googleapis.com/v4/spreadsheets/${spreadsheetId}/values/${range}:append?valueInputOption=RAW&insertDataOption=INSERT_ROWS`; - return svc.httpRequest({ - method: 'PUT', - url, - body: JSON.stringify(body), - headers: { - 'Authorization': `Bearer ${accessToken}`, - 'Content-Type': 'application/json', - } - }).then(({ status, statusText, headers, body }) => { - if (typeof body === 'string') { - body = JSON.parse(body); - } - return { status, body }; + const url = `https://sheets.googleapis.com/v4/spreadsheets/${spreadsheetId}/values/${range}?valueInputOption=RAW`; + // const url = `https://sheets.googleapis.com/v4/spreadsheets/${spreadsheetId}/values/${range}:append?valueInputOption=RAW&insertDataOption=INSERT_ROWS`; + return svc + .httpRequest({ + method: "PUT", + url, + body: JSON.stringify(body), + headers: { + Authorization: `Bearer ${accessToken}`, + "Content-Type": "application/json", + }, }) + .then(({ status, statusText, headers, body }) => { + if (typeof body === "string") { + body = JSON.parse(body); + } + return { status, body }; + }); }; diff --git a/app/app-service/service.js b/app/app-service/service.js index 2b3a8d7..5d67ec7 100644 --- a/app/app-service/service.js +++ b/app/app-service/service.js @@ -1,9 +1,9 @@ import * as notificationMgr from "@zos/notification"; -import { Time } from '@zos/sensor'; +import { Time } from "@zos/sensor"; import { BasePage } from "@zeppos/zml/base-page"; import { HeartRate, Sleep } from "@zos/sensor"; -import { getProfile } from '@zos/user'; -import { getDeviceInfo } from '@zos/device'; +import { getProfile } from "@zos/user"; +import { getDeviceInfo } from "@zos/device"; import { sendDataToGoogleSheets } from "./google-api"; const timeSensor = new Time(); @@ -11,59 +11,61 @@ const storage = getApp()._options.globalData.storage; const debug = true; AppService( - BasePage({ - onInit() { - const token = storage.getKey('token'); - this.log('token', token); - notifyWatch(`Token: ${token}`); - timeSensor.onPerMinute(() => { - this.log( - `Time report: ${timeSensor.getHours()}:${timeSensor.getMinutes().toString().padStart(2, '0')}:${timeSensor.getSeconds().toString().padStart(2, '0')}` - ) + BasePage({ + onInit() { + const token = storage.getKey("token"); + this.log("token", token); + notifyWatch(`Token: ${token}`); + timeSensor.onPerMinute(() => { + this.log( + `Time report: ${timeSensor.getHours()}:${timeSensor.getMinutes().toString().padStart(2, "0")}:${timeSensor.getSeconds().toString().padStart(2, "0")}`, + ); - sendDataToGoogleSheets(this, token, this.getMetrics()).then(res => { - this.log('Successfully wrote to Google Sheets', res.message); - notifyWatch(res.message); - }).catch(error => { - this.log('Failed to write to Google Sheets', error.message); - notifyWatch(`Failed to write to Google Sheets: ${error.message}`); - }); - }); - }, - getMetrics() { - const deviceInfo = getDeviceInfo(); - const heartRate = new HeartRate(); - const sleep = new Sleep(); + sendDataToGoogleSheets(this, token, this.getMetrics()) + .then((res) => { + this.log("Successfully wrote to Google Sheets", res.message); + notifyWatch(res.message); + }) + .catch((error) => { + this.log("Failed to write to Google Sheets", error.message); + notifyWatch(`Failed to write to Google Sheets: ${error.message}`); + }); + }); + }, + getMetrics() { + const deviceInfo = getDeviceInfo(); + const heartRate = new HeartRate(); + const sleep = new Sleep(); - sleep.updateInfo(); + sleep.updateInfo(); - return { - recordTime: Math.floor(new Date().getTime() / 1000), - user: getProfile(), - device: deviceInfo, - heartRateLast: heartRate.getLast(), - heartRateResting: heartRate.getResting(), - heartRateSummary: heartRate.getDailySummary(), - sleepInfo: sleep.getInfo(), - sleepStageList: sleep.getStageConstantObj(), - sleepStatus: sleep.getSleepingStatus(), - }; - }, - onRun() { - this.log('app side service onRun'); - }, - onDestroy() { - this.log('app side service onDestroy'); - }, - }) + return { + recordTime: Math.floor(new Date().getTime() / 1000), + user: getProfile(), + device: deviceInfo, + heartRateLast: heartRate.getLast(), + heartRateResting: heartRate.getResting(), + heartRateSummary: heartRate.getDailySummary(), + sleepInfo: sleep.getInfo(), + sleepStageList: sleep.getStageConstantObj(), + sleepStatus: sleep.getSleepingStatus(), + }; + }, + onRun() { + this.log("app side service onRun"); + }, + onDestroy() { + this.log("app side service onDestroy"); + }, + }), ); const notifyWatch = (content) => { - if (debug) { - notificationMgr.notify({ - title: 'MyAlyce', - content, - actions: [] - }); - } -} \ No newline at end of file + if (debug) { + notificationMgr.notify({ + title: "MyAlyce", + content, + actions: [], + }); + } +}; diff --git a/app/app-side/index.js b/app/app-side/index.js index c15c961..724c99b 100644 --- a/app/app-side/index.js +++ b/app/app-side/index.js @@ -3,19 +3,21 @@ import { BaseSideService, settingsLib } from "@zeppos/zml/base-side"; AppSideService( BaseSideService({ onInit() { - console.log('app side service invoke onInit'); + console.log("app side service invoke onInit"); }, - onRun() { }, + onRun() {}, - onDestroy() { }, + onDestroy() {}, onRequest(req, res) { - console.log(`Method ==> ${req.method}`) + console.log(`Method ==> ${req.method}`); if (req.method === "POST_TO_GOOGLE") { - console.log('req.body', req.body) + console.log("req.body", req.body); } else if (req.method === "GET_TOKEN") { - const token = settingsLib.getItem('googleAuthData') ? JSON.parse(settingsLib.getItem('googleAuthData')).access_token : undefined; + const token = settingsLib.getItem("googleAuthData") + ? JSON.parse(settingsLib.getItem("googleAuthData")).access_token + : undefined; if (token) { res(null, token); } else { @@ -24,18 +26,18 @@ AppSideService( } }, onSettingsChange({ key, newValue, oldValue }) { - console.log('onSettingsChange', key, newValue, oldValue); + console.log("onSettingsChange", key, newValue, oldValue); console.log(settingsLib.getAll()); - if (key === 'googleAuthData') { - console.log('googleAuthData changed'); + if (key === "googleAuthData") { + console.log("googleAuthData changed"); this.call({ method: "SET_TOKEN", params: { - key: 'googleAuthData', - value: JSON.parse(newValue).access_token - } - }) + key: "googleAuthData", + value: JSON.parse(newValue).access_token, + }, + }); } }, }), -) +); diff --git a/app/app.js b/app/app.js index 4e30eaa..0db7163 100644 --- a/app/app.js +++ b/app/app.js @@ -1,4 +1,4 @@ -import { BaseApp } from '@zeppos/zml/base-app' +import { BaseApp } from "@zeppos/zml/base-app"; import EasyStorage from "@silver-zepp/easy-storage"; const storage = new EasyStorage(); @@ -6,13 +6,13 @@ const storage = new EasyStorage(); App( BaseApp({ globalData: { - storage: storage + storage: storage, }, onCreate() { - console.log('app invoke onCreate') + console.log("app invoke onCreate"); }, onDestroy(opts) { - console.log('app invoke onDestroy') + console.log("app invoke onDestroy"); }, }), -) \ No newline at end of file +); diff --git a/app/app.json b/app/app.json index 760e4e6..b70b101 100644 --- a/app/app.json +++ b/app/app.json @@ -34,7 +34,8 @@ "page": { "pages": [ "page/index", - "page/permissionsPage" + "page/permissionsPage", + "page/rescuePlanPage" ] }, "app-side": { diff --git a/app/google-api-constants.example.js b/app/google-api-constants.example.js deleted file mode 100644 index 6fdafc6..0000000 --- a/app/google-api-constants.example.js +++ /dev/null @@ -1,4 +0,0 @@ -// You should create a `google-api.js` file that has your Google API related constants -export const GOOGLE_API_CLIENT_ID = 'client-id-here'; -export const GOOGLE_API_CLIENT_SECRET = 'client-secret-here'; -export const GOOGLE_API_REDIRECT_URI = 'https://zepp-os.zepp.com/app-settings/redirect.html'; \ No newline at end of file diff --git a/app/page/index.js b/app/page/index.js index d8fa8ac..16a6941 100644 --- a/app/page/index.js +++ b/app/page/index.js @@ -1,10 +1,15 @@ -import { BasePage } from '@zeppos/zml/base-page'; +import { BasePage } from "@zeppos/zml/base-page"; import * as appService from "@zos/app-service"; import { queryPermission, requestPermission } from "@zos/app"; -import hmUI from '@zos/ui'; -import { push } from '@zos/router'; -import { Sleep } from '@zos/sensor'; // Import the Sleep module -import { START_BUTTON, SLEEP_BUTTON, PERMISSIONS_BUTTON, STOP_BUTTON } from 'zosLoader:./index.[pf].layout.js'; +import hmUI from "@zos/ui"; +import { push } from "@zos/router"; +import { Sleep } from "@zos/sensor"; // Import the Sleep module +import { + START_BUTTON, + SLEEP_BUTTON, + PERMISSIONS_BUTTON, + STOP_BUTTON, +} from "zosLoader:./index.[pf].layout.js"; const permissions = ["device:os.bg_service"]; const service = "app-service/service"; @@ -22,12 +27,12 @@ Page( }, onInit(params) { console.log("Index Page onInit invoked"); - + // Log the entire params object to see the received data console.log("Received params:", params); - + // Check if params is a string and parse it as JSON - if (typeof params === 'string') { + if (typeof params === "string") { try { params = JSON.parse(params); // Convert string to object console.log("Parsed params:", params); @@ -36,25 +41,34 @@ Page( return; } } - + // Ensure params is an object with keys - if (params && typeof params === 'object' && Object.keys(params).length > 1) { + if ( + params && + typeof params === "object" && + Object.keys(params).length > 1 + ) { // Iterate through specific keys and store their values in state const permissionKeys = [ - "sleepScore", "startEndTime", "deepSleepTime", - "totalSleepTime", "wakeStage", "remStage", - "lightStage", "deepStage" + "sleepScore", + "startEndTime", + "deepSleepTime", + "totalSleepTime", + "wakeStage", + "remStage", + "lightStage", + "deepStage", ]; - + let permissions = {}; // Local object to store permissions - - permissionKeys.forEach(key => { + + permissionKeys.forEach((key) => { if (params.hasOwnProperty(key)) { permissions[key] = params[key]; console.log(`Permission: ${key}, Value: ${params[key]}`); } }); - + // Store the permissions in state this.state.permissions = permissions; console.log("Stored permissions:", this.state.permissions); @@ -64,18 +78,20 @@ Page( // Get token and store it in storage this.request({ - method: "GET_TOKEN" - }).then(res => { - hmUI.showToast({ - text: "token: " + res + method: "GET_TOKEN", + }) + .then((res) => { + hmUI.showToast({ + text: "token: " + res, + }); + storage.setKey("token", res); }) - storage.setKey("token", res); - }).catch(err => { - hmUI.showToast({ - text: "Error getting token on load (not signed in?)" + .catch((err) => { + hmUI.showToast({ + text: "Error getting token on load (not signed in?)", + }); + console.error("error getting token", err); }); - console.error("error getting token", err); - }); }, build() { @@ -108,9 +124,14 @@ Page( appService.stop({ file: service, complete_func: (info) => { - console.log("service stopped complete_func:", JSON.stringify(info)); + console.log( + "service stopped complete_func:", + JSON.stringify(info), + ); hmUI.showToast({ - text: info.result ? "Service stopped" : "Service failed to stop", + text: info.result + ? "Service stopped" + : "Service failed to stop", }); }, }); @@ -119,17 +140,17 @@ Page( hmUI.createWidget(hmUI.widget.BUTTON, { ...SLEEP_BUTTON, - click_func: this.onClickSleepButton.bind(this) + click_func: this.onClickSleepButton.bind(this), }); hmUI.createWidget(hmUI.widget.BUTTON, { ...PERMISSIONS_BUTTON, click_func: () => { - console.log('Permissions button clicked'); + console.log("Permissions button clicked"); push({ url: "page/permissionsPage", // No parameters passed here }); - } + }, }); }, @@ -156,17 +177,17 @@ Page( }, onClickSleepButton() { - console.log('Sleep button pressed'); - + console.log("Sleep button pressed"); + // Log the current state and permissions to see what data is available - console.log('Current state:', JSON.stringify(this.state)); - + console.log("Current state:", JSON.stringify(this.state)); + // Access permissions from the state if (this.state.permissions) { Object.entries(this.state.permissions).forEach(([key, value]) => { if (value === true) { console.log(`Permission for ${key} is granted.`); - + // Actual data extraction based on the granted permission switch (key) { case "sleepScore": @@ -237,7 +258,7 @@ Page( console.log(`No data for ${stageKey}`); } }, - }) + }), ); // Service-related functions @@ -249,7 +270,9 @@ const startAppService = (token) => { complete_func: (info) => { console.log("service started complete_func:", JSON.stringify(info)); hmUI.showToast({ - text: info.result ? 'Service started' + token : 'Service failed to start', + text: info.result + ? "Service started" + token + : "Service failed to start", }); }, }); diff --git a/app/page/index.r.layout.js b/app/page/index.r.layout.js index ae4da43..65b1684 100644 --- a/app/page/index.r.layout.js +++ b/app/page/index.r.layout.js @@ -1,5 +1,10 @@ import { px } from "@zos/utils"; -import { BUTTON_TEXT, BUTTON_TEXT_STOP, NORMAL_COLOR, PRESS_COLOR } from "../utils/constants"; +import { + BUTTON_TEXT, + BUTTON_TEXT_STOP, + NORMAL_COLOR, + PRESS_COLOR, +} from "../utils/constants"; export const START_BUTTON = { x: px(60), @@ -10,10 +15,9 @@ export const START_BUTTON = { radius: px(12), normal_color: NORMAL_COLOR, press_color: PRESS_COLOR, - text: BUTTON_TEXT + text: BUTTON_TEXT, }; - export const STOP_BUTTON = { x: px(60), y: px(300), @@ -23,7 +27,7 @@ export const STOP_BUTTON = { radius: px(12), normal_color: NORMAL_COLOR, press_color: PRESS_COLOR, - text: BUTTON_TEXT_STOP + text: BUTTON_TEXT_STOP, }; export const SLEEP_BUTTON = { @@ -35,7 +39,7 @@ export const SLEEP_BUTTON = { radius: px(12), normal_color: 0xaa42ee, press_color: 0xb964f0, - text: "Sleep Data" + text: "Sleep Data", }; export const PERMISSIONS_BUTTON = { @@ -47,5 +51,17 @@ export const PERMISSIONS_BUTTON = { radius: px(12), normal_color: 0x0352fc, press_color: 0x487ff7, - text: "Permission Data" + text: "Permission Data", +}; + +export const RESCUE_PLAN_BUTTON = { + x: px(60), + y: px(300), + w: px(360), + h: px(80), + text_size: px(36), + radius: px(12), + normal_color: a86432, + press_color: cc7a3d, + text: "Configure Rescue Plan", }; diff --git a/app/page/permissionsPage.js b/app/page/permissionsPage.js index 9c06a2d..ba950f3 100644 --- a/app/page/permissionsPage.js +++ b/app/page/permissionsPage.js @@ -1,133 +1,143 @@ -import hmUI from '@zos/ui'; -import { push } from '@zos/router'; -import { TOGGLE_OPTIONS, BACK_BUTTON } from 'zosLoader:./permissionsPage.[pf].layout.js'; -import { LocalStorage } from '@zos/storage'; // Import LocalStorage only once - -console.log("Navigated to the permissions page"); - -Page({ - state: { - message: "Permissions Page", - sleepScore: true, - startEndTime: true, - deepSleepTime: true, - totalSleepTime: true, - wakeStage: true, - remStage: true, - lightStage: true, - deepStage: true, - }, - - onInit() { - console.log("Permissions Page onInit invoked"); - this.localStorage = new LocalStorage(); // Initialize LocalStorage once - this.restoreToggleStates(); // Restore saved states when the page is initialized - }, - - build() { - console.log("Permissions Page Build Called"); - - // Display the main title - hmUI.createWidget(hmUI.widget.TEXT, { - text: this.state.message, - x: 100, - y: 20, - w: 200, - h: 50, - text_size: 24, - color: 0xFFFFFF, - align_h: hmUI.align.CENTER_H - }); - - // Create toggle switches with their corresponding names - TOGGLE_OPTIONS.forEach((option, index) => { - const checkedValue = this.state[option.key] !== undefined ? this.state[option.key] : true; - - // Create the switch widget for each option - hmUI.createWidget(hmUI.widget.SLIDE_SWITCH, { - x: option.x + 100, // Position the toggle switch slightly to the right - y: option.y, - w: option.w, - h: option.h, - checked: checkedValue, - color: 0xFFFFFF, // Text color for better visibility - text_size: px(16), // Smaller text size - checked_change_func: (slideSwitch, checked) => { - // Handle toggle change - this.handleToggleChange(option.key, checked); // Call the function for toggle change - } - }); - - // Create the label (name) for each toggle switch next to it - hmUI.createWidget(hmUI.widget.TEXT, { - text: option.label, - x: option.x, // Position the label next to the toggle - y: option.y + 5, // Adjust the Y position slightly to match the center of the toggle - w: px(100), // Adjust the width for the label - h: option.h, // Keep the same height as the toggle - text_size: px(16), // Smaller text size for the label - color: 0xFFFFFF, // Text color for better visibility - align_h: hmUI.align.LEFT, // Align the text to the left - }); - - console.log(`Created toggle widget and label for: ${option.label}`); - }); - - // Add the back button at the bottom of the page - hmUI.createWidget(hmUI.widget.BUTTON, { - ...BACK_BUTTON, - y: 500, // Adjust Y position for the back button - click_func: () => { - console.log("Back button clicked, preferences saved:"); - - // Log all the permissions and their state - TOGGLE_OPTIONS.forEach(option => { - const permissionState = this.state[option.key]; - console.log(`${option.label}: ${permissionState}`); - }); - - // Save permissions to localStorage - this.localStorage.setItem('userPermissions', JSON.stringify(this.state)); // Store the entire state - - // Log the params being passed to index.js - const paramsToPass = JSON.stringify(this.state); - console.log("Passing the following parameters to index.js: ", paramsToPass); - - // Pass the entire state through params when navigating to index.js - push({ - url: "page/index", - params: paramsToPass, // Pass the state as params - }); - }, - }); - }, - - onDestroy() { - console.log("Permissions Page onDestroy invoked"); - }, - - // Function to handle toggle change and save the state to localStorage - handleToggleChange(toggleId, isChecked) { - // Update the state when the switch is toggled - this.state[toggleId] = isChecked; - console.log(`${toggleId} tracking set to ${isChecked}`); - - // Store updated state to localStorage - this.localStorage.setItem(toggleId, isChecked.toString()); // Store state as a string - }, - - // Function to restore the toggle states from localStorage - restoreToggleStates() { - TOGGLE_OPTIONS.forEach(option => { - const toggleId = option.key; - - // Retrieve saved state from localStorage - const storedState = this.localStorage.getItem(toggleId); - if (storedState !== null) { - this.state[toggleId] = storedState === 'true'; // Convert string to boolean - } - - console.log(`Restored ${toggleId} state: ${this.state[toggleId]}`); - }); - } -}); +import hmUI from "@zos/ui"; +import { push } from "@zos/router"; +import { + TOGGLE_OPTIONS, + BACK_BUTTON, +} from "zosLoader:./permissionsPage.[pf].layout.js"; +import { LocalStorage } from "@zos/storage"; // Import LocalStorage only once + +console.log("Navigated to the permissions page"); + +Page({ + state: { + message: "Permissions Page", + sleepScore: true, + startEndTime: true, + deepSleepTime: true, + totalSleepTime: true, + wakeStage: true, + remStage: true, + lightStage: true, + deepStage: true, + }, + + onInit() { + console.log("Permissions Page onInit invoked"); + this.localStorage = new LocalStorage(); // Initialize LocalStorage once + this.restoreToggleStates(); // Restore saved states when the page is initialized + }, + + build() { + console.log("Permissions Page Build Called"); + + // Display the main title + hmUI.createWidget(hmUI.widget.TEXT, { + text: this.state.message, + x: 100, + y: 20, + w: 200, + h: 50, + text_size: 24, + color: 0xffffff, + align_h: hmUI.align.CENTER_H, + }); + + // Create toggle switches with their corresponding names + TOGGLE_OPTIONS.forEach((option, index) => { + const checkedValue = + this.state[option.key] !== undefined ? this.state[option.key] : true; + + // Create the switch widget for each option + hmUI.createWidget(hmUI.widget.SLIDE_SWITCH, { + x: option.x + 100, // Position the toggle switch slightly to the right + y: option.y, + w: option.w, + h: option.h, + checked: checkedValue, + color: 0xffffff, // Text color for better visibility + text_size: px(16), // Smaller text size + checked_change_func: (slideSwitch, checked) => { + // Handle toggle change + this.handleToggleChange(option.key, checked); // Call the function for toggle change + }, + }); + + // Create the label (name) for each toggle switch next to it + hmUI.createWidget(hmUI.widget.TEXT, { + text: option.label, + x: option.x, // Position the label next to the toggle + y: option.y + 5, // Adjust the Y position slightly to match the center of the toggle + w: px(100), // Adjust the width for the label + h: option.h, // Keep the same height as the toggle + text_size: px(16), // Smaller text size for the label + color: 0xffffff, // Text color for better visibility + align_h: hmUI.align.LEFT, // Align the text to the left + }); + + console.log(`Created toggle widget and label for: ${option.label}`); + }); + + // Add the back button at the bottom of the page + hmUI.createWidget(hmUI.widget.BUTTON, { + ...BACK_BUTTON, + y: 500, // Adjust Y position for the back button + click_func: () => { + console.log("Back button clicked, preferences saved:"); + + // Log all the permissions and their state + TOGGLE_OPTIONS.forEach((option) => { + const permissionState = this.state[option.key]; + console.log(`${option.label}: ${permissionState}`); + }); + + // Save permissions to localStorage + this.localStorage.setItem( + "userPermissions", + JSON.stringify(this.state), + ); // Store the entire state + + // Log the params being passed to index.js + const paramsToPass = JSON.stringify(this.state); + console.log( + "Passing the following parameters to index.js: ", + paramsToPass, + ); + + // Pass the entire state through params when navigating to index.js + push({ + url: "page/index", + params: paramsToPass, // Pass the state as params + }); + }, + }); + }, + + onDestroy() { + console.log("Permissions Page onDestroy invoked"); + }, + + // Function to handle toggle change and save the state to localStorage + handleToggleChange(toggleId, isChecked) { + // Update the state when the switch is toggled + this.state[toggleId] = isChecked; + console.log(`${toggleId} tracking set to ${isChecked}`); + + // Store updated state to localStorage + this.localStorage.setItem(toggleId, isChecked.toString()); // Store state as a string + }, + + // Function to restore the toggle states from localStorage + restoreToggleStates() { + TOGGLE_OPTIONS.forEach((option) => { + const toggleId = option.key; + + // Retrieve saved state from localStorage + const storedState = this.localStorage.getItem(toggleId); + if (storedState !== null) { + this.state[toggleId] = storedState === "true"; // Convert string to boolean + } + + console.log(`Restored ${toggleId} state: ${this.state[toggleId]}`); + }); + }, +}); diff --git a/app/page/permissionsPage.r.layout.js b/app/page/permissionsPage.r.layout.js index bb3985b..f68a7b4 100644 --- a/app/page/permissionsPage.r.layout.js +++ b/app/page/permissionsPage.r.layout.js @@ -1,81 +1,81 @@ -import { px } from "@zos/utils"; -import { BUTTON_TEXT, NORMAL_COLOR, PRESS_COLOR } from "../utils/constants"; - -export const TOGGLE_OPTIONS = [ - { - label: "Sleep Score", - key: "sleepScore", - x: px(100), - y: px(80), - w: px(200), - h: px(40), - }, - { - label: "Start & End Time", - key: "startEndTime", - x: px(100), - y: px(130), - w: px(200), - h: px(40), - }, - { - label: "Deep Sleep Time", - key: "deepSleepTime", - x: px(100), - y: px(180), - w: px(200), - h: px(40), - }, - { - label: "Total Sleep Time", - key: "totalSleepTime", - x: px(100), - y: px(230), - w: px(200), - h: px(40), - }, - { - label: "Wake Stage", - key: "wakeStage", - x: px(100), - y: px(280), - w: px(200), - h: px(40), - }, - { - label: "REM Stage", - key: "remStage", - x: px(100), - y: px(330), - w: px(200), - h: px(40), - }, - { - label: "Light Stage", - key: "lightStage", - x: px(100), - y: px(380), - w: px(200), - h: px(40), - }, - { - label: "Deep Stage", - key: "deepStage", - x: px(100), - y: px(430), - w: px(200), - h: px(40), - }, -]; - -export const BACK_BUTTON = { - x: px(150), - y: px(325), - w: px(200), - h: px(50), - text_size: px(25), - radius: px(12), - normal_color: NORMAL_COLOR, - press_color: PRESS_COLOR, - text: "Go Back" -}; +import { px } from "@zos/utils"; +import { BUTTON_TEXT, NORMAL_COLOR, PRESS_COLOR } from "../utils/constants"; + +export const TOGGLE_OPTIONS = [ + { + label: "Sleep Score", + key: "sleepScore", + x: px(100), + y: px(80), + w: px(200), + h: px(40), + }, + { + label: "Start & End Time", + key: "startEndTime", + x: px(100), + y: px(130), + w: px(200), + h: px(40), + }, + { + label: "Deep Sleep Time", + key: "deepSleepTime", + x: px(100), + y: px(180), + w: px(200), + h: px(40), + }, + { + label: "Total Sleep Time", + key: "totalSleepTime", + x: px(100), + y: px(230), + w: px(200), + h: px(40), + }, + { + label: "Wake Stage", + key: "wakeStage", + x: px(100), + y: px(280), + w: px(200), + h: px(40), + }, + { + label: "REM Stage", + key: "remStage", + x: px(100), + y: px(330), + w: px(200), + h: px(40), + }, + { + label: "Light Stage", + key: "lightStage", + x: px(100), + y: px(380), + w: px(200), + h: px(40), + }, + { + label: "Deep Stage", + key: "deepStage", + x: px(100), + y: px(430), + w: px(200), + h: px(40), + }, +]; + +export const BACK_BUTTON = { + x: px(150), + y: px(325), + w: px(200), + h: px(50), + text_size: px(25), + radius: px(12), + normal_color: NORMAL_COLOR, + press_color: PRESS_COLOR, + text: "Go Back", +}; diff --git a/app/page/rescuePlanPage.js b/app/page/rescuePlanPage.js new file mode 100644 index 0000000..ba950f3 --- /dev/null +++ b/app/page/rescuePlanPage.js @@ -0,0 +1,143 @@ +import hmUI from "@zos/ui"; +import { push } from "@zos/router"; +import { + TOGGLE_OPTIONS, + BACK_BUTTON, +} from "zosLoader:./permissionsPage.[pf].layout.js"; +import { LocalStorage } from "@zos/storage"; // Import LocalStorage only once + +console.log("Navigated to the permissions page"); + +Page({ + state: { + message: "Permissions Page", + sleepScore: true, + startEndTime: true, + deepSleepTime: true, + totalSleepTime: true, + wakeStage: true, + remStage: true, + lightStage: true, + deepStage: true, + }, + + onInit() { + console.log("Permissions Page onInit invoked"); + this.localStorage = new LocalStorage(); // Initialize LocalStorage once + this.restoreToggleStates(); // Restore saved states when the page is initialized + }, + + build() { + console.log("Permissions Page Build Called"); + + // Display the main title + hmUI.createWidget(hmUI.widget.TEXT, { + text: this.state.message, + x: 100, + y: 20, + w: 200, + h: 50, + text_size: 24, + color: 0xffffff, + align_h: hmUI.align.CENTER_H, + }); + + // Create toggle switches with their corresponding names + TOGGLE_OPTIONS.forEach((option, index) => { + const checkedValue = + this.state[option.key] !== undefined ? this.state[option.key] : true; + + // Create the switch widget for each option + hmUI.createWidget(hmUI.widget.SLIDE_SWITCH, { + x: option.x + 100, // Position the toggle switch slightly to the right + y: option.y, + w: option.w, + h: option.h, + checked: checkedValue, + color: 0xffffff, // Text color for better visibility + text_size: px(16), // Smaller text size + checked_change_func: (slideSwitch, checked) => { + // Handle toggle change + this.handleToggleChange(option.key, checked); // Call the function for toggle change + }, + }); + + // Create the label (name) for each toggle switch next to it + hmUI.createWidget(hmUI.widget.TEXT, { + text: option.label, + x: option.x, // Position the label next to the toggle + y: option.y + 5, // Adjust the Y position slightly to match the center of the toggle + w: px(100), // Adjust the width for the label + h: option.h, // Keep the same height as the toggle + text_size: px(16), // Smaller text size for the label + color: 0xffffff, // Text color for better visibility + align_h: hmUI.align.LEFT, // Align the text to the left + }); + + console.log(`Created toggle widget and label for: ${option.label}`); + }); + + // Add the back button at the bottom of the page + hmUI.createWidget(hmUI.widget.BUTTON, { + ...BACK_BUTTON, + y: 500, // Adjust Y position for the back button + click_func: () => { + console.log("Back button clicked, preferences saved:"); + + // Log all the permissions and their state + TOGGLE_OPTIONS.forEach((option) => { + const permissionState = this.state[option.key]; + console.log(`${option.label}: ${permissionState}`); + }); + + // Save permissions to localStorage + this.localStorage.setItem( + "userPermissions", + JSON.stringify(this.state), + ); // Store the entire state + + // Log the params being passed to index.js + const paramsToPass = JSON.stringify(this.state); + console.log( + "Passing the following parameters to index.js: ", + paramsToPass, + ); + + // Pass the entire state through params when navigating to index.js + push({ + url: "page/index", + params: paramsToPass, // Pass the state as params + }); + }, + }); + }, + + onDestroy() { + console.log("Permissions Page onDestroy invoked"); + }, + + // Function to handle toggle change and save the state to localStorage + handleToggleChange(toggleId, isChecked) { + // Update the state when the switch is toggled + this.state[toggleId] = isChecked; + console.log(`${toggleId} tracking set to ${isChecked}`); + + // Store updated state to localStorage + this.localStorage.setItem(toggleId, isChecked.toString()); // Store state as a string + }, + + // Function to restore the toggle states from localStorage + restoreToggleStates() { + TOGGLE_OPTIONS.forEach((option) => { + const toggleId = option.key; + + // Retrieve saved state from localStorage + const storedState = this.localStorage.getItem(toggleId); + if (storedState !== null) { + this.state[toggleId] = storedState === "true"; // Convert string to boolean + } + + console.log(`Restored ${toggleId} state: ${this.state[toggleId]}`); + }); + }, +}); diff --git a/app/setting/index.js b/app/setting/index.js index 050fc7d..b8d53fc 100644 --- a/app/setting/index.js +++ b/app/setting/index.js @@ -1,104 +1,116 @@ -import { requestGoogleAuthData } from "../app-service/google-api" -import { GOOGLE_API_CLIENT_ID, GOOGLE_API_CLIENT_SECRET, GOOGLE_API_REDIRECT_URI } from "../google-api-constants"; +import { requestGoogleAuthData } from "../app-service/google-api"; +import { + GOOGLE_API_CLIENT_ID, + GOOGLE_API_CLIENT_SECRET, + GOOGLE_API_REDIRECT_URI, +} from "../google-api-constants"; AppSettingsPage({ - state: { - props: {}, - googleAuthData: null, - }, - setState(props) { - console.log('setState', props); - this.state.props = props; - const storedAuthData = JSON.parse(props.settingsStorage.getItem('googleAuthData')); - if (storedAuthData) { - this.state.googleAuthData = storedAuthData; - } - if (this.isTokenExpired() || !this.state.googleAuthData) { - this.state.googleAuthData = null; - } - console.log('state:', this.state); - }, - build(props) { - this.setState(props); + state: { + props: {}, + googleAuthData: null, + }, + setState(props) { + console.log("setState", props); + this.state.props = props; + const storedAuthData = JSON.parse( + props.settingsStorage.getItem("googleAuthData"), + ); + if (storedAuthData) { + this.state.googleAuthData = storedAuthData; + } + if (this.isTokenExpired() || !this.state.googleAuthData) { + this.state.googleAuthData = null; + } + console.log("state:", this.state); + }, + build(props) { + this.setState(props); - const nowTag = (new Date()).toISOString().substring(0, 19); - if (props.settingsStorage.getItem("now") !== nowTag) props.settingsStorage.setItem("now", nowTag); + const nowTag = new Date().toISOString().substring(0, 19); + if (props.settingsStorage.getItem("now") !== nowTag) + props.settingsStorage.setItem("now", nowTag); - const signInBtn = Button({ - label: this.state.googleAuthData ? 'Sign Out' : 'Sign In', // fix - style: { - fontSize: '12px', - borderRadius: '30px', - background: '#D85E33', - color: 'white' - }, - }) + const signInBtn = Button({ + label: this.state.googleAuthData ? "Sign Out" : "Sign In", // fix + style: { + fontSize: "12px", + borderRadius: "30px", + background: "#D85E33", + color: "white", + }, + }); - const clearBtn = Button({ - label: 'Clear', - style: { - fontSize: '12px', - borderRadius: '30px', - background: '#D85E33', - color: 'white' - }, - onClick: () => { - console.log('before clear', this.state.props.settingsStorage.toObject()); - // this.state.props.settingsStorage.clear(); - props.settingsStorage.setItem("googleAuthData", null); - props.settingsStorage.setItem("googleAuthCode", null); - this.state.googleAuthData = ""; - console.log('after clear', this.state.props.settingsStorage.toObject()); - } - }) + const clearBtn = Button({ + label: "Clear", + style: { + fontSize: "12px", + borderRadius: "30px", + background: "#D85E33", + color: "white", + }, + onClick: () => { + console.log( + "before clear", + this.state.props.settingsStorage.toObject(), + ); + // this.state.props.settingsStorage.clear(); + props.settingsStorage.setItem("googleAuthData", null); + props.settingsStorage.setItem("googleAuthCode", null); + this.state.googleAuthData = ""; + console.log("after clear", this.state.props.settingsStorage.toObject()); + }, + }); - const auth = Auth({ - label: signInBtn, - authorizeUrl: 'https://accounts.google.com/o/oauth2/v2/auth', - requestTokenUrl: 'https://oauth2.googleapis.com/token', - scope: 'https://www.googleapis.com/auth/drive', - clientId: GOOGLE_API_CLIENT_ID, - clientSecret: GOOGLE_API_CLIENT_SECRET, - oAuthParams: { - redirect_uri: GOOGLE_API_REDIRECT_URI, - response_type: 'code', - include_granted_scopes: 'true', - access_type: 'offline', - prompt: 'consent' - }, - onAccessToken: (token) => { - console.log('onAccessToken', token) - }, - onReturn: async (authBody) => { - console.log('onReturn', authBody) - // this.state.props.settingsStorage.setItem('googleAuthCode', authBody.code) - const authData = await requestGoogleAuthData(authBody) - authData.requested_at = new Date() - authData.expires_at = new Date(authData.requested_at.getTime() + authData.expires_in * 1000) - this.state.props.settingsStorage.setItem('googleAuthData', JSON.stringify(authData)) - console.log('authData', this.state.googleAuthData) - }, - }) + const auth = Auth({ + label: signInBtn, + authorizeUrl: "https://accounts.google.com/o/oauth2/v2/auth", + requestTokenUrl: "https://oauth2.googleapis.com/token", + scope: "https://www.googleapis.com/auth/drive", + clientId: GOOGLE_API_CLIENT_ID, + clientSecret: GOOGLE_API_CLIENT_SECRET, + oAuthParams: { + redirect_uri: GOOGLE_API_REDIRECT_URI, + response_type: "code", + include_granted_scopes: "true", + access_type: "offline", + prompt: "consent", + }, + onAccessToken: (token) => { + console.log("onAccessToken", token); + }, + onReturn: async (authBody) => { + console.log("onReturn", authBody); + // this.state.props.settingsStorage.setItem('googleAuthCode', authBody.code) + const authData = await requestGoogleAuthData(authBody); + authData.requested_at = new Date(); + authData.expires_at = new Date( + authData.requested_at.getTime() + authData.expires_in * 1000, + ); + this.state.props.settingsStorage.setItem( + "googleAuthData", + JSON.stringify(authData), + ); + console.log("authData", this.state.googleAuthData); + }, + }); - return View( - { - style: { - padding: '12px 20px' - } - }, - [ - auth, - clearBtn - ] - ) - }, - isTokenExpired() { - const authData = this.state.googleAuthData; - if (!authData || !authData.expires_at) { - return true; - } - const now = new Date(); - const expiresAt = new Date(authData.expires_at); - return now >= expiresAt; - }, -}) \ No newline at end of file + return View( + { + style: { + padding: "12px 20px", + }, + }, + [auth, clearBtn], + ); + }, + isTokenExpired() { + const authData = this.state.googleAuthData; + if (!authData || !authData.expires_at) { + return true; + } + const now = new Date(); + const expiresAt = new Date(authData.expires_at); + return now >= expiresAt; + }, +}); diff --git a/app/utils/constants.js b/app/utils/constants.js index 26180b0..c8c3d93 100644 --- a/app/utils/constants.js +++ b/app/utils/constants.js @@ -1,4 +1,4 @@ export const BUTTON_TEXT = "Start"; export const BUTTON_TEXT_STOP = "Stop"; export const NORMAL_COLOR = 0xff0000; -export const PRESS_COLOR = 0xaa0000; \ No newline at end of file +export const PRESS_COLOR = 0xaa0000; From 3287b5386bfdc8c620c46d547c40ef8fb912ad68 Mon Sep 17 00:00:00 2001 From: Emil Date: Tue, 26 Nov 2024 03:26:38 -0700 Subject: [PATCH 07/28] Fixed the Prettier Error --- app/package.json | 2 +- app/page/index.js | 516 +++++++++++++-------------- app/page/index.r.layout.js | 86 ++--- app/page/permissionsPage.js | 276 +++++++------- app/page/permissionsPage.r.layout.js | 150 ++++---- app/page/rescuePlanPage.js | 276 +++++++------- app/setting/index.js | 2 +- 7 files changed, 654 insertions(+), 654 deletions(-) diff --git a/app/package.json b/app/package.json index 6750e8f..16732d1 100644 --- a/app/package.json +++ b/app/package.json @@ -7,7 +7,7 @@ "license": "ISC", "devDependencies": { "@zeppos/device-types": "^3.0.0", - "prettier": "^3.3.3" + "prettier": "^3.4.0" }, "dependencies": { "@silver-zepp/easy-storage": "^1.6.7-b", diff --git a/app/page/index.js b/app/page/index.js index 16a6941..cca2d01 100644 --- a/app/page/index.js +++ b/app/page/index.js @@ -1,18 +1,18 @@ -import { BasePage } from "@zeppos/zml/base-page"; -import * as appService from "@zos/app-service"; -import { queryPermission, requestPermission } from "@zos/app"; -import hmUI from "@zos/ui"; -import { push } from "@zos/router"; -import { Sleep } from "@zos/sensor"; // Import the Sleep module +import { BasePage } from '@zeppos/zml/base-page'; +import * as appService from '@zos/app-service'; +import { queryPermission, requestPermission } from '@zos/app'; +import hmUI from '@zos/ui'; +import { push } from '@zos/router'; +import { Sleep } from '@zos/sensor'; // Import the Sleep module import { - START_BUTTON, - SLEEP_BUTTON, - PERMISSIONS_BUTTON, - STOP_BUTTON, -} from "zosLoader:./index.[pf].layout.js"; + START_BUTTON, + SLEEP_BUTTON, + PERMISSIONS_BUTTON, + STOP_BUTTON, +} from 'zosLoader:./index.[pf].layout.js'; -const permissions = ["device:os.bg_service"]; -const service = "app-service/service"; +const permissions = ['device:os.bg_service']; +const service = 'app-service/service'; const storage = getApp()._options.globalData.storage; // Initialize the Sleep module @@ -20,282 +20,282 @@ const sleep = new Sleep(); // Main page setup Page( - BasePage({ - state: { - temp: null, - permissions: {}, - }, - onInit(params) { - console.log("Index Page onInit invoked"); + BasePage({ + state: { + temp: null, + permissions: {}, + }, + onInit(params) { + console.log('Index Page onInit invoked'); - // Log the entire params object to see the received data - console.log("Received params:", params); + // Log the entire params object to see the received data + console.log('Received params:', params); - // Check if params is a string and parse it as JSON - if (typeof params === "string") { - try { - params = JSON.parse(params); // Convert string to object - console.log("Parsed params:", params); - } catch (error) { - console.error("Error parsing params:", error); - return; - } - } + // Check if params is a string and parse it as JSON + if (typeof params === 'string') { + try { + params = JSON.parse(params); // Convert string to object + console.log('Parsed params:', params); + } catch (error) { + console.error('Error parsing params:', error); + return; + } + } - // Ensure params is an object with keys - if ( - params && - typeof params === "object" && - Object.keys(params).length > 1 - ) { - // Iterate through specific keys and store their values in state - const permissionKeys = [ - "sleepScore", - "startEndTime", - "deepSleepTime", - "totalSleepTime", - "wakeStage", - "remStage", - "lightStage", - "deepStage", - ]; + // Ensure params is an object with keys + if ( + params && + typeof params === 'object' && + Object.keys(params).length > 1 + ) { + // Iterate through specific keys and store their values in state + const permissionKeys = [ + 'sleepScore', + 'startEndTime', + 'deepSleepTime', + 'totalSleepTime', + 'wakeStage', + 'remStage', + 'lightStage', + 'deepStage', + ]; - let permissions = {}; // Local object to store permissions + let permissions = {}; // Local object to store permissions - permissionKeys.forEach((key) => { - if (params.hasOwnProperty(key)) { - permissions[key] = params[key]; - console.log(`Permission: ${key}, Value: ${params[key]}`); - } - }); + permissionKeys.forEach((key) => { + if (params.hasOwnProperty(key)) { + permissions[key] = params[key]; + console.log(`Permission: ${key}, Value: ${params[key]}`); + } + }); - // Store the permissions in state - this.state.permissions = permissions; - console.log("Stored permissions:", this.state.permissions); - } else { - console.log("No permission data received or invalid format."); - } + // Store the permissions in state + this.state.permissions = permissions; + console.log('Stored permissions:', this.state.permissions); + } else { + console.log('No permission data received or invalid format.'); + } - // Get token and store it in storage - this.request({ - method: "GET_TOKEN", - }) - .then((res) => { - hmUI.showToast({ - text: "token: " + res, - }); - storage.setKey("token", res); - }) - .catch((err) => { - hmUI.showToast({ - text: "Error getting token on load (not signed in?)", - }); - console.error("error getting token", err); - }); - }, + // Get token and store it in storage + this.request({ + method: 'GET_TOKEN', + }) + .then((res) => { + hmUI.showToast({ + text: 'token: ' + res, + }); + storage.setKey('token', res); + }) + .catch((err) => { + hmUI.showToast({ + text: 'Error getting token on load (not signed in?)', + }); + console.error('error getting token', err); + }); + }, - build() { - hmUI.createWidget(hmUI.widget.BUTTON, { - ...START_BUTTON, - click_func: async () => { - console.log("fetch button clicked"); - const token = storage.getKey("token"); - if (!token) { - hmUI.showToast({ - text: "Please sign in", - }); - console.log("No token found, user needs to sign in"); - return; - } + build() { + hmUI.createWidget(hmUI.widget.BUTTON, { + ...START_BUTTON, + click_func: async () => { + console.log('fetch button clicked'); + const token = storage.getKey('token'); + if (!token) { + hmUI.showToast({ + text: 'Please sign in', + }); + console.log('No token found, user needs to sign in'); + return; + } - // Only proceed if got token - if (checkPermissions()) { - startAppService(token); - } else { - console.log("Permission denied"); - } - }, - }); + // Only proceed if got token + if (checkPermissions()) { + startAppService(token); + } else { + console.log('Permission denied'); + } + }, + }); - hmUI.createWidget(hmUI.widget.BUTTON, { - ...STOP_BUTTON, - click_func: () => { - console.log("stop button clicked"); - appService.stop({ - file: service, - complete_func: (info) => { - console.log( - "service stopped complete_func:", - JSON.stringify(info), - ); - hmUI.showToast({ - text: info.result - ? "Service stopped" - : "Service failed to stop", - }); - }, - }); - }, - }); + hmUI.createWidget(hmUI.widget.BUTTON, { + ...STOP_BUTTON, + click_func: () => { + console.log('stop button clicked'); + appService.stop({ + file: service, + complete_func: (info) => { + console.log( + 'service stopped complete_func:', + JSON.stringify(info), + ); + hmUI.showToast({ + text: info.result + ? 'Service stopped' + : 'Service failed to stop', + }); + }, + }); + }, + }); - hmUI.createWidget(hmUI.widget.BUTTON, { - ...SLEEP_BUTTON, - click_func: this.onClickSleepButton.bind(this), - }); + hmUI.createWidget(hmUI.widget.BUTTON, { + ...SLEEP_BUTTON, + click_func: this.onClickSleepButton.bind(this), + }); - hmUI.createWidget(hmUI.widget.BUTTON, { - ...PERMISSIONS_BUTTON, - click_func: () => { - console.log("Permissions button clicked"); - push({ - url: "page/permissionsPage", // No parameters passed here - }); - }, - }); - }, + hmUI.createWidget(hmUI.widget.BUTTON, { + ...PERMISSIONS_BUTTON, + click_func: () => { + console.log('Permissions button clicked'); + push({ + url: 'page/permissionsPage', // No parameters passed here + }); + }, + }); + }, - onDestroy() { - console.log("page onDestroy invoked"); - }, + onDestroy() { + console.log('page onDestroy invoked'); + }, - onRequest(req, res) { - console.log("page onRequest invoked"); - console.log("req:", req); - console.log("res:", res); - }, + onRequest(req, res) { + console.log('page onRequest invoked'); + console.log('req:', req); + console.log('res:', res); + }, - onCall(req) { - if (req.method === "SET_TOKEN") { - console.log("SET_TOKEN method invoked"); - storage.setKey("token", req.params.value); + onCall(req) { + if (req.method === 'SET_TOKEN') { + console.log('SET_TOKEN method invoked'); + storage.setKey('token', req.params.value); - hmUI.showToast({ - text: "Token saved " + JSON.stringify(req.params), - }); - storage.setKey("token", req.params.value); - } - }, + hmUI.showToast({ + text: 'Token saved ' + JSON.stringify(req.params), + }); + storage.setKey('token', req.params.value); + } + }, - onClickSleepButton() { - console.log("Sleep button pressed"); + onClickSleepButton() { + console.log('Sleep button pressed'); - // Log the current state and permissions to see what data is available - console.log("Current state:", JSON.stringify(this.state)); + // Log the current state and permissions to see what data is available + console.log('Current state:', JSON.stringify(this.state)); - // Access permissions from the state - if (this.state.permissions) { - Object.entries(this.state.permissions).forEach(([key, value]) => { - if (value === true) { - console.log(`Permission for ${key} is granted.`); + // Access permissions from the state + if (this.state.permissions) { + Object.entries(this.state.permissions).forEach(([key, value]) => { + if (value === true) { + console.log(`Permission for ${key} is granted.`); - // Actual data extraction based on the granted permission - switch (key) { - case "sleepScore": - // Get the sleep score using the `getInfo` method - this.getSleepInfo("score"); - break; - case "startEndTime": - // Get the start and end times (assuming `getInfo` provides this) - this.getSleepInfo("startTime"); - this.getSleepInfo("endTime"); - break; - case "deepSleepTime": - // Get the deep sleep time using `getInfo` - this.getSleepInfo("deepTime"); - break; - case "totalSleepTime": - // Get the total sleep time using `getInfo` - this.getSleepInfo("totalTime"); - break; - case "wakeStage": - // Get the wake stage using `getStageConstantObj` - this.getStageConstantObj("WAKE_STAGE"); - break; - case "remStage": - // Get the REM stage using `getStageConstantObj` - this.getStageConstantObj("REM_STAGE"); - break; - case "lightStage": - // Get the light sleep stage using `getStageConstantObj` - this.getStageConstantObj("LIGHT_STAGE"); - break; - case "deepStage": - // Get the deep sleep stage using `getStageConstantObj` - this.getStageConstantObj("DEEP_STAGE"); - break; - default: - console.log(`No action defined for permission: ${key}`); - } - } else { - console.log(`Permission for ${key} is denied.`); - } - }); - } else { - console.log("No permissions found in state."); - } - }, + // Actual data extraction based on the granted permission + switch (key) { + case 'sleepScore': + // Get the sleep score using the `getInfo` method + this.getSleepInfo('score'); + break; + case 'startEndTime': + // Get the start and end times (assuming `getInfo` provides this) + this.getSleepInfo('startTime'); + this.getSleepInfo('endTime'); + break; + case 'deepSleepTime': + // Get the deep sleep time using `getInfo` + this.getSleepInfo('deepTime'); + break; + case 'totalSleepTime': + // Get the total sleep time using `getInfo` + this.getSleepInfo('totalTime'); + break; + case 'wakeStage': + // Get the wake stage using `getStageConstantObj` + this.getStageConstantObj('WAKE_STAGE'); + break; + case 'remStage': + // Get the REM stage using `getStageConstantObj` + this.getStageConstantObj('REM_STAGE'); + break; + case 'lightStage': + // Get the light sleep stage using `getStageConstantObj` + this.getStageConstantObj('LIGHT_STAGE'); + break; + case 'deepStage': + // Get the deep sleep stage using `getStageConstantObj` + this.getStageConstantObj('DEEP_STAGE'); + break; + default: + console.log(`No action defined for permission: ${key}`); + } + } else { + console.log(`Permission for ${key} is denied.`); + } + }); + } else { + console.log('No permissions found in state.'); + } + }, - // Extract sleep info (getInfo method) - getSleepInfo(infoKey) { - // Using the ZeppOS Sleep module to fetch the sleep info - const info = sleep.getInfo(); + // Extract sleep info (getInfo method) + getSleepInfo(infoKey) { + // Using the ZeppOS Sleep module to fetch the sleep info + const info = sleep.getInfo(); - if (info && info.hasOwnProperty(infoKey)) { - console.log(`${infoKey}: ${info[infoKey]}`); - } else { - console.log(`No data for ${infoKey}`); - } - }, + if (info && info.hasOwnProperty(infoKey)) { + console.log(`${infoKey}: ${info[infoKey]}`); + } else { + console.log(`No data for ${infoKey}`); + } + }, - // Extract stage constant - getStageConstantObj(stageKey) { - // Using the ZeppOS Sleep module to fetch stage constants - const sleepStageConstants = sleep.getStageConstantObj(); + // Extract stage constant + getStageConstantObj(stageKey) { + // Using the ZeppOS Sleep module to fetch stage constants + const sleepStageConstants = sleep.getStageConstantObj(); - if (sleepStageConstants && sleepStageConstants.hasOwnProperty(stageKey)) { - console.log(`${stageKey}: ${sleepStageConstants[stageKey]}`); - } else { - console.log(`No data for ${stageKey}`); - } - }, - }), + if (sleepStageConstants && sleepStageConstants.hasOwnProperty(stageKey)) { + console.log(`${stageKey}: ${sleepStageConstants[stageKey]}`); + } else { + console.log(`No data for ${stageKey}`); + } + }, + }), ); // Service-related functions const startAppService = (token) => { - console.log("startAppService invoked"); - console.log(`starting service: ${service}`); - appService.start({ - file: service, - complete_func: (info) => { - console.log("service started complete_func:", JSON.stringify(info)); - hmUI.showToast({ - text: info.result - ? "Service started" + token - : "Service failed to start", - }); - }, - }); + console.log('startAppService invoked'); + console.log(`starting service: ${service}`); + appService.start({ + file: service, + complete_func: (info) => { + console.log('service started complete_func:', JSON.stringify(info)); + hmUI.showToast({ + text: info.result + ? 'Service started' + token + : 'Service failed to start', + }); + }, + }); }; // Asynchronous permission check const checkPermissions = async () => { - // Query for permissions first - const [permissionResult] = queryPermission({ permissions }); + // Query for permissions first + const [permissionResult] = queryPermission({ permissions }); - if (permissionResult === 2) { - console.log("Permission previously allowed"); - return true; // Permission granted - } else { - requestPermission({ - permissions, - callback: ([result]) => { - if (result === 2) { - console.log("permission granted"); - return true; - } - }, - }); - } - return false; + if (permissionResult === 2) { + console.log('Permission previously allowed'); + return true; // Permission granted + } else { + requestPermission({ + permissions, + callback: ([result]) => { + if (result === 2) { + console.log('permission granted'); + return true; + } + }, + }); + } + return false; }; diff --git a/app/page/index.r.layout.js b/app/page/index.r.layout.js index c240911..3345606 100644 --- a/app/page/index.r.layout.js +++ b/app/page/index.r.layout.js @@ -1,55 +1,55 @@ -import { px } from "@zos/utils"; +import { px } from '@zos/utils'; import { - BUTTON_TEXT, - BUTTON_TEXT_STOP, - NORMAL_COLOR, - PRESS_COLOR, -} from "../utils/constants"; + BUTTON_TEXT, + BUTTON_TEXT_STOP, + NORMAL_COLOR, + PRESS_COLOR, +} from '../utils/constants'; export const START_BUTTON = { - x: px(60), - y: px(300), - w: px(360), - h: px(80), - text_size: px(36), - radius: px(12), - normal_color: NORMAL_COLOR, - press_color: PRESS_COLOR, - text: BUTTON_TEXT, + x: px(60), + y: px(300), + w: px(360), + h: px(80), + text_size: px(36), + radius: px(12), + normal_color: NORMAL_COLOR, + press_color: PRESS_COLOR, + text: BUTTON_TEXT, }; export const STOP_BUTTON = { - x: px(60), - y: px(300), - w: px(360), - h: px(80), - text_size: px(36), - radius: px(12), - normal_color: NORMAL_COLOR, - press_color: PRESS_COLOR, - text: BUTTON_TEXT_STOP, + x: px(60), + y: px(300), + w: px(360), + h: px(80), + text_size: px(36), + radius: px(12), + normal_color: NORMAL_COLOR, + press_color: PRESS_COLOR, + text: BUTTON_TEXT_STOP, }; export const SLEEP_BUTTON = { - x: px(50), - y: px(225), - w: px(200), - h: px(50), - text_size: px(25), - radius: px(12), - normal_color: 0xaa42ee, - press_color: 0xb964f0, - text: "Sleep Data", + x: px(50), + y: px(225), + w: px(200), + h: px(50), + text_size: px(25), + radius: px(12), + normal_color: 0xaa42ee, + press_color: 0xb964f0, + text: 'Sleep Data', }; export const PERMISSIONS_BUTTON = { - x: px(75), - y: px(100), - w: px(225), - h: px(50), - text_size: px(25), - radius: px(12), - normal_color: 0x0352fc, - press_color: 0x487ff7, - text: "Permission Data" -}; \ No newline at end of file + x: px(75), + y: px(100), + w: px(225), + h: px(50), + text_size: px(25), + radius: px(12), + normal_color: 0x0352fc, + press_color: 0x487ff7, + text: 'Permission Data', +}; diff --git a/app/page/permissionsPage.js b/app/page/permissionsPage.js index ba950f3..a112aaf 100644 --- a/app/page/permissionsPage.js +++ b/app/page/permissionsPage.js @@ -1,143 +1,143 @@ -import hmUI from "@zos/ui"; -import { push } from "@zos/router"; +import hmUI from '@zos/ui'; +import { push } from '@zos/router'; import { - TOGGLE_OPTIONS, - BACK_BUTTON, -} from "zosLoader:./permissionsPage.[pf].layout.js"; -import { LocalStorage } from "@zos/storage"; // Import LocalStorage only once + TOGGLE_OPTIONS, + BACK_BUTTON, +} from 'zosLoader:./permissionsPage.[pf].layout.js'; +import { LocalStorage } from '@zos/storage'; // Import LocalStorage only once -console.log("Navigated to the permissions page"); +console.log('Navigated to the permissions page'); Page({ - state: { - message: "Permissions Page", - sleepScore: true, - startEndTime: true, - deepSleepTime: true, - totalSleepTime: true, - wakeStage: true, - remStage: true, - lightStage: true, - deepStage: true, - }, - - onInit() { - console.log("Permissions Page onInit invoked"); - this.localStorage = new LocalStorage(); // Initialize LocalStorage once - this.restoreToggleStates(); // Restore saved states when the page is initialized - }, - - build() { - console.log("Permissions Page Build Called"); - - // Display the main title - hmUI.createWidget(hmUI.widget.TEXT, { - text: this.state.message, - x: 100, - y: 20, - w: 200, - h: 50, - text_size: 24, - color: 0xffffff, - align_h: hmUI.align.CENTER_H, - }); - - // Create toggle switches with their corresponding names - TOGGLE_OPTIONS.forEach((option, index) => { - const checkedValue = - this.state[option.key] !== undefined ? this.state[option.key] : true; - - // Create the switch widget for each option - hmUI.createWidget(hmUI.widget.SLIDE_SWITCH, { - x: option.x + 100, // Position the toggle switch slightly to the right - y: option.y, - w: option.w, - h: option.h, - checked: checkedValue, - color: 0xffffff, // Text color for better visibility - text_size: px(16), // Smaller text size - checked_change_func: (slideSwitch, checked) => { - // Handle toggle change - this.handleToggleChange(option.key, checked); // Call the function for toggle change - }, - }); - - // Create the label (name) for each toggle switch next to it - hmUI.createWidget(hmUI.widget.TEXT, { - text: option.label, - x: option.x, // Position the label next to the toggle - y: option.y + 5, // Adjust the Y position slightly to match the center of the toggle - w: px(100), // Adjust the width for the label - h: option.h, // Keep the same height as the toggle - text_size: px(16), // Smaller text size for the label - color: 0xffffff, // Text color for better visibility - align_h: hmUI.align.LEFT, // Align the text to the left - }); - - console.log(`Created toggle widget and label for: ${option.label}`); - }); - - // Add the back button at the bottom of the page - hmUI.createWidget(hmUI.widget.BUTTON, { - ...BACK_BUTTON, - y: 500, // Adjust Y position for the back button - click_func: () => { - console.log("Back button clicked, preferences saved:"); - - // Log all the permissions and their state - TOGGLE_OPTIONS.forEach((option) => { - const permissionState = this.state[option.key]; - console.log(`${option.label}: ${permissionState}`); - }); - - // Save permissions to localStorage - this.localStorage.setItem( - "userPermissions", - JSON.stringify(this.state), - ); // Store the entire state - - // Log the params being passed to index.js - const paramsToPass = JSON.stringify(this.state); - console.log( - "Passing the following parameters to index.js: ", - paramsToPass, - ); - - // Pass the entire state through params when navigating to index.js - push({ - url: "page/index", - params: paramsToPass, // Pass the state as params - }); - }, - }); - }, - - onDestroy() { - console.log("Permissions Page onDestroy invoked"); - }, - - // Function to handle toggle change and save the state to localStorage - handleToggleChange(toggleId, isChecked) { - // Update the state when the switch is toggled - this.state[toggleId] = isChecked; - console.log(`${toggleId} tracking set to ${isChecked}`); - - // Store updated state to localStorage - this.localStorage.setItem(toggleId, isChecked.toString()); // Store state as a string - }, - - // Function to restore the toggle states from localStorage - restoreToggleStates() { - TOGGLE_OPTIONS.forEach((option) => { - const toggleId = option.key; - - // Retrieve saved state from localStorage - const storedState = this.localStorage.getItem(toggleId); - if (storedState !== null) { - this.state[toggleId] = storedState === "true"; // Convert string to boolean - } - - console.log(`Restored ${toggleId} state: ${this.state[toggleId]}`); - }); - }, + state: { + message: 'Permissions Page', + sleepScore: true, + startEndTime: true, + deepSleepTime: true, + totalSleepTime: true, + wakeStage: true, + remStage: true, + lightStage: true, + deepStage: true, + }, + + onInit() { + console.log('Permissions Page onInit invoked'); + this.localStorage = new LocalStorage(); // Initialize LocalStorage once + this.restoreToggleStates(); // Restore saved states when the page is initialized + }, + + build() { + console.log('Permissions Page Build Called'); + + // Display the main title + hmUI.createWidget(hmUI.widget.TEXT, { + text: this.state.message, + x: 100, + y: 20, + w: 200, + h: 50, + text_size: 24, + color: 0xffffff, + align_h: hmUI.align.CENTER_H, + }); + + // Create toggle switches with their corresponding names + TOGGLE_OPTIONS.forEach((option, index) => { + const checkedValue = + this.state[option.key] !== undefined ? this.state[option.key] : true; + + // Create the switch widget for each option + hmUI.createWidget(hmUI.widget.SLIDE_SWITCH, { + x: option.x + 100, // Position the toggle switch slightly to the right + y: option.y, + w: option.w, + h: option.h, + checked: checkedValue, + color: 0xffffff, // Text color for better visibility + text_size: px(16), // Smaller text size + checked_change_func: (slideSwitch, checked) => { + // Handle toggle change + this.handleToggleChange(option.key, checked); // Call the function for toggle change + }, + }); + + // Create the label (name) for each toggle switch next to it + hmUI.createWidget(hmUI.widget.TEXT, { + text: option.label, + x: option.x, // Position the label next to the toggle + y: option.y + 5, // Adjust the Y position slightly to match the center of the toggle + w: px(100), // Adjust the width for the label + h: option.h, // Keep the same height as the toggle + text_size: px(16), // Smaller text size for the label + color: 0xffffff, // Text color for better visibility + align_h: hmUI.align.LEFT, // Align the text to the left + }); + + console.log(`Created toggle widget and label for: ${option.label}`); + }); + + // Add the back button at the bottom of the page + hmUI.createWidget(hmUI.widget.BUTTON, { + ...BACK_BUTTON, + y: 500, // Adjust Y position for the back button + click_func: () => { + console.log('Back button clicked, preferences saved:'); + + // Log all the permissions and their state + TOGGLE_OPTIONS.forEach((option) => { + const permissionState = this.state[option.key]; + console.log(`${option.label}: ${permissionState}`); + }); + + // Save permissions to localStorage + this.localStorage.setItem( + 'userPermissions', + JSON.stringify(this.state), + ); // Store the entire state + + // Log the params being passed to index.js + const paramsToPass = JSON.stringify(this.state); + console.log( + 'Passing the following parameters to index.js: ', + paramsToPass, + ); + + // Pass the entire state through params when navigating to index.js + push({ + url: 'page/index', + params: paramsToPass, // Pass the state as params + }); + }, + }); + }, + + onDestroy() { + console.log('Permissions Page onDestroy invoked'); + }, + + // Function to handle toggle change and save the state to localStorage + handleToggleChange(toggleId, isChecked) { + // Update the state when the switch is toggled + this.state[toggleId] = isChecked; + console.log(`${toggleId} tracking set to ${isChecked}`); + + // Store updated state to localStorage + this.localStorage.setItem(toggleId, isChecked.toString()); // Store state as a string + }, + + // Function to restore the toggle states from localStorage + restoreToggleStates() { + TOGGLE_OPTIONS.forEach((option) => { + const toggleId = option.key; + + // Retrieve saved state from localStorage + const storedState = this.localStorage.getItem(toggleId); + if (storedState !== null) { + this.state[toggleId] = storedState === 'true'; // Convert string to boolean + } + + console.log(`Restored ${toggleId} state: ${this.state[toggleId]}`); + }); + }, }); diff --git a/app/page/permissionsPage.r.layout.js b/app/page/permissionsPage.r.layout.js index f68a7b4..93ad2cc 100644 --- a/app/page/permissionsPage.r.layout.js +++ b/app/page/permissionsPage.r.layout.js @@ -1,81 +1,81 @@ -import { px } from "@zos/utils"; -import { BUTTON_TEXT, NORMAL_COLOR, PRESS_COLOR } from "../utils/constants"; +import { px } from '@zos/utils'; +import { BUTTON_TEXT, NORMAL_COLOR, PRESS_COLOR } from '../utils/constants'; export const TOGGLE_OPTIONS = [ - { - label: "Sleep Score", - key: "sleepScore", - x: px(100), - y: px(80), - w: px(200), - h: px(40), - }, - { - label: "Start & End Time", - key: "startEndTime", - x: px(100), - y: px(130), - w: px(200), - h: px(40), - }, - { - label: "Deep Sleep Time", - key: "deepSleepTime", - x: px(100), - y: px(180), - w: px(200), - h: px(40), - }, - { - label: "Total Sleep Time", - key: "totalSleepTime", - x: px(100), - y: px(230), - w: px(200), - h: px(40), - }, - { - label: "Wake Stage", - key: "wakeStage", - x: px(100), - y: px(280), - w: px(200), - h: px(40), - }, - { - label: "REM Stage", - key: "remStage", - x: px(100), - y: px(330), - w: px(200), - h: px(40), - }, - { - label: "Light Stage", - key: "lightStage", - x: px(100), - y: px(380), - w: px(200), - h: px(40), - }, - { - label: "Deep Stage", - key: "deepStage", - x: px(100), - y: px(430), - w: px(200), - h: px(40), - }, + { + label: 'Sleep Score', + key: 'sleepScore', + x: px(100), + y: px(80), + w: px(200), + h: px(40), + }, + { + label: 'Start & End Time', + key: 'startEndTime', + x: px(100), + y: px(130), + w: px(200), + h: px(40), + }, + { + label: 'Deep Sleep Time', + key: 'deepSleepTime', + x: px(100), + y: px(180), + w: px(200), + h: px(40), + }, + { + label: 'Total Sleep Time', + key: 'totalSleepTime', + x: px(100), + y: px(230), + w: px(200), + h: px(40), + }, + { + label: 'Wake Stage', + key: 'wakeStage', + x: px(100), + y: px(280), + w: px(200), + h: px(40), + }, + { + label: 'REM Stage', + key: 'remStage', + x: px(100), + y: px(330), + w: px(200), + h: px(40), + }, + { + label: 'Light Stage', + key: 'lightStage', + x: px(100), + y: px(380), + w: px(200), + h: px(40), + }, + { + label: 'Deep Stage', + key: 'deepStage', + x: px(100), + y: px(430), + w: px(200), + h: px(40), + }, ]; export const BACK_BUTTON = { - x: px(150), - y: px(325), - w: px(200), - h: px(50), - text_size: px(25), - radius: px(12), - normal_color: NORMAL_COLOR, - press_color: PRESS_COLOR, - text: "Go Back", + x: px(150), + y: px(325), + w: px(200), + h: px(50), + text_size: px(25), + radius: px(12), + normal_color: NORMAL_COLOR, + press_color: PRESS_COLOR, + text: 'Go Back', }; diff --git a/app/page/rescuePlanPage.js b/app/page/rescuePlanPage.js index ba950f3..a112aaf 100644 --- a/app/page/rescuePlanPage.js +++ b/app/page/rescuePlanPage.js @@ -1,143 +1,143 @@ -import hmUI from "@zos/ui"; -import { push } from "@zos/router"; +import hmUI from '@zos/ui'; +import { push } from '@zos/router'; import { - TOGGLE_OPTIONS, - BACK_BUTTON, -} from "zosLoader:./permissionsPage.[pf].layout.js"; -import { LocalStorage } from "@zos/storage"; // Import LocalStorage only once + TOGGLE_OPTIONS, + BACK_BUTTON, +} from 'zosLoader:./permissionsPage.[pf].layout.js'; +import { LocalStorage } from '@zos/storage'; // Import LocalStorage only once -console.log("Navigated to the permissions page"); +console.log('Navigated to the permissions page'); Page({ - state: { - message: "Permissions Page", - sleepScore: true, - startEndTime: true, - deepSleepTime: true, - totalSleepTime: true, - wakeStage: true, - remStage: true, - lightStage: true, - deepStage: true, - }, - - onInit() { - console.log("Permissions Page onInit invoked"); - this.localStorage = new LocalStorage(); // Initialize LocalStorage once - this.restoreToggleStates(); // Restore saved states when the page is initialized - }, - - build() { - console.log("Permissions Page Build Called"); - - // Display the main title - hmUI.createWidget(hmUI.widget.TEXT, { - text: this.state.message, - x: 100, - y: 20, - w: 200, - h: 50, - text_size: 24, - color: 0xffffff, - align_h: hmUI.align.CENTER_H, - }); - - // Create toggle switches with their corresponding names - TOGGLE_OPTIONS.forEach((option, index) => { - const checkedValue = - this.state[option.key] !== undefined ? this.state[option.key] : true; - - // Create the switch widget for each option - hmUI.createWidget(hmUI.widget.SLIDE_SWITCH, { - x: option.x + 100, // Position the toggle switch slightly to the right - y: option.y, - w: option.w, - h: option.h, - checked: checkedValue, - color: 0xffffff, // Text color for better visibility - text_size: px(16), // Smaller text size - checked_change_func: (slideSwitch, checked) => { - // Handle toggle change - this.handleToggleChange(option.key, checked); // Call the function for toggle change - }, - }); - - // Create the label (name) for each toggle switch next to it - hmUI.createWidget(hmUI.widget.TEXT, { - text: option.label, - x: option.x, // Position the label next to the toggle - y: option.y + 5, // Adjust the Y position slightly to match the center of the toggle - w: px(100), // Adjust the width for the label - h: option.h, // Keep the same height as the toggle - text_size: px(16), // Smaller text size for the label - color: 0xffffff, // Text color for better visibility - align_h: hmUI.align.LEFT, // Align the text to the left - }); - - console.log(`Created toggle widget and label for: ${option.label}`); - }); - - // Add the back button at the bottom of the page - hmUI.createWidget(hmUI.widget.BUTTON, { - ...BACK_BUTTON, - y: 500, // Adjust Y position for the back button - click_func: () => { - console.log("Back button clicked, preferences saved:"); - - // Log all the permissions and their state - TOGGLE_OPTIONS.forEach((option) => { - const permissionState = this.state[option.key]; - console.log(`${option.label}: ${permissionState}`); - }); - - // Save permissions to localStorage - this.localStorage.setItem( - "userPermissions", - JSON.stringify(this.state), - ); // Store the entire state - - // Log the params being passed to index.js - const paramsToPass = JSON.stringify(this.state); - console.log( - "Passing the following parameters to index.js: ", - paramsToPass, - ); - - // Pass the entire state through params when navigating to index.js - push({ - url: "page/index", - params: paramsToPass, // Pass the state as params - }); - }, - }); - }, - - onDestroy() { - console.log("Permissions Page onDestroy invoked"); - }, - - // Function to handle toggle change and save the state to localStorage - handleToggleChange(toggleId, isChecked) { - // Update the state when the switch is toggled - this.state[toggleId] = isChecked; - console.log(`${toggleId} tracking set to ${isChecked}`); - - // Store updated state to localStorage - this.localStorage.setItem(toggleId, isChecked.toString()); // Store state as a string - }, - - // Function to restore the toggle states from localStorage - restoreToggleStates() { - TOGGLE_OPTIONS.forEach((option) => { - const toggleId = option.key; - - // Retrieve saved state from localStorage - const storedState = this.localStorage.getItem(toggleId); - if (storedState !== null) { - this.state[toggleId] = storedState === "true"; // Convert string to boolean - } - - console.log(`Restored ${toggleId} state: ${this.state[toggleId]}`); - }); - }, + state: { + message: 'Permissions Page', + sleepScore: true, + startEndTime: true, + deepSleepTime: true, + totalSleepTime: true, + wakeStage: true, + remStage: true, + lightStage: true, + deepStage: true, + }, + + onInit() { + console.log('Permissions Page onInit invoked'); + this.localStorage = new LocalStorage(); // Initialize LocalStorage once + this.restoreToggleStates(); // Restore saved states when the page is initialized + }, + + build() { + console.log('Permissions Page Build Called'); + + // Display the main title + hmUI.createWidget(hmUI.widget.TEXT, { + text: this.state.message, + x: 100, + y: 20, + w: 200, + h: 50, + text_size: 24, + color: 0xffffff, + align_h: hmUI.align.CENTER_H, + }); + + // Create toggle switches with their corresponding names + TOGGLE_OPTIONS.forEach((option, index) => { + const checkedValue = + this.state[option.key] !== undefined ? this.state[option.key] : true; + + // Create the switch widget for each option + hmUI.createWidget(hmUI.widget.SLIDE_SWITCH, { + x: option.x + 100, // Position the toggle switch slightly to the right + y: option.y, + w: option.w, + h: option.h, + checked: checkedValue, + color: 0xffffff, // Text color for better visibility + text_size: px(16), // Smaller text size + checked_change_func: (slideSwitch, checked) => { + // Handle toggle change + this.handleToggleChange(option.key, checked); // Call the function for toggle change + }, + }); + + // Create the label (name) for each toggle switch next to it + hmUI.createWidget(hmUI.widget.TEXT, { + text: option.label, + x: option.x, // Position the label next to the toggle + y: option.y + 5, // Adjust the Y position slightly to match the center of the toggle + w: px(100), // Adjust the width for the label + h: option.h, // Keep the same height as the toggle + text_size: px(16), // Smaller text size for the label + color: 0xffffff, // Text color for better visibility + align_h: hmUI.align.LEFT, // Align the text to the left + }); + + console.log(`Created toggle widget and label for: ${option.label}`); + }); + + // Add the back button at the bottom of the page + hmUI.createWidget(hmUI.widget.BUTTON, { + ...BACK_BUTTON, + y: 500, // Adjust Y position for the back button + click_func: () => { + console.log('Back button clicked, preferences saved:'); + + // Log all the permissions and their state + TOGGLE_OPTIONS.forEach((option) => { + const permissionState = this.state[option.key]; + console.log(`${option.label}: ${permissionState}`); + }); + + // Save permissions to localStorage + this.localStorage.setItem( + 'userPermissions', + JSON.stringify(this.state), + ); // Store the entire state + + // Log the params being passed to index.js + const paramsToPass = JSON.stringify(this.state); + console.log( + 'Passing the following parameters to index.js: ', + paramsToPass, + ); + + // Pass the entire state through params when navigating to index.js + push({ + url: 'page/index', + params: paramsToPass, // Pass the state as params + }); + }, + }); + }, + + onDestroy() { + console.log('Permissions Page onDestroy invoked'); + }, + + // Function to handle toggle change and save the state to localStorage + handleToggleChange(toggleId, isChecked) { + // Update the state when the switch is toggled + this.state[toggleId] = isChecked; + console.log(`${toggleId} tracking set to ${isChecked}`); + + // Store updated state to localStorage + this.localStorage.setItem(toggleId, isChecked.toString()); // Store state as a string + }, + + // Function to restore the toggle states from localStorage + restoreToggleStates() { + TOGGLE_OPTIONS.forEach((option) => { + const toggleId = option.key; + + // Retrieve saved state from localStorage + const storedState = this.localStorage.getItem(toggleId); + if (storedState !== null) { + this.state[toggleId] = storedState === 'true'; // Convert string to boolean + } + + console.log(`Restored ${toggleId} state: ${this.state[toggleId]}`); + }); + }, }); diff --git a/app/setting/index.js b/app/setting/index.js index 86bb82d..08b26f1 100644 --- a/app/setting/index.js +++ b/app/setting/index.js @@ -143,4 +143,4 @@ const requestGoogleAuthData = async (authResponse) => { body: body, }); return await data.json(); -}; \ No newline at end of file +}; From f34697b61c8a434cbc415abcc2833066df7105b8 Mon Sep 17 00:00:00 2001 From: Emily Barkley <149705329+EsBarkley@users.noreply.github.com> Date: Tue, 26 Nov 2024 14:13:54 -0700 Subject: [PATCH 08/28] Delete app/page/rescuePlanPage.js Deleted accidentally added rescuePlanPage --- app/page/rescuePlanPage.js | 143 ------------------------------------- 1 file changed, 143 deletions(-) delete mode 100644 app/page/rescuePlanPage.js diff --git a/app/page/rescuePlanPage.js b/app/page/rescuePlanPage.js deleted file mode 100644 index a112aaf..0000000 --- a/app/page/rescuePlanPage.js +++ /dev/null @@ -1,143 +0,0 @@ -import hmUI from '@zos/ui'; -import { push } from '@zos/router'; -import { - TOGGLE_OPTIONS, - BACK_BUTTON, -} from 'zosLoader:./permissionsPage.[pf].layout.js'; -import { LocalStorage } from '@zos/storage'; // Import LocalStorage only once - -console.log('Navigated to the permissions page'); - -Page({ - state: { - message: 'Permissions Page', - sleepScore: true, - startEndTime: true, - deepSleepTime: true, - totalSleepTime: true, - wakeStage: true, - remStage: true, - lightStage: true, - deepStage: true, - }, - - onInit() { - console.log('Permissions Page onInit invoked'); - this.localStorage = new LocalStorage(); // Initialize LocalStorage once - this.restoreToggleStates(); // Restore saved states when the page is initialized - }, - - build() { - console.log('Permissions Page Build Called'); - - // Display the main title - hmUI.createWidget(hmUI.widget.TEXT, { - text: this.state.message, - x: 100, - y: 20, - w: 200, - h: 50, - text_size: 24, - color: 0xffffff, - align_h: hmUI.align.CENTER_H, - }); - - // Create toggle switches with their corresponding names - TOGGLE_OPTIONS.forEach((option, index) => { - const checkedValue = - this.state[option.key] !== undefined ? this.state[option.key] : true; - - // Create the switch widget for each option - hmUI.createWidget(hmUI.widget.SLIDE_SWITCH, { - x: option.x + 100, // Position the toggle switch slightly to the right - y: option.y, - w: option.w, - h: option.h, - checked: checkedValue, - color: 0xffffff, // Text color for better visibility - text_size: px(16), // Smaller text size - checked_change_func: (slideSwitch, checked) => { - // Handle toggle change - this.handleToggleChange(option.key, checked); // Call the function for toggle change - }, - }); - - // Create the label (name) for each toggle switch next to it - hmUI.createWidget(hmUI.widget.TEXT, { - text: option.label, - x: option.x, // Position the label next to the toggle - y: option.y + 5, // Adjust the Y position slightly to match the center of the toggle - w: px(100), // Adjust the width for the label - h: option.h, // Keep the same height as the toggle - text_size: px(16), // Smaller text size for the label - color: 0xffffff, // Text color for better visibility - align_h: hmUI.align.LEFT, // Align the text to the left - }); - - console.log(`Created toggle widget and label for: ${option.label}`); - }); - - // Add the back button at the bottom of the page - hmUI.createWidget(hmUI.widget.BUTTON, { - ...BACK_BUTTON, - y: 500, // Adjust Y position for the back button - click_func: () => { - console.log('Back button clicked, preferences saved:'); - - // Log all the permissions and their state - TOGGLE_OPTIONS.forEach((option) => { - const permissionState = this.state[option.key]; - console.log(`${option.label}: ${permissionState}`); - }); - - // Save permissions to localStorage - this.localStorage.setItem( - 'userPermissions', - JSON.stringify(this.state), - ); // Store the entire state - - // Log the params being passed to index.js - const paramsToPass = JSON.stringify(this.state); - console.log( - 'Passing the following parameters to index.js: ', - paramsToPass, - ); - - // Pass the entire state through params when navigating to index.js - push({ - url: 'page/index', - params: paramsToPass, // Pass the state as params - }); - }, - }); - }, - - onDestroy() { - console.log('Permissions Page onDestroy invoked'); - }, - - // Function to handle toggle change and save the state to localStorage - handleToggleChange(toggleId, isChecked) { - // Update the state when the switch is toggled - this.state[toggleId] = isChecked; - console.log(`${toggleId} tracking set to ${isChecked}`); - - // Store updated state to localStorage - this.localStorage.setItem(toggleId, isChecked.toString()); // Store state as a string - }, - - // Function to restore the toggle states from localStorage - restoreToggleStates() { - TOGGLE_OPTIONS.forEach((option) => { - const toggleId = option.key; - - // Retrieve saved state from localStorage - const storedState = this.localStorage.getItem(toggleId); - if (storedState !== null) { - this.state[toggleId] = storedState === 'true'; // Convert string to boolean - } - - console.log(`Restored ${toggleId} state: ${this.state[toggleId]}`); - }); - }, -}); From 2923d58edb21f91a24d4b05d34c2eb511d8adc03 Mon Sep 17 00:00:00 2001 From: Emily Barkley <149705329+EsBarkley@users.noreply.github.com> Date: Tue, 26 Nov 2024 14:22:48 -0700 Subject: [PATCH 09/28] Update index.js Fixed asycn and storage --- app/page/index.js | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/app/page/index.js b/app/page/index.js index cca2d01..a0b10ee 100644 --- a/app/page/index.js +++ b/app/page/index.js @@ -13,9 +13,7 @@ import { const permissions = ['device:os.bg_service']; const service = 'app-service/service'; -const storage = getApp()._options.globalData.storage; - -// Initialize the Sleep module +const storage = getApp().globals.storage const sleep = new Sleep(); // Main page setup @@ -97,7 +95,7 @@ Page( build() { hmUI.createWidget(hmUI.widget.BUTTON, { ...START_BUTTON, - click_func: async () => { + click_func: () => { console.log('fetch button clicked'); const token = storage.getKey('token'); if (!token) { @@ -112,7 +110,7 @@ Page( if (checkPermissions()) { startAppService(token); } else { - console.log('Permission denied'); + console.log('permission denied'); } }, }); @@ -278,14 +276,13 @@ const startAppService = (token) => { }); }; -// Asynchronous permission check -const checkPermissions = async () => { - // Query for permissions first - const [permissionResult] = queryPermission({ permissions }); - +const checkPermissions = () => { + const [permissionResult] = queryPermission({ + permissions, + }); if (permissionResult === 2) { - console.log('Permission previously allowed'); - return true; // Permission granted + console.log('permission previously allowed'); + return true; } else { requestPermission({ permissions, @@ -299,3 +296,4 @@ const checkPermissions = async () => { } return false; }; + From a6e7ef7488c18a15425fac2c64418ad26fd685c6 Mon Sep 17 00:00:00 2001 From: Emil Date: Tue, 26 Nov 2024 14:27:24 -0700 Subject: [PATCH 10/28] Fixed prettier formatting issues --- app/page/index.js | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/app/page/index.js b/app/page/index.js index cca2d01..8c97fe6 100644 --- a/app/page/index.js +++ b/app/page/index.js @@ -13,9 +13,7 @@ import { const permissions = ['device:os.bg_service']; const service = 'app-service/service'; -const storage = getApp()._options.globalData.storage; - -// Initialize the Sleep module +const storage = getApp().globals.storage; const sleep = new Sleep(); // Main page setup @@ -97,7 +95,7 @@ Page( build() { hmUI.createWidget(hmUI.widget.BUTTON, { ...START_BUTTON, - click_func: async () => { + click_func: () => { console.log('fetch button clicked'); const token = storage.getKey('token'); if (!token) { @@ -278,14 +276,13 @@ const startAppService = (token) => { }); }; -// Asynchronous permission check -const checkPermissions = async () => { - // Query for permissions first - const [permissionResult] = queryPermission({ permissions }); - +const checkPermissions = () => { + const [permissionResult] = queryPermission({ + permissions, + }); if (permissionResult === 2) { - console.log('Permission previously allowed'); - return true; // Permission granted + console.log('permission previously allowed'); + return true; } else { requestPermission({ permissions, From 4210f3468b4902da73c1bc0ed0bbbee350626481 Mon Sep 17 00:00:00 2001 From: Emil Date: Tue, 26 Nov 2024 14:45:11 -0700 Subject: [PATCH 11/28] Missed semicolon --- app/page/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/page/index.js b/app/page/index.js index a0b10ee..3910cff 100644 --- a/app/page/index.js +++ b/app/page/index.js @@ -13,7 +13,7 @@ import { const permissions = ['device:os.bg_service']; const service = 'app-service/service'; -const storage = getApp().globals.storage +const storage = getApp().globals.storage; const sleep = new Sleep(); // Main page setup @@ -110,7 +110,7 @@ Page( if (checkPermissions()) { startAppService(token); } else { - console.log('permission denied'); + console.log('Permission denied'); } }, }); From 73b5aedfe75039da8590641aaf806e0fedbddec5 Mon Sep 17 00:00:00 2001 From: Emil Date: Tue, 26 Nov 2024 14:48:47 -0700 Subject: [PATCH 12/28] Prettier Error Fix --- app/page/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/app/page/index.js b/app/page/index.js index 3910cff..8c97fe6 100644 --- a/app/page/index.js +++ b/app/page/index.js @@ -296,4 +296,3 @@ const checkPermissions = () => { } return false; }; - From 5a51663d29e203d66e413aa928b75359d208a773 Mon Sep 17 00:00:00 2001 From: Emily Barkley <149705329+EsBarkley@users.noreply.github.com> Date: Tue, 26 Nov 2024 16:47:01 -0700 Subject: [PATCH 13/28] Update app.json Deleted file path to rescuePlanPage --- app/app.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/app.json b/app/app.json index b70b101..760e4e6 100644 --- a/app/app.json +++ b/app/app.json @@ -34,8 +34,7 @@ "page": { "pages": [ "page/index", - "page/permissionsPage", - "page/rescuePlanPage" + "page/permissionsPage" ] }, "app-side": { From 2e786c647068eb0676352159780deb12f773f3a2 Mon Sep 17 00:00:00 2001 From: Emily Barkley <149705329+EsBarkley@users.noreply.github.com> Date: Tue, 26 Nov 2024 16:59:32 -0700 Subject: [PATCH 14/28] Update index.r.layout.js Fixed stop button positioning --- app/page/index.r.layout.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/page/index.r.layout.js b/app/page/index.r.layout.js index 3345606..455053c 100644 --- a/app/page/index.r.layout.js +++ b/app/page/index.r.layout.js @@ -19,11 +19,11 @@ export const START_BUTTON = { }; export const STOP_BUTTON = { - x: px(60), - y: px(300), - w: px(360), - h: px(80), - text_size: px(36), + x: px(260), + y: px(150), + w: px(200), + h: px(60), + text_size: px(30), radius: px(12), normal_color: NORMAL_COLOR, press_color: PRESS_COLOR, From 31f4d8f31cac6476dbed5423853f62442f942abb Mon Sep 17 00:00:00 2001 From: Emil Date: Sat, 18 Jan 2025 15:48:44 -0700 Subject: [PATCH 15/28] Change that separates the sleep permissions stuff to their own separate files --- app/app.json | 2 +- app/page/index.js | 457 +++++++++++++++--------------------- app/page/permissionsPage.js | 2 +- app/page/sleepFunctions.js | 82 +++++++ 4 files changed, 271 insertions(+), 272 deletions(-) create mode 100644 app/page/sleepFunctions.js diff --git a/app/app.json b/app/app.json index b70b101..ae33649 100644 --- a/app/app.json +++ b/app/app.json @@ -35,7 +35,7 @@ "pages": [ "page/index", "page/permissionsPage", - "page/rescuePlanPage" + "page/sleepFunctions" ] }, "app-side": { diff --git a/app/page/index.js b/app/page/index.js index 8c97fe6..dbfef92 100644 --- a/app/page/index.js +++ b/app/page/index.js @@ -3,14 +3,15 @@ import * as appService from '@zos/app-service'; import { queryPermission, requestPermission } from '@zos/app'; import hmUI from '@zos/ui'; import { push } from '@zos/router'; -import { Sleep } from '@zos/sensor'; // Import the Sleep module -import { - START_BUTTON, - SLEEP_BUTTON, - PERMISSIONS_BUTTON, - STOP_BUTTON, +import { + START_BUTTON, + SLEEP_BUTTON, + PERMISSIONS_BUTTON, + STOP_BUTTON } from 'zosLoader:./index.[pf].layout.js'; +import * as sleepUtils from './sleepFunctions'; // Import sleep functions + const permissions = ['device:os.bg_service']; const service = 'app-service/service'; const storage = getApp().globals.storage; @@ -18,281 +19,197 @@ const sleep = new Sleep(); // Main page setup Page( - BasePage({ - state: { - temp: null, - permissions: {}, - }, - onInit(params) { - console.log('Index Page onInit invoked'); - - // Log the entire params object to see the received data - console.log('Received params:', params); - - // Check if params is a string and parse it as JSON - if (typeof params === 'string') { - try { - params = JSON.parse(params); // Convert string to object - console.log('Parsed params:', params); - } catch (error) { - console.error('Error parsing params:', error); - return; - } - } - - // Ensure params is an object with keys - if ( - params && - typeof params === 'object' && - Object.keys(params).length > 1 - ) { - // Iterate through specific keys and store their values in state - const permissionKeys = [ - 'sleepScore', - 'startEndTime', - 'deepSleepTime', - 'totalSleepTime', - 'wakeStage', - 'remStage', - 'lightStage', - 'deepStage', - ]; - - let permissions = {}; // Local object to store permissions - - permissionKeys.forEach((key) => { - if (params.hasOwnProperty(key)) { - permissions[key] = params[key]; - console.log(`Permission: ${key}, Value: ${params[key]}`); - } - }); - - // Store the permissions in state - this.state.permissions = permissions; - console.log('Stored permissions:', this.state.permissions); - } else { - console.log('No permission data received or invalid format.'); - } - - // Get token and store it in storage - this.request({ - method: 'GET_TOKEN', - }) - .then((res) => { - hmUI.showToast({ - text: 'token: ' + res, - }); - storage.setKey('token', res); - }) - .catch((err) => { - hmUI.showToast({ - text: 'Error getting token on load (not signed in?)', - }); - console.error('error getting token', err); - }); - }, - - build() { - hmUI.createWidget(hmUI.widget.BUTTON, { - ...START_BUTTON, - click_func: () => { - console.log('fetch button clicked'); - const token = storage.getKey('token'); - if (!token) { - hmUI.showToast({ - text: 'Please sign in', - }); - console.log('No token found, user needs to sign in'); - return; - } - - // Only proceed if got token - if (checkPermissions()) { - startAppService(token); - } else { - console.log('Permission denied'); - } - }, - }); - - hmUI.createWidget(hmUI.widget.BUTTON, { - ...STOP_BUTTON, - click_func: () => { - console.log('stop button clicked'); - appService.stop({ - file: service, - complete_func: (info) => { - console.log( - 'service stopped complete_func:', - JSON.stringify(info), - ); - hmUI.showToast({ - text: info.result - ? 'Service stopped' - : 'Service failed to stop', - }); - }, - }); - }, - }); + BasePage({ + state: { + temp: null, + permissions: {}, + }, + onInit(params) { + console.log('Index Page onInit invoked'); + + // Log the entire params object to see the received data + console.log('Received params:', params); + + // Check if params is a string and parse it as JSON + if (typeof params === 'string') { + try { + params = JSON.parse(params); // Convert string to object + console.log('Parsed params:', params); + } catch (error) { + console.error('Error parsing params:', error); + return; + } + } + + // Ensure params is an object with keys + if (params && typeof params === 'object' && Object.keys(params).length > 1) { + // Iterate through specific keys and store their values in state + const permissionKeys = [ + 'sleepScore', + 'startEndTime', + 'deepSleepTime', + 'totalSleepTime', + 'wakeStage', + 'remStage', + 'lightStage', + 'deepStage', + ]; + + let permissions = {}; // Local object to store permissions + + permissionKeys.forEach((key) => { + if (params.hasOwnProperty(key)) { + permissions[key] = params[key]; + console.log(`Permission: ${key}, Value: ${params[key]}`); + } + }); + + // Store the permissions in state + this.state.permissions = permissions; + console.log('Stored permissions:', this.state.permissions); + } else { + console.log('No permission data received or invalid format.'); + } + + // Get token and store it in storage + this.request({ + method: 'GET_TOKEN', + }) + .then((res) => { + hmUI.showToast({ + text: 'token: ' + res, + }); + storage.setKey('token', res); + }) + .catch((err) => { + hmUI.showToast({ + text: 'Error getting token on load (not signed in?)', + }); + console.error('error getting token', err); + }); + }, + + build() { + hmUI.createWidget(hmUI.widget.BUTTON, { + ...START_BUTTON, + click_func: () => { + console.log('fetch button clicked'); + const token = storage.getKey('token'); + if (!token) { + hmUI.showToast({ + text: 'Please sign in', + }); + console.log('No token found, user needs to sign in'); + return; + } + + // Only proceed if got token + if (checkPermissions()) { + startAppService(token); + } else { + console.log('Permission denied'); + } + }, + }); + + hmUI.createWidget(hmUI.widget.BUTTON, { + ...STOP_BUTTON, + click_func: () => { + console.log('stop button clicked'); + appService.stop({ + file: service, + complete_func: (info) => { + console.log( + 'service stopped complete_func:', + JSON.stringify(info), + ); + hmUI.showToast({ + text: info.result + ? 'Service stopped' + : 'Service failed to stop', + }); + }, + }); + }, + }); hmUI.createWidget(hmUI.widget.BUTTON, { ...SLEEP_BUTTON, - click_func: this.onClickSleepButton.bind(this), - }); - - hmUI.createWidget(hmUI.widget.BUTTON, { - ...PERMISSIONS_BUTTON, click_func: () => { - console.log('Permissions button clicked'); - push({ - url: 'page/permissionsPage', // No parameters passed here - }); + console.log('Sleep button pressed'); + sleepUtils.onClickSleepButton(permissions); // Ensure this matches the exported function name }, }); - }, - - onDestroy() { - console.log('page onDestroy invoked'); - }, - - onRequest(req, res) { - console.log('page onRequest invoked'); - console.log('req:', req); - console.log('res:', res); - }, - - onCall(req) { - if (req.method === 'SET_TOKEN') { - console.log('SET_TOKEN method invoked'); - storage.setKey('token', req.params.value); - - hmUI.showToast({ - text: 'Token saved ' + JSON.stringify(req.params), - }); - storage.setKey('token', req.params.value); - } - }, - - onClickSleepButton() { - console.log('Sleep button pressed'); - - // Log the current state and permissions to see what data is available - console.log('Current state:', JSON.stringify(this.state)); - - // Access permissions from the state - if (this.state.permissions) { - Object.entries(this.state.permissions).forEach(([key, value]) => { - if (value === true) { - console.log(`Permission for ${key} is granted.`); - - // Actual data extraction based on the granted permission - switch (key) { - case 'sleepScore': - // Get the sleep score using the `getInfo` method - this.getSleepInfo('score'); - break; - case 'startEndTime': - // Get the start and end times (assuming `getInfo` provides this) - this.getSleepInfo('startTime'); - this.getSleepInfo('endTime'); - break; - case 'deepSleepTime': - // Get the deep sleep time using `getInfo` - this.getSleepInfo('deepTime'); - break; - case 'totalSleepTime': - // Get the total sleep time using `getInfo` - this.getSleepInfo('totalTime'); - break; - case 'wakeStage': - // Get the wake stage using `getStageConstantObj` - this.getStageConstantObj('WAKE_STAGE'); - break; - case 'remStage': - // Get the REM stage using `getStageConstantObj` - this.getStageConstantObj('REM_STAGE'); - break; - case 'lightStage': - // Get the light sleep stage using `getStageConstantObj` - this.getStageConstantObj('LIGHT_STAGE'); - break; - case 'deepStage': - // Get the deep sleep stage using `getStageConstantObj` - this.getStageConstantObj('DEEP_STAGE'); - break; - default: - console.log(`No action defined for permission: ${key}`); - } - } else { - console.log(`Permission for ${key} is denied.`); - } - }); - } else { - console.log('No permissions found in state.'); - } - }, - - // Extract sleep info (getInfo method) - getSleepInfo(infoKey) { - // Using the ZeppOS Sleep module to fetch the sleep info - const info = sleep.getInfo(); - - if (info && info.hasOwnProperty(infoKey)) { - console.log(`${infoKey}: ${info[infoKey]}`); - } else { - console.log(`No data for ${infoKey}`); - } - }, - - // Extract stage constant - getStageConstantObj(stageKey) { - // Using the ZeppOS Sleep module to fetch stage constants - const sleepStageConstants = sleep.getStageConstantObj(); - - if (sleepStageConstants && sleepStageConstants.hasOwnProperty(stageKey)) { - console.log(`${stageKey}: ${sleepStageConstants[stageKey]}`); - } else { - console.log(`No data for ${stageKey}`); - } - }, - }), + + hmUI.createWidget(hmUI.widget.BUTTON, { + ...PERMISSIONS_BUTTON, + click_func: () => { + console.log('Permissions button clicked'); + push({ + url: 'page/permissionsPage', // No parameters passed here + }); + }, + }); + }, + + onDestroy() { + console.log('page onDestroy invoked'); + }, + + onRequest(req, res) { + console.log('page onRequest invoked'); + console.log('req:', req); + console.log('res:', res); + }, + + onCall(req) { + if (req.method === 'SET_TOKEN') { + console.log('SET_TOKEN method invoked'); + storage.setKey('token', req.params.value); + + hmUI.showToast({ + text: 'Token saved ' + JSON.stringify(req.params), + }); + storage.setKey('token', req.params.value); + } + }, + }), ); // Service-related functions const startAppService = (token) => { - console.log('startAppService invoked'); - console.log(`starting service: ${service}`); - appService.start({ - file: service, - complete_func: (info) => { - console.log('service started complete_func:', JSON.stringify(info)); - hmUI.showToast({ - text: info.result - ? 'Service started' + token - : 'Service failed to start', - }); - }, - }); + console.log('startAppService invoked'); + console.log(`starting service: ${service}`); + appService.start({ + file: service, + complete_func: (info) => { + console.log('service started complete_func:', JSON.stringify(info)); + hmUI.showToast({ + text: info.result + ? 'Service started' + token + : 'Service failed to start', + }); + }, + }); }; const checkPermissions = () => { - const [permissionResult] = queryPermission({ - permissions, - }); - if (permissionResult === 2) { - console.log('permission previously allowed'); - return true; - } else { - requestPermission({ - permissions, - callback: ([result]) => { - if (result === 2) { - console.log('permission granted'); - return true; - } - }, - }); - } - return false; + const [permissionResult] = queryPermission({ + permissions, + }); + if (permissionResult === 2) { + console.log('permission previously allowed'); + return true; + } else { + requestPermission({ + permissions, + callback: ([result]) => { + if (result === 2) { + console.log('permission granted'); + return true; + } + }, + }); + } + return false; }; diff --git a/app/page/permissionsPage.js b/app/page/permissionsPage.js index a112aaf..8874ee4 100644 --- a/app/page/permissionsPage.js +++ b/app/page/permissionsPage.js @@ -4,7 +4,7 @@ import { TOGGLE_OPTIONS, BACK_BUTTON, } from 'zosLoader:./permissionsPage.[pf].layout.js'; -import { LocalStorage } from '@zos/storage'; // Import LocalStorage only once +import { LocalStorage } from '@zos/storage'; console.log('Navigated to the permissions page'); diff --git a/app/page/sleepFunctions.js b/app/page/sleepFunctions.js new file mode 100644 index 0000000..fa4d3cf --- /dev/null +++ b/app/page/sleepFunctions.js @@ -0,0 +1,82 @@ +import { Sleep } from '@zos/sensor'; + +const sleep = new Sleep(); + +/** + * Extract sleep information by key. + * @param {string} infoKey - The key to retrieve from sleep.getInfo(). + */ +export const getSleepInfo = (infoKey) => { + const info = sleep.getInfo(); + if (info && Object.prototype.hasOwnProperty.call(info, infoKey)) { + console.log(`${infoKey}: ${info[infoKey]}`); + } else { + console.warn(`No data available for ${infoKey}.`); + } +}; + +/** + * Extract sleep stage constant by key. + * @param {string} stageKey - The key to retrieve from sleep.getStageConstantObj(). + */ +export const getStageConstantObj = (stageKey) => { + const sleepStageConstants = sleep.getStageConstantObj(); + if (sleepStageConstants && Object.prototype.hasOwnProperty.call(sleepStageConstants, stageKey)) { + console.log(`${stageKey}: ${sleepStageConstants[stageKey]}`); + } else { + console.warn(`No data available for ${stageKey}.`); + } +}; + +/** + * Handle the sleep button click. + * @param {object} permissions - The permissions object containing permission states. + */ +export const handleSleepButtonClick = (permissions) => { + console.log('Sleep button pressed'); + console.log('Current permissions:', JSON.stringify(permissions, null, 2)); + + // Ensure permissions object is valid + if (permissions) { + Object.entries(permissions).forEach(([key, value]) => { + if (value === true) { + console.log(`Permission for ${key} is granted.`); + + // Extract and log data based on the granted permission + switch (key) { + case 'sleepScore': + getSleepInfo('score'); + break; + case 'startEndTime': + getSleepInfo('startTime'); + getSleepInfo('endTime'); + break; + case 'deepSleepTime': + getSleepInfo('deepTime'); + break; + case 'totalSleepTime': + getSleepInfo('totalTime'); + break; + case 'wakeStage': + getStageConstantObj('WAKE_STAGE'); + break; + case 'remStage': + getStageConstantObj('REM_STAGE'); + break; + case 'lightStage': + getStageConstantObj('LIGHT_STAGE'); + break; + case 'deepStage': + getStageConstantObj('DEEP_STAGE'); + break; + default: + console.log(`No action defined for permission: ${key}`); + } + } else { + console.warn(`Permission for ${key} is denied.`); + } + }); + } else { + console.warn('No permissions object provided.'); + } +}; From c0b2bfeaa64a824df5c595051c32696c59a1df93 Mon Sep 17 00:00:00 2001 From: Emil Date: Sat, 18 Jan 2025 16:01:55 -0700 Subject: [PATCH 16/28] updated app.json --- app/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/app.json b/app/app.json index ae33649..39c1b01 100644 --- a/app/app.json +++ b/app/app.json @@ -35,7 +35,7 @@ "pages": [ "page/index", "page/permissionsPage", - "page/sleepFunctions" + "page/sleepFunctions" ] }, "app-side": { From b83f0f56de17f9fb75431ad3b7b5157d77592157 Mon Sep 17 00:00:00 2001 From: Emil Date: Sun, 19 Jan 2025 00:46:14 -0700 Subject: [PATCH 17/28] Separate the sleep functions from the index.js file --- app/google-api-constants.example.js | 5 - app/page/index.js | 383 ++++++++++++++------------- app/page/index.r.layout.js | 2 +- app/page/permissionsPage.js | 4 +- app/page/permissionsPage.r.layout.js | 2 +- app/page/sleepFunctions.js | 153 ++++++----- 6 files changed, 281 insertions(+), 268 deletions(-) delete mode 100644 app/google-api-constants.example.js diff --git a/app/google-api-constants.example.js b/app/google-api-constants.example.js deleted file mode 100644 index e269cbf..0000000 --- a/app/google-api-constants.example.js +++ /dev/null @@ -1,5 +0,0 @@ -// You should create a `google-api.js` file that has your Google API related constants -export const GOOGLE_API_CLIENT_ID = 'client-id-here'; -export const GOOGLE_API_CLIENT_SECRET = 'client-secret-here'; -export const GOOGLE_API_REDIRECT_URI = - 'https://zepp-os.zepp.com/app-settings/redirect.html'; diff --git a/app/page/index.js b/app/page/index.js index dbfef92..e2e2ac6 100644 --- a/app/page/index.js +++ b/app/page/index.js @@ -3,14 +3,19 @@ import * as appService from '@zos/app-service'; import { queryPermission, requestPermission } from '@zos/app'; import hmUI from '@zos/ui'; import { push } from '@zos/router'; -import { - START_BUTTON, - SLEEP_BUTTON, - PERMISSIONS_BUTTON, - STOP_BUTTON +import { Sleep } from '@zos/sensor'; // Import the Sleep module +import { + START_BUTTON, + SLEEP_BUTTON, + PERMISSIONS_BUTTON, + STOP_BUTTON, } from 'zosLoader:./index.[pf].layout.js'; -import * as sleepUtils from './sleepFunctions'; // Import sleep functions +import { + onClickSleepButton, + getSleepInfo, + getStageConstantObj +} from './sleepFunctions.js'; const permissions = ['device:os.bg_service']; const service = 'app-service/service'; @@ -19,197 +24,201 @@ const sleep = new Sleep(); // Main page setup Page( - BasePage({ - state: { - temp: null, - permissions: {}, - }, - onInit(params) { - console.log('Index Page onInit invoked'); - - // Log the entire params object to see the received data - console.log('Received params:', params); - - // Check if params is a string and parse it as JSON - if (typeof params === 'string') { - try { - params = JSON.parse(params); // Convert string to object - console.log('Parsed params:', params); - } catch (error) { - console.error('Error parsing params:', error); - return; - } - } - - // Ensure params is an object with keys - if (params && typeof params === 'object' && Object.keys(params).length > 1) { - // Iterate through specific keys and store their values in state - const permissionKeys = [ - 'sleepScore', - 'startEndTime', - 'deepSleepTime', - 'totalSleepTime', - 'wakeStage', - 'remStage', - 'lightStage', - 'deepStage', - ]; - - let permissions = {}; // Local object to store permissions - - permissionKeys.forEach((key) => { - if (params.hasOwnProperty(key)) { - permissions[key] = params[key]; - console.log(`Permission: ${key}, Value: ${params[key]}`); - } - }); - - // Store the permissions in state - this.state.permissions = permissions; - console.log('Stored permissions:', this.state.permissions); - } else { - console.log('No permission data received or invalid format.'); - } - - // Get token and store it in storage - this.request({ - method: 'GET_TOKEN', - }) - .then((res) => { - hmUI.showToast({ - text: 'token: ' + res, - }); - storage.setKey('token', res); - }) - .catch((err) => { - hmUI.showToast({ - text: 'Error getting token on load (not signed in?)', - }); - console.error('error getting token', err); - }); - }, - - build() { - hmUI.createWidget(hmUI.widget.BUTTON, { - ...START_BUTTON, - click_func: () => { - console.log('fetch button clicked'); - const token = storage.getKey('token'); - if (!token) { - hmUI.showToast({ - text: 'Please sign in', - }); - console.log('No token found, user needs to sign in'); - return; - } - - // Only proceed if got token - if (checkPermissions()) { - startAppService(token); - } else { - console.log('Permission denied'); - } - }, - }); - - hmUI.createWidget(hmUI.widget.BUTTON, { - ...STOP_BUTTON, - click_func: () => { - console.log('stop button clicked'); - appService.stop({ - file: service, - complete_func: (info) => { - console.log( - 'service stopped complete_func:', - JSON.stringify(info), - ); - hmUI.showToast({ - text: info.result - ? 'Service stopped' - : 'Service failed to stop', - }); - }, - }); - }, - }); + BasePage({ + state: { + temp: null, + permissions: {}, // Will hold the permissions data + }, + onInit(params) { + console.log('Index Page onInit invoked'); + + // Log the entire params object to see the received data + console.log('Received params:', params); + + // Check if params is a string and parse it as JSON + if (typeof params === 'string') { + try { + params = JSON.parse(params); // Convert string to object + console.log('Parsed params:', params); + } catch (error) { + console.error('Error parsing params:', error); + return; + } + } + + // Ensure params is an object with keys + if (params && typeof params === 'object' && Object.keys(params).length > 1) { + + // Iterate through specific keys and store their values in state + const permissionKeys = [ + 'sleepScore', + 'startEndTime', + 'deepSleepTime', + 'totalSleepTime', + 'wakeStage', + 'remStage', + 'lightStage', + 'deepStage', + ]; + + let permissions = {}; // Local object to store permissions + + permissionKeys.forEach((key) => { + if (params.hasOwnProperty(key)) { + permissions[key] = params[key]; + console.log(`Permission: ${key}, Value: ${params[key]}`); + } + }); + + // Store the permissions in state + this.state.permissions = permissions; + console.log('Stored permissions:', this.state.permissions); + } else { + console.log('No permission data received or invalid format.'); + } + + // Get token and store it in storage + this.request({ + method: 'GET_TOKEN', + }) + .then((res) => { + hmUI.showToast({ + text: 'token: ' + res, + }); + storage.setKey('token', res); + }) + .catch((err) => { + hmUI.showToast({ + text: 'Error getting token on load (not signed in?)', + }); + console.error('error getting token', err); + }); + }, + + build() { + hmUI.createWidget(hmUI.widget.BUTTON, { + ...START_BUTTON, + click_func: () => { + console.log('fetch button clicked'); + const token = storage.getKey('token'); + if (!token) { + hmUI.showToast({ + text: 'Please sign in', + }); + console.log('No token found, user needs to sign in'); + return; + } + + // Only proceed if got token + if (checkPermissions()) { + startAppService(token); + } else { + console.log('Permission denied'); + } + }, + }); hmUI.createWidget(hmUI.widget.BUTTON, { - ...SLEEP_BUTTON, + ...STOP_BUTTON, click_func: () => { - console.log('Sleep button pressed'); - sleepUtils.onClickSleepButton(permissions); // Ensure this matches the exported function name + console.log('stop button clicked'); + appService.stop({ + file: service, + complete_func: (info) => { + console.log( + 'service stopped complete_func:', + JSON.stringify(info), + ); + hmUI.showToast({ + text: info.result + ? 'Service stopped' + : 'Service failed to stop', + }); + }, + }); }, }); - - hmUI.createWidget(hmUI.widget.BUTTON, { - ...PERMISSIONS_BUTTON, - click_func: () => { - console.log('Permissions button clicked'); - push({ - url: 'page/permissionsPage', // No parameters passed here - }); - }, - }); - }, - - onDestroy() { - console.log('page onDestroy invoked'); - }, - - onRequest(req, res) { - console.log('page onRequest invoked'); - console.log('req:', req); - console.log('res:', res); - }, - - onCall(req) { - if (req.method === 'SET_TOKEN') { - console.log('SET_TOKEN method invoked'); - storage.setKey('token', req.params.value); - - hmUI.showToast({ - text: 'Token saved ' + JSON.stringify(req.params), - }); - storage.setKey('token', req.params.value); - } - }, - }), + + hmUI.createWidget(hmUI.widget.BUTTON, { + ...SLEEP_BUTTON, + click_func: () => { + const jsonstringPermissions = JSON.stringify(this?.state?.permissions); + console.log('JSON string of permissions:', jsonstringPermissions); + + onClickSleepButton(jsonstringPermissions); + } + }); + + hmUI.createWidget(hmUI.widget.BUTTON, { + ...PERMISSIONS_BUTTON, + click_func: () => { + console.log('Permissions button clicked'); + push({ + url: 'page/permissionsPage', // No parameters passed here + }); + }, + }); + }, + + onDestroy() { + console.log('page onDestroy invoked'); + }, + + onRequest(req, res) { + console.log('page onRequest invoked'); + console.log('req:', req); + console.log('res:', res); + }, + + onCall(req) { + if (req.method === 'SET_TOKEN') { + console.log('SET_TOKEN method invoked'); + storage.setKey('token', req.params.value); + + hmUI.showToast({ + text: 'Token saved ' + JSON.stringify(req.params), + }); + storage.setKey('token', req.params.value); + } + }, + }), + ); // Service-related functions const startAppService = (token) => { - console.log('startAppService invoked'); - console.log(`starting service: ${service}`); - appService.start({ - file: service, - complete_func: (info) => { - console.log('service started complete_func:', JSON.stringify(info)); - hmUI.showToast({ - text: info.result - ? 'Service started' + token - : 'Service failed to start', - }); - }, - }); + console.log('startAppService invoked'); + console.log(`starting service: ${service}`); + appService.start({ + file: service, + complete_func: (info) => { + console.log('service started complete_func:', JSON.stringify(info)); + hmUI.showToast({ + text: info.result + ? 'Service started' + token + : 'Service failed to start', + }); + }, + }); }; const checkPermissions = () => { - const [permissionResult] = queryPermission({ - permissions, - }); - if (permissionResult === 2) { - console.log('permission previously allowed'); - return true; - } else { - requestPermission({ - permissions, - callback: ([result]) => { - if (result === 2) { - console.log('permission granted'); - return true; - } - }, - }); - } - return false; + const [permissionResult] = queryPermission({ + permissions, + }); + if (permissionResult === 2) { + console.log('permission previously allowed'); + return true; + } else { + requestPermission({ + permissions, + callback: ([result]) => { + if (result === 2) { + console.log('permission granted'); + return true; + } + }, + }); + } + return false; }; diff --git a/app/page/index.r.layout.js b/app/page/index.r.layout.js index 455053c..b75c4ca 100644 --- a/app/page/index.r.layout.js +++ b/app/page/index.r.layout.js @@ -52,4 +52,4 @@ export const PERMISSIONS_BUTTON = { normal_color: 0x0352fc, press_color: 0x487ff7, text: 'Permission Data', -}; +}; \ No newline at end of file diff --git a/app/page/permissionsPage.js b/app/page/permissionsPage.js index 8874ee4..11a8c61 100644 --- a/app/page/permissionsPage.js +++ b/app/page/permissionsPage.js @@ -4,7 +4,7 @@ import { TOGGLE_OPTIONS, BACK_BUTTON, } from 'zosLoader:./permissionsPage.[pf].layout.js'; -import { LocalStorage } from '@zos/storage'; +import { LocalStorage } from '@zos/storage'; // Import LocalStorage only once console.log('Navigated to the permissions page'); @@ -140,4 +140,4 @@ Page({ console.log(`Restored ${toggleId} state: ${this.state[toggleId]}`); }); }, -}); +}); \ No newline at end of file diff --git a/app/page/permissionsPage.r.layout.js b/app/page/permissionsPage.r.layout.js index 93ad2cc..98cd67a 100644 --- a/app/page/permissionsPage.r.layout.js +++ b/app/page/permissionsPage.r.layout.js @@ -78,4 +78,4 @@ export const BACK_BUTTON = { normal_color: NORMAL_COLOR, press_color: PRESS_COLOR, text: 'Go Back', -}; +}; \ No newline at end of file diff --git a/app/page/sleepFunctions.js b/app/page/sleepFunctions.js index fa4d3cf..ea69caa 100644 --- a/app/page/sleepFunctions.js +++ b/app/page/sleepFunctions.js @@ -1,82 +1,91 @@ -import { Sleep } from '@zos/sensor'; +import { Sleep } from '@zos/sensor'; // Import the Sleep module const sleep = new Sleep(); -/** - * Extract sleep information by key. - * @param {string} infoKey - The key to retrieve from sleep.getInfo(). - */ -export const getSleepInfo = (infoKey) => { +// Function to handle the sleep button click and permissions +export function onClickSleepButton(jsonstringPermissions) { + console.log('Sleep button pressed. in sleepFunctions.js'); + + // Log the received JSON string of permissions + console.log('Received JSON string of permissions:', jsonstringPermissions); + + try { + // Parse the JSON string to access the permissions as an object + const permissions = JSON.parse(jsonstringPermissions); + + // Log the parsed permissions object + console.log('Parsed permissions:', permissions); + + if (permissions) { + Object.entries(permissions).forEach(([key, value]) => { + if (value === true) { + console.log(`Permission for ${key} is granted.`); + + // Actual data extraction based on the granted permission + switch (key) { + case 'sleepScore': + getSleepInfo('score'); + break; + case 'startEndTime': + getSleepInfo('startTime'); + getSleepInfo('endTime'); + break; + case 'deepSleepTime': + getSleepInfo('deepTime'); + break; + case 'totalSleepTime': + getSleepInfo('totalTime'); + break; + case 'wakeStage': + getStageConstantObj('WAKE_STAGE'); + break; + case 'remStage': + getStageConstantObj('REM_STAGE'); + break; + case 'lightStage': + getStageConstantObj('LIGHT_STAGE'); + break; + case 'deepStage': + getStageConstantObj('DEEP_STAGE'); + break; + default: + console.log(`No action defined for permission: ${key}`); + } + } else { + console.log(`Permission for ${key} is denied.`); + } + }); + } else { + console.log('No permissions found in the parsed object.'); + } + } catch (error) { + console.error('Error parsing permissions JSON:', error); + } + } + + // Extract sleep info (getInfo method) + export function getSleepInfo(infoKey) { const info = sleep.getInfo(); - if (info && Object.prototype.hasOwnProperty.call(info, infoKey)) { - console.log(`${infoKey}: ${info[infoKey]}`); + + if (info) { + if (info.hasOwnProperty(infoKey)) { + console.log(`${infoKey}: ${info[infoKey]}`); + } else { + console.log(`No data for ${infoKey}`); + } } else { - console.warn(`No data available for ${infoKey}.`); + console.log('No sleep data available'); } -}; + } -/** - * Extract sleep stage constant by key. - * @param {string} stageKey - The key to retrieve from sleep.getStageConstantObj(). - */ -export const getStageConstantObj = (stageKey) => { + // Extract stage constant + export function getStageConstantObj(stageKey) { const sleepStageConstants = sleep.getStageConstantObj(); - if (sleepStageConstants && Object.prototype.hasOwnProperty.call(sleepStageConstants, stageKey)) { - console.log(`${stageKey}: ${sleepStageConstants[stageKey]}`); - } else { - console.warn(`No data available for ${stageKey}.`); - } -}; - -/** - * Handle the sleep button click. - * @param {object} permissions - The permissions object containing permission states. - */ -export const handleSleepButtonClick = (permissions) => { - console.log('Sleep button pressed'); - console.log('Current permissions:', JSON.stringify(permissions, null, 2)); - - // Ensure permissions object is valid - if (permissions) { - Object.entries(permissions).forEach(([key, value]) => { - if (value === true) { - console.log(`Permission for ${key} is granted.`); - - // Extract and log data based on the granted permission - switch (key) { - case 'sleepScore': - getSleepInfo('score'); - break; - case 'startEndTime': - getSleepInfo('startTime'); - getSleepInfo('endTime'); - break; - case 'deepSleepTime': - getSleepInfo('deepTime'); - break; - case 'totalSleepTime': - getSleepInfo('totalTime'); - break; - case 'wakeStage': - getStageConstantObj('WAKE_STAGE'); - break; - case 'remStage': - getStageConstantObj('REM_STAGE'); - break; - case 'lightStage': - getStageConstantObj('LIGHT_STAGE'); - break; - case 'deepStage': - getStageConstantObj('DEEP_STAGE'); - break; - default: - console.log(`No action defined for permission: ${key}`); - } - } else { - console.warn(`Permission for ${key} is denied.`); - } - }); + + if (sleepStageConstants && sleepStageConstants.hasOwnProperty(stageKey)) { + console.log(`${stageKey}: ${sleepStageConstants[stageKey]}`); } else { - console.warn('No permissions object provided.'); + console.log(`No data for ${stageKey}`); } -}; + } + \ No newline at end of file From a88714c73e8e4ec0affa4630527a5b2fd4a1ed48 Mon Sep 17 00:00:00 2001 From: Emil Date: Sun, 19 Jan 2025 00:46:14 -0700 Subject: [PATCH 18/28] Created the sleepFunctions.js file, which separates the sleep functions from the index.js file --- app/google-api-constants.example.js | 5 - app/page/index.js | 383 ++++++++++++++------------- app/page/index.r.layout.js | 2 +- app/page/permissionsPage.js | 4 +- app/page/permissionsPage.r.layout.js | 2 +- app/page/sleepFunctions.js | 153 ++++++----- 6 files changed, 281 insertions(+), 268 deletions(-) delete mode 100644 app/google-api-constants.example.js diff --git a/app/google-api-constants.example.js b/app/google-api-constants.example.js deleted file mode 100644 index e269cbf..0000000 --- a/app/google-api-constants.example.js +++ /dev/null @@ -1,5 +0,0 @@ -// You should create a `google-api.js` file that has your Google API related constants -export const GOOGLE_API_CLIENT_ID = 'client-id-here'; -export const GOOGLE_API_CLIENT_SECRET = 'client-secret-here'; -export const GOOGLE_API_REDIRECT_URI = - 'https://zepp-os.zepp.com/app-settings/redirect.html'; diff --git a/app/page/index.js b/app/page/index.js index dbfef92..e2e2ac6 100644 --- a/app/page/index.js +++ b/app/page/index.js @@ -3,14 +3,19 @@ import * as appService from '@zos/app-service'; import { queryPermission, requestPermission } from '@zos/app'; import hmUI from '@zos/ui'; import { push } from '@zos/router'; -import { - START_BUTTON, - SLEEP_BUTTON, - PERMISSIONS_BUTTON, - STOP_BUTTON +import { Sleep } from '@zos/sensor'; // Import the Sleep module +import { + START_BUTTON, + SLEEP_BUTTON, + PERMISSIONS_BUTTON, + STOP_BUTTON, } from 'zosLoader:./index.[pf].layout.js'; -import * as sleepUtils from './sleepFunctions'; // Import sleep functions +import { + onClickSleepButton, + getSleepInfo, + getStageConstantObj +} from './sleepFunctions.js'; const permissions = ['device:os.bg_service']; const service = 'app-service/service'; @@ -19,197 +24,201 @@ const sleep = new Sleep(); // Main page setup Page( - BasePage({ - state: { - temp: null, - permissions: {}, - }, - onInit(params) { - console.log('Index Page onInit invoked'); - - // Log the entire params object to see the received data - console.log('Received params:', params); - - // Check if params is a string and parse it as JSON - if (typeof params === 'string') { - try { - params = JSON.parse(params); // Convert string to object - console.log('Parsed params:', params); - } catch (error) { - console.error('Error parsing params:', error); - return; - } - } - - // Ensure params is an object with keys - if (params && typeof params === 'object' && Object.keys(params).length > 1) { - // Iterate through specific keys and store their values in state - const permissionKeys = [ - 'sleepScore', - 'startEndTime', - 'deepSleepTime', - 'totalSleepTime', - 'wakeStage', - 'remStage', - 'lightStage', - 'deepStage', - ]; - - let permissions = {}; // Local object to store permissions - - permissionKeys.forEach((key) => { - if (params.hasOwnProperty(key)) { - permissions[key] = params[key]; - console.log(`Permission: ${key}, Value: ${params[key]}`); - } - }); - - // Store the permissions in state - this.state.permissions = permissions; - console.log('Stored permissions:', this.state.permissions); - } else { - console.log('No permission data received or invalid format.'); - } - - // Get token and store it in storage - this.request({ - method: 'GET_TOKEN', - }) - .then((res) => { - hmUI.showToast({ - text: 'token: ' + res, - }); - storage.setKey('token', res); - }) - .catch((err) => { - hmUI.showToast({ - text: 'Error getting token on load (not signed in?)', - }); - console.error('error getting token', err); - }); - }, - - build() { - hmUI.createWidget(hmUI.widget.BUTTON, { - ...START_BUTTON, - click_func: () => { - console.log('fetch button clicked'); - const token = storage.getKey('token'); - if (!token) { - hmUI.showToast({ - text: 'Please sign in', - }); - console.log('No token found, user needs to sign in'); - return; - } - - // Only proceed if got token - if (checkPermissions()) { - startAppService(token); - } else { - console.log('Permission denied'); - } - }, - }); - - hmUI.createWidget(hmUI.widget.BUTTON, { - ...STOP_BUTTON, - click_func: () => { - console.log('stop button clicked'); - appService.stop({ - file: service, - complete_func: (info) => { - console.log( - 'service stopped complete_func:', - JSON.stringify(info), - ); - hmUI.showToast({ - text: info.result - ? 'Service stopped' - : 'Service failed to stop', - }); - }, - }); - }, - }); + BasePage({ + state: { + temp: null, + permissions: {}, // Will hold the permissions data + }, + onInit(params) { + console.log('Index Page onInit invoked'); + + // Log the entire params object to see the received data + console.log('Received params:', params); + + // Check if params is a string and parse it as JSON + if (typeof params === 'string') { + try { + params = JSON.parse(params); // Convert string to object + console.log('Parsed params:', params); + } catch (error) { + console.error('Error parsing params:', error); + return; + } + } + + // Ensure params is an object with keys + if (params && typeof params === 'object' && Object.keys(params).length > 1) { + + // Iterate through specific keys and store their values in state + const permissionKeys = [ + 'sleepScore', + 'startEndTime', + 'deepSleepTime', + 'totalSleepTime', + 'wakeStage', + 'remStage', + 'lightStage', + 'deepStage', + ]; + + let permissions = {}; // Local object to store permissions + + permissionKeys.forEach((key) => { + if (params.hasOwnProperty(key)) { + permissions[key] = params[key]; + console.log(`Permission: ${key}, Value: ${params[key]}`); + } + }); + + // Store the permissions in state + this.state.permissions = permissions; + console.log('Stored permissions:', this.state.permissions); + } else { + console.log('No permission data received or invalid format.'); + } + + // Get token and store it in storage + this.request({ + method: 'GET_TOKEN', + }) + .then((res) => { + hmUI.showToast({ + text: 'token: ' + res, + }); + storage.setKey('token', res); + }) + .catch((err) => { + hmUI.showToast({ + text: 'Error getting token on load (not signed in?)', + }); + console.error('error getting token', err); + }); + }, + + build() { + hmUI.createWidget(hmUI.widget.BUTTON, { + ...START_BUTTON, + click_func: () => { + console.log('fetch button clicked'); + const token = storage.getKey('token'); + if (!token) { + hmUI.showToast({ + text: 'Please sign in', + }); + console.log('No token found, user needs to sign in'); + return; + } + + // Only proceed if got token + if (checkPermissions()) { + startAppService(token); + } else { + console.log('Permission denied'); + } + }, + }); hmUI.createWidget(hmUI.widget.BUTTON, { - ...SLEEP_BUTTON, + ...STOP_BUTTON, click_func: () => { - console.log('Sleep button pressed'); - sleepUtils.onClickSleepButton(permissions); // Ensure this matches the exported function name + console.log('stop button clicked'); + appService.stop({ + file: service, + complete_func: (info) => { + console.log( + 'service stopped complete_func:', + JSON.stringify(info), + ); + hmUI.showToast({ + text: info.result + ? 'Service stopped' + : 'Service failed to stop', + }); + }, + }); }, }); - - hmUI.createWidget(hmUI.widget.BUTTON, { - ...PERMISSIONS_BUTTON, - click_func: () => { - console.log('Permissions button clicked'); - push({ - url: 'page/permissionsPage', // No parameters passed here - }); - }, - }); - }, - - onDestroy() { - console.log('page onDestroy invoked'); - }, - - onRequest(req, res) { - console.log('page onRequest invoked'); - console.log('req:', req); - console.log('res:', res); - }, - - onCall(req) { - if (req.method === 'SET_TOKEN') { - console.log('SET_TOKEN method invoked'); - storage.setKey('token', req.params.value); - - hmUI.showToast({ - text: 'Token saved ' + JSON.stringify(req.params), - }); - storage.setKey('token', req.params.value); - } - }, - }), + + hmUI.createWidget(hmUI.widget.BUTTON, { + ...SLEEP_BUTTON, + click_func: () => { + const jsonstringPermissions = JSON.stringify(this?.state?.permissions); + console.log('JSON string of permissions:', jsonstringPermissions); + + onClickSleepButton(jsonstringPermissions); + } + }); + + hmUI.createWidget(hmUI.widget.BUTTON, { + ...PERMISSIONS_BUTTON, + click_func: () => { + console.log('Permissions button clicked'); + push({ + url: 'page/permissionsPage', // No parameters passed here + }); + }, + }); + }, + + onDestroy() { + console.log('page onDestroy invoked'); + }, + + onRequest(req, res) { + console.log('page onRequest invoked'); + console.log('req:', req); + console.log('res:', res); + }, + + onCall(req) { + if (req.method === 'SET_TOKEN') { + console.log('SET_TOKEN method invoked'); + storage.setKey('token', req.params.value); + + hmUI.showToast({ + text: 'Token saved ' + JSON.stringify(req.params), + }); + storage.setKey('token', req.params.value); + } + }, + }), + ); // Service-related functions const startAppService = (token) => { - console.log('startAppService invoked'); - console.log(`starting service: ${service}`); - appService.start({ - file: service, - complete_func: (info) => { - console.log('service started complete_func:', JSON.stringify(info)); - hmUI.showToast({ - text: info.result - ? 'Service started' + token - : 'Service failed to start', - }); - }, - }); + console.log('startAppService invoked'); + console.log(`starting service: ${service}`); + appService.start({ + file: service, + complete_func: (info) => { + console.log('service started complete_func:', JSON.stringify(info)); + hmUI.showToast({ + text: info.result + ? 'Service started' + token + : 'Service failed to start', + }); + }, + }); }; const checkPermissions = () => { - const [permissionResult] = queryPermission({ - permissions, - }); - if (permissionResult === 2) { - console.log('permission previously allowed'); - return true; - } else { - requestPermission({ - permissions, - callback: ([result]) => { - if (result === 2) { - console.log('permission granted'); - return true; - } - }, - }); - } - return false; + const [permissionResult] = queryPermission({ + permissions, + }); + if (permissionResult === 2) { + console.log('permission previously allowed'); + return true; + } else { + requestPermission({ + permissions, + callback: ([result]) => { + if (result === 2) { + console.log('permission granted'); + return true; + } + }, + }); + } + return false; }; diff --git a/app/page/index.r.layout.js b/app/page/index.r.layout.js index 455053c..b75c4ca 100644 --- a/app/page/index.r.layout.js +++ b/app/page/index.r.layout.js @@ -52,4 +52,4 @@ export const PERMISSIONS_BUTTON = { normal_color: 0x0352fc, press_color: 0x487ff7, text: 'Permission Data', -}; +}; \ No newline at end of file diff --git a/app/page/permissionsPage.js b/app/page/permissionsPage.js index 8874ee4..11a8c61 100644 --- a/app/page/permissionsPage.js +++ b/app/page/permissionsPage.js @@ -4,7 +4,7 @@ import { TOGGLE_OPTIONS, BACK_BUTTON, } from 'zosLoader:./permissionsPage.[pf].layout.js'; -import { LocalStorage } from '@zos/storage'; +import { LocalStorage } from '@zos/storage'; // Import LocalStorage only once console.log('Navigated to the permissions page'); @@ -140,4 +140,4 @@ Page({ console.log(`Restored ${toggleId} state: ${this.state[toggleId]}`); }); }, -}); +}); \ No newline at end of file diff --git a/app/page/permissionsPage.r.layout.js b/app/page/permissionsPage.r.layout.js index 93ad2cc..98cd67a 100644 --- a/app/page/permissionsPage.r.layout.js +++ b/app/page/permissionsPage.r.layout.js @@ -78,4 +78,4 @@ export const BACK_BUTTON = { normal_color: NORMAL_COLOR, press_color: PRESS_COLOR, text: 'Go Back', -}; +}; \ No newline at end of file diff --git a/app/page/sleepFunctions.js b/app/page/sleepFunctions.js index fa4d3cf..ea69caa 100644 --- a/app/page/sleepFunctions.js +++ b/app/page/sleepFunctions.js @@ -1,82 +1,91 @@ -import { Sleep } from '@zos/sensor'; +import { Sleep } from '@zos/sensor'; // Import the Sleep module const sleep = new Sleep(); -/** - * Extract sleep information by key. - * @param {string} infoKey - The key to retrieve from sleep.getInfo(). - */ -export const getSleepInfo = (infoKey) => { +// Function to handle the sleep button click and permissions +export function onClickSleepButton(jsonstringPermissions) { + console.log('Sleep button pressed. in sleepFunctions.js'); + + // Log the received JSON string of permissions + console.log('Received JSON string of permissions:', jsonstringPermissions); + + try { + // Parse the JSON string to access the permissions as an object + const permissions = JSON.parse(jsonstringPermissions); + + // Log the parsed permissions object + console.log('Parsed permissions:', permissions); + + if (permissions) { + Object.entries(permissions).forEach(([key, value]) => { + if (value === true) { + console.log(`Permission for ${key} is granted.`); + + // Actual data extraction based on the granted permission + switch (key) { + case 'sleepScore': + getSleepInfo('score'); + break; + case 'startEndTime': + getSleepInfo('startTime'); + getSleepInfo('endTime'); + break; + case 'deepSleepTime': + getSleepInfo('deepTime'); + break; + case 'totalSleepTime': + getSleepInfo('totalTime'); + break; + case 'wakeStage': + getStageConstantObj('WAKE_STAGE'); + break; + case 'remStage': + getStageConstantObj('REM_STAGE'); + break; + case 'lightStage': + getStageConstantObj('LIGHT_STAGE'); + break; + case 'deepStage': + getStageConstantObj('DEEP_STAGE'); + break; + default: + console.log(`No action defined for permission: ${key}`); + } + } else { + console.log(`Permission for ${key} is denied.`); + } + }); + } else { + console.log('No permissions found in the parsed object.'); + } + } catch (error) { + console.error('Error parsing permissions JSON:', error); + } + } + + // Extract sleep info (getInfo method) + export function getSleepInfo(infoKey) { const info = sleep.getInfo(); - if (info && Object.prototype.hasOwnProperty.call(info, infoKey)) { - console.log(`${infoKey}: ${info[infoKey]}`); + + if (info) { + if (info.hasOwnProperty(infoKey)) { + console.log(`${infoKey}: ${info[infoKey]}`); + } else { + console.log(`No data for ${infoKey}`); + } } else { - console.warn(`No data available for ${infoKey}.`); + console.log('No sleep data available'); } -}; + } -/** - * Extract sleep stage constant by key. - * @param {string} stageKey - The key to retrieve from sleep.getStageConstantObj(). - */ -export const getStageConstantObj = (stageKey) => { + // Extract stage constant + export function getStageConstantObj(stageKey) { const sleepStageConstants = sleep.getStageConstantObj(); - if (sleepStageConstants && Object.prototype.hasOwnProperty.call(sleepStageConstants, stageKey)) { - console.log(`${stageKey}: ${sleepStageConstants[stageKey]}`); - } else { - console.warn(`No data available for ${stageKey}.`); - } -}; - -/** - * Handle the sleep button click. - * @param {object} permissions - The permissions object containing permission states. - */ -export const handleSleepButtonClick = (permissions) => { - console.log('Sleep button pressed'); - console.log('Current permissions:', JSON.stringify(permissions, null, 2)); - - // Ensure permissions object is valid - if (permissions) { - Object.entries(permissions).forEach(([key, value]) => { - if (value === true) { - console.log(`Permission for ${key} is granted.`); - - // Extract and log data based on the granted permission - switch (key) { - case 'sleepScore': - getSleepInfo('score'); - break; - case 'startEndTime': - getSleepInfo('startTime'); - getSleepInfo('endTime'); - break; - case 'deepSleepTime': - getSleepInfo('deepTime'); - break; - case 'totalSleepTime': - getSleepInfo('totalTime'); - break; - case 'wakeStage': - getStageConstantObj('WAKE_STAGE'); - break; - case 'remStage': - getStageConstantObj('REM_STAGE'); - break; - case 'lightStage': - getStageConstantObj('LIGHT_STAGE'); - break; - case 'deepStage': - getStageConstantObj('DEEP_STAGE'); - break; - default: - console.log(`No action defined for permission: ${key}`); - } - } else { - console.warn(`Permission for ${key} is denied.`); - } - }); + + if (sleepStageConstants && sleepStageConstants.hasOwnProperty(stageKey)) { + console.log(`${stageKey}: ${sleepStageConstants[stageKey]}`); } else { - console.warn('No permissions object provided.'); + console.log(`No data for ${stageKey}`); } -}; + } + \ No newline at end of file From 71250ab40a3b7d8fb20fb141bc6d673c49ff354b Mon Sep 17 00:00:00 2001 From: Emil Date: Sun, 19 Jan 2025 00:52:56 -0700 Subject: [PATCH 19/28] changed file name --- app/google-api-constants.example.js | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 app/google-api-constants.example.js diff --git a/app/google-api-constants.example.js b/app/google-api-constants.example.js new file mode 100644 index 0000000..e269cbf --- /dev/null +++ b/app/google-api-constants.example.js @@ -0,0 +1,5 @@ +// You should create a `google-api.js` file that has your Google API related constants +export const GOOGLE_API_CLIENT_ID = 'client-id-here'; +export const GOOGLE_API_CLIENT_SECRET = 'client-secret-here'; +export const GOOGLE_API_REDIRECT_URI = + 'https://zepp-os.zepp.com/app-settings/redirect.html'; From b6aec08167e875e6a8082fd9a511a3a9eadaf9bf Mon Sep 17 00:00:00 2001 From: Emil Date: Sun, 19 Jan 2025 00:58:16 -0700 Subject: [PATCH 20/28] added google-api-constants.example.js file --- app/google-api-constants.example.js | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 app/google-api-constants.example.js diff --git a/app/google-api-constants.example.js b/app/google-api-constants.example.js deleted file mode 100644 index e269cbf..0000000 --- a/app/google-api-constants.example.js +++ /dev/null @@ -1,5 +0,0 @@ -// You should create a `google-api.js` file that has your Google API related constants -export const GOOGLE_API_CLIENT_ID = 'client-id-here'; -export const GOOGLE_API_CLIENT_SECRET = 'client-secret-here'; -export const GOOGLE_API_REDIRECT_URI = - 'https://zepp-os.zepp.com/app-settings/redirect.html'; From 1f61a5549730a903286104674e844310ca5c5591 Mon Sep 17 00:00:00 2001 From: Emil Date: Sun, 19 Jan 2025 00:59:07 -0700 Subject: [PATCH 21/28] added google-api-constants.example.js file --- app/google-api-constants.example.js | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 app/google-api-constants.example.js diff --git a/app/google-api-constants.example.js b/app/google-api-constants.example.js new file mode 100644 index 0000000..e269cbf --- /dev/null +++ b/app/google-api-constants.example.js @@ -0,0 +1,5 @@ +// You should create a `google-api.js` file that has your Google API related constants +export const GOOGLE_API_CLIENT_ID = 'client-id-here'; +export const GOOGLE_API_CLIENT_SECRET = 'client-secret-here'; +export const GOOGLE_API_REDIRECT_URI = + 'https://zepp-os.zepp.com/app-settings/redirect.html'; From e2857eaca79fcbd7da0621a8e0e48a3b8ef665ae Mon Sep 17 00:00:00 2001 From: Emil Date: Sun, 19 Jan 2025 01:00:22 -0700 Subject: [PATCH 22/28] added file --- app/google-api-constants.example.js | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 app/google-api-constants.example.js diff --git a/app/google-api-constants.example.js b/app/google-api-constants.example.js new file mode 100644 index 0000000..e269cbf --- /dev/null +++ b/app/google-api-constants.example.js @@ -0,0 +1,5 @@ +// You should create a `google-api.js` file that has your Google API related constants +export const GOOGLE_API_CLIENT_ID = 'client-id-here'; +export const GOOGLE_API_CLIENT_SECRET = 'client-secret-here'; +export const GOOGLE_API_REDIRECT_URI = + 'https://zepp-os.zepp.com/app-settings/redirect.html'; From 9fcc287148710db8713bcbafcdefa7e6ce1b150d Mon Sep 17 00:00:00 2001 From: Emil Date: Sun, 19 Jan 2025 01:02:47 -0700 Subject: [PATCH 23/28] Fixed formatting in sleepFunctions.js --- app/page/sleepFunctions.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app/page/sleepFunctions.js b/app/page/sleepFunctions.js index ea69caa..877a188 100644 --- a/app/page/sleepFunctions.js +++ b/app/page/sleepFunctions.js @@ -1,3 +1,4 @@ + import { Sleep } from '@zos/sensor'; // Import the Sleep module const sleep = new Sleep(); From 9f59b0d96e0212d0020caccc60f38fb6f70d034f Mon Sep 17 00:00:00 2001 From: Emily Barkley <149705329+EsBarkley@users.noreply.github.com> Date: Sun, 19 Jan 2025 19:33:11 -0700 Subject: [PATCH 24/28] Update index.r.layout.js Fixed duplicate coordinates in index.r.layout.js --- app/page/index.r.layout.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/app/page/index.r.layout.js b/app/page/index.r.layout.js index 128ea4f..455053c 100644 --- a/app/page/index.r.layout.js +++ b/app/page/index.r.layout.js @@ -9,7 +9,6 @@ import { export const START_BUTTON = { x: px(60), y: px(300), - y: px(300), w: px(360), h: px(80), text_size: px(36), @@ -20,11 +19,6 @@ export const START_BUTTON = { }; export const STOP_BUTTON = { - x: px(260), - y: px(150), - w: px(200), - h: px(60), - text_size: px(30), x: px(260), y: px(150), w: px(200), From 743bfd5125cb84f65e03e8a875c97e0b97718038 Mon Sep 17 00:00:00 2001 From: Emil Date: Sun, 19 Jan 2025 20:22:52 -0700 Subject: [PATCH 25/28] Separated some widget created in permissionsPage to be created in permissionsPage.layout --- app/page/index.js | 2 +- app/page/index.r.layout.js | 6 ----- app/page/permissionsPage.js | 24 ++++++------------- app/page/permissionsPage.r.layout.js | 35 ++++++++++++++++++++++++++++ 4 files changed, 43 insertions(+), 24 deletions(-) diff --git a/app/page/index.js b/app/page/index.js index 2d9d628..7d0bc29 100644 --- a/app/page/index.js +++ b/app/page/index.js @@ -139,7 +139,7 @@ Page( }, }); - hmUI.createWidget(hmUI.widget.BUTTON, { + hmUI.createWidget(hmUI.widget.BUTTON, { ...SLEEP_BUTTON, click_func: () => { const jsonstringPermissions = JSON.stringify(this?.state?.permissions); diff --git a/app/page/index.r.layout.js b/app/page/index.r.layout.js index 128ea4f..455053c 100644 --- a/app/page/index.r.layout.js +++ b/app/page/index.r.layout.js @@ -9,7 +9,6 @@ import { export const START_BUTTON = { x: px(60), y: px(300), - y: px(300), w: px(360), h: px(80), text_size: px(36), @@ -20,11 +19,6 @@ export const START_BUTTON = { }; export const STOP_BUTTON = { - x: px(260), - y: px(150), - w: px(200), - h: px(60), - text_size: px(30), x: px(260), y: px(150), w: px(200), diff --git a/app/page/permissionsPage.js b/app/page/permissionsPage.js index 11a8c61..df6356e 100644 --- a/app/page/permissionsPage.js +++ b/app/page/permissionsPage.js @@ -3,6 +3,8 @@ import { push } from '@zos/router'; import { TOGGLE_OPTIONS, BACK_BUTTON, + titleText, + createToggleLabel, } from 'zosLoader:./permissionsPage.[pf].layout.js'; import { LocalStorage } from '@zos/storage'; // Import LocalStorage only once @@ -31,15 +33,9 @@ Page({ console.log('Permissions Page Build Called'); // Display the main title + // Need to add to permissionsPage layout file hmUI.createWidget(hmUI.widget.TEXT, { - text: this.state.message, - x: 100, - y: 20, - w: 200, - h: 50, - text_size: 24, - color: 0xffffff, - align_h: hmUI.align.CENTER_H, + ...titleText, }); // Create toggle switches with their corresponding names @@ -62,17 +58,11 @@ Page({ }, }); - // Create the label (name) for each toggle switch next to it + // Create the label for each toggle switch next to it hmUI.createWidget(hmUI.widget.TEXT, { - text: option.label, - x: option.x, // Position the label next to the toggle - y: option.y + 5, // Adjust the Y position slightly to match the center of the toggle - w: px(100), // Adjust the width for the label - h: option.h, // Keep the same height as the toggle - text_size: px(16), // Smaller text size for the label - color: 0xffffff, // Text color for better visibility - align_h: hmUI.align.LEFT, // Align the text to the left + ...createToggleLabel(option), }); + console.log(`Created toggle widget and label for: ${option.label}`); }); diff --git a/app/page/permissionsPage.r.layout.js b/app/page/permissionsPage.r.layout.js index 98cd67a..f6f2824 100644 --- a/app/page/permissionsPage.r.layout.js +++ b/app/page/permissionsPage.r.layout.js @@ -1,5 +1,40 @@ import { px } from '@zos/utils'; import { BUTTON_TEXT, NORMAL_COLOR, PRESS_COLOR } from '../utils/constants'; +import hmUI, { createWidget, widget, align, text_style, prop } from "@zos/ui"; + +/*export const createToggleSwitch = (option, checkedValue, handleToggleChange) => ({ + x: px(option.x + 100), // Position the toggle switch slightly to the right + y: px(option.y), + w: px(option.w), + h: px(option.h), + checked: px(checkedValue), + color: 0xffffff, // Text color for better visibility + text_size: px(16), // Smaller text size +});*/ + +// Function to create a label for a toggle switch +export const createToggleLabel = (option) => ({ + text: option.label, + x: px(option.x), // Position the label next to the toggle + y: px(option.y + 5), // Adjust the Y position slightly to match the center of the toggle + w: px(100), // Adjust the width for the label + h: px(option.h), // Keep the same height as the toggle + text_size: px(16), // Smaller text size for the label + color: 0xffffff, // Text color for better visibility + align_h: hmUI.align.LEFT, // Align the text to the left +}); + +export const titleText = createWidget(widget.TEXT, { + text: "Permissions Page", + x: px(100), + y: px(20), + w: px(200), + h: px(50), + text_size: px(24), + color: 0xffffff, + align_h: hmUI.align.CENTER_H, + text_style: hmUI.text_style.WRAP, +}); export const TOGGLE_OPTIONS = [ { From dff1ec5b81bd70661fb8ad7956ca6b065d013d70 Mon Sep 17 00:00:00 2001 From: Emil Date: Mon, 20 Jan 2025 00:09:39 -0700 Subject: [PATCH 26/28] Fixed formatting in index.js --- app/page/index.js | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/app/page/index.js b/app/page/index.js index 7d0bc29..ab144e6 100644 --- a/app/page/index.js +++ b/app/page/index.js @@ -203,22 +203,22 @@ const startAppService = (token) => { }; const checkPermissions = () => { - const [permissionResult] = queryPermission({ - permissions - }); - if (permissionResult === 2) { - console.log('permission previously allowed'); - return true; - } else { - requestPermission({ - permissions, - callback([result]) { - if (result === 2) { - console.log('permission granted'); - return true; - } - } - }); - } - return false; + const [permissionResult] = queryPermission({ + permissions + }); + if (permissionResult === 2) { + console.log('permission previously allowed'); + return true; + } else { + requestPermission({ + permissions, + callback([result]) { + if (result === 2) { + console.log('permission granted'); + return true; + } + } + }); + } + return false; } \ No newline at end of file From e1055351eb966c2b2db2fe013cfe75bdd31bb98f Mon Sep 17 00:00:00 2001 From: Emil Date: Mon, 20 Jan 2025 00:14:01 -0700 Subject: [PATCH 27/28] Fixed formatting in index.js --- app/page/index.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/app/page/index.js b/app/page/index.js index ab144e6..5b05ab2 100644 --- a/app/page/index.js +++ b/app/page/index.js @@ -204,21 +204,21 @@ const startAppService = (token) => { const checkPermissions = () => { const [permissionResult] = queryPermission({ - permissions + permissions, }); if (permissionResult === 2) { console.log('permission previously allowed'); return true; } else { requestPermission({ - permissions, - callback([result]) { - if (result === 2) { - console.log('permission granted'); - return true; - } - } + permissions, + callback: ([result]) => { + if (result === 2) { + console.log('permission granted'); + return true; + } + }, }); } return false; -} \ No newline at end of file +}; \ No newline at end of file From 437f181c5e2cec1f858c5dea659d5d6ccc66eea4 Mon Sep 17 00:00:00 2001 From: Emil Date: Mon, 20 Jan 2025 00:25:47 -0700 Subject: [PATCH 28/28] Prettier format fix --- app/page/index.js | 46 ++++---- app/page/index.r.layout.js | 8 +- app/page/permissionsPage.js | 3 +- app/page/permissionsPage.r.layout.js | 6 +- app/page/sleepFunctions.js | 168 +++++++++++++-------------- server/server.ts | 38 +++--- 6 files changed, 137 insertions(+), 132 deletions(-) diff --git a/app/page/index.js b/app/page/index.js index 5b05ab2..f7d15b6 100644 --- a/app/page/index.js +++ b/app/page/index.js @@ -1,6 +1,6 @@ -import { BasePage } from '@zeppos/zml/base-page' -import * as appService from "@zos/app-service"; -import { queryPermission, requestPermission } from "@zos/app"; +import { BasePage } from '@zeppos/zml/base-page'; +import * as appService from '@zos/app-service'; +import { queryPermission, requestPermission } from '@zos/app'; import hmUI from '@zos/ui'; import { push } from '@zos/router'; import { Sleep } from '@zos/sensor'; // Import the Sleep module @@ -11,10 +11,10 @@ import { STOP_BUTTON, } from 'zosLoader:./index.[pf].layout.js'; -import { - onClickSleepButton, - getSleepInfo, - getStageConstantObj +import { + onClickSleepButton, + getSleepInfo, + getStageConstantObj, } from './sleepFunctions.js'; const permissions = ['device:os.bg_service']; @@ -30,7 +30,7 @@ Page( permissions: {}, // Will hold the permissions data }, onInit(params) { - console.log('Index Page onInit invoked'); + console.log('Index PageonInit invoked'); // Log the entire params object to see the received data console.log('Received params:', params); @@ -47,8 +47,11 @@ Page( } // Ensure params is an object with keys - if (params && typeof params === 'object' && Object.keys(params).length > 1) { - + if ( + params && + typeof params === 'object' && + Object.keys(params).length > 1 + ) { // Iterate through specific keys and store their values in state const permissionKeys = [ 'sleepScore', @@ -139,15 +142,17 @@ Page( }, }); - hmUI.createWidget(hmUI.widget.BUTTON, { - ...SLEEP_BUTTON, - click_func: () => { - const jsonstringPermissions = JSON.stringify(this?.state?.permissions); - console.log('JSON string of permissions:', jsonstringPermissions); - - onClickSleepButton(jsonstringPermissions); - } - }); + hmUI.createWidget(hmUI.widget.BUTTON, { + ...SLEEP_BUTTON, + click_func: () => { + const jsonstringPermissions = JSON.stringify( + this?.state?.permissions, + ); + console.log('JSON string of permissions:', jsonstringPermissions); + + onClickSleepButton(jsonstringPermissions); + }, + }); hmUI.createWidget(hmUI.widget.BUTTON, { ...PERMISSIONS_BUTTON, @@ -182,7 +187,6 @@ Page( } }, }), - ); // Service-related functions @@ -221,4 +225,4 @@ const checkPermissions = () => { }); } return false; -}; \ No newline at end of file +}; diff --git a/app/page/index.r.layout.js b/app/page/index.r.layout.js index 455053c..e31ea14 100644 --- a/app/page/index.r.layout.js +++ b/app/page/index.r.layout.js @@ -19,10 +19,10 @@ export const START_BUTTON = { }; export const STOP_BUTTON = { - x: px(260), - y: px(150), - w: px(200), - h: px(60), + x: px(260), + y: px(150), + w: px(200), + h: px(60), text_size: px(30), radius: px(12), normal_color: NORMAL_COLOR, diff --git a/app/page/permissionsPage.js b/app/page/permissionsPage.js index df6356e..036bc15 100644 --- a/app/page/permissionsPage.js +++ b/app/page/permissionsPage.js @@ -62,7 +62,6 @@ Page({ hmUI.createWidget(hmUI.widget.TEXT, { ...createToggleLabel(option), }); - console.log(`Created toggle widget and label for: ${option.label}`); }); @@ -130,4 +129,4 @@ Page({ console.log(`Restored ${toggleId} state: ${this.state[toggleId]}`); }); }, -}); \ No newline at end of file +}); diff --git a/app/page/permissionsPage.r.layout.js b/app/page/permissionsPage.r.layout.js index f6f2824..ba456df 100644 --- a/app/page/permissionsPage.r.layout.js +++ b/app/page/permissionsPage.r.layout.js @@ -1,6 +1,6 @@ import { px } from '@zos/utils'; import { BUTTON_TEXT, NORMAL_COLOR, PRESS_COLOR } from '../utils/constants'; -import hmUI, { createWidget, widget, align, text_style, prop } from "@zos/ui"; +import hmUI, { createWidget, widget, align, text_style, prop } from '@zos/ui'; /*export const createToggleSwitch = (option, checkedValue, handleToggleChange) => ({ x: px(option.x + 100), // Position the toggle switch slightly to the right @@ -25,7 +25,7 @@ export const createToggleLabel = (option) => ({ }); export const titleText = createWidget(widget.TEXT, { - text: "Permissions Page", + text: 'Permissions Page', x: px(100), y: px(20), w: px(200), @@ -113,4 +113,4 @@ export const BACK_BUTTON = { normal_color: NORMAL_COLOR, press_color: PRESS_COLOR, text: 'Go Back', -}; \ No newline at end of file +}; diff --git a/app/page/sleepFunctions.js b/app/page/sleepFunctions.js index 877a188..252b443 100644 --- a/app/page/sleepFunctions.js +++ b/app/page/sleepFunctions.js @@ -1,92 +1,90 @@ - import { Sleep } from '@zos/sensor'; // Import the Sleep module const sleep = new Sleep(); // Function to handle the sleep button click and permissions export function onClickSleepButton(jsonstringPermissions) { - console.log('Sleep button pressed. in sleepFunctions.js'); - - // Log the received JSON string of permissions - console.log('Received JSON string of permissions:', jsonstringPermissions); - - try { - // Parse the JSON string to access the permissions as an object - const permissions = JSON.parse(jsonstringPermissions); - - // Log the parsed permissions object - console.log('Parsed permissions:', permissions); - - if (permissions) { - Object.entries(permissions).forEach(([key, value]) => { - if (value === true) { - console.log(`Permission for ${key} is granted.`); - - // Actual data extraction based on the granted permission - switch (key) { - case 'sleepScore': - getSleepInfo('score'); - break; - case 'startEndTime': - getSleepInfo('startTime'); - getSleepInfo('endTime'); - break; - case 'deepSleepTime': - getSleepInfo('deepTime'); - break; - case 'totalSleepTime': - getSleepInfo('totalTime'); - break; - case 'wakeStage': - getStageConstantObj('WAKE_STAGE'); - break; - case 'remStage': - getStageConstantObj('REM_STAGE'); - break; - case 'lightStage': - getStageConstantObj('LIGHT_STAGE'); - break; - case 'deepStage': - getStageConstantObj('DEEP_STAGE'); - break; - default: - console.log(`No action defined for permission: ${key}`); - } - } else { - console.log(`Permission for ${key} is denied.`); - } - }); - } else { - console.log('No permissions found in the parsed object.'); - } - } catch (error) { - console.error('Error parsing permissions JSON:', error); - } - } - - // Extract sleep info (getInfo method) - export function getSleepInfo(infoKey) { - const info = sleep.getInfo(); - - if (info) { - if (info.hasOwnProperty(infoKey)) { - console.log(`${infoKey}: ${info[infoKey]}`); - } else { - console.log(`No data for ${infoKey}`); - } - } else { - console.log('No sleep data available'); - } - } + console.log('Sleep button pressed. in sleepFunctions.js'); + + // Log the received JSON string of permissions + console.log('Received JSON string of permissions:', jsonstringPermissions); + + try { + // Parse the JSON string to access the permissions as an object + const permissions = JSON.parse(jsonstringPermissions); + + // Log the parsed permissions object + console.log('Parsed permissions:', permissions); + + if (permissions) { + Object.entries(permissions).forEach(([key, value]) => { + if (value === true) { + console.log(`Permission for ${key} is granted.`); + + // Actual data extraction based on the granted permission + switch (key) { + case 'sleepScore': + getSleepInfo('score'); + break; + case 'startEndTime': + getSleepInfo('startTime'); + getSleepInfo('endTime'); + break; + case 'deepSleepTime': + getSleepInfo('deepTime'); + break; + case 'totalSleepTime': + getSleepInfo('totalTime'); + break; + case 'wakeStage': + getStageConstantObj('WAKE_STAGE'); + break; + case 'remStage': + getStageConstantObj('REM_STAGE'); + break; + case 'lightStage': + getStageConstantObj('LIGHT_STAGE'); + break; + case 'deepStage': + getStageConstantObj('DEEP_STAGE'); + break; + default: + console.log(`No action defined for permission: ${key}`); + } + } else { + console.log(`Permission for ${key} is denied.`); + } + }); + } else { + console.log('No permissions found in the parsed object.'); + } + } catch (error) { + console.error('Error parsing permissions JSON:', error); + } +} + +// Extract sleep info (getInfo method) +export function getSleepInfo(infoKey) { + const info = sleep.getInfo(); + + if (info) { + if (info.hasOwnProperty(infoKey)) { + console.log(`${infoKey}: ${info[infoKey]}`); + } else { + console.log(`No data for ${infoKey}`); + } + } else { + console.log('No sleep data available'); + } +} + +// Extract stage constant +export function getStageConstantObj(stageKey) { + const sleepStageConstants = sleep.getStageConstantObj(); - // Extract stage constant - export function getStageConstantObj(stageKey) { - const sleepStageConstants = sleep.getStageConstantObj(); - - if (sleepStageConstants && sleepStageConstants.hasOwnProperty(stageKey)) { - console.log(`${stageKey}: ${sleepStageConstants[stageKey]}`); - } else { - console.log(`No data for ${stageKey}`); - } - } - \ No newline at end of file + if (sleepStageConstants && sleepStageConstants.hasOwnProperty(stageKey)) { + console.log(`${stageKey}: ${sleepStageConstants[stageKey]}`); + } else { + console.log(`No data for ${stageKey}`); + } +} diff --git a/server/server.ts b/server/server.ts index 1a0911d..1cca3ea 100644 --- a/server/server.ts +++ b/server/server.ts @@ -6,27 +6,31 @@ const PORT = 3000; app.use(express.json()); app.post('/post', (req, res) => { - const data = req.body; - // Process stuff here - console.log(`Received data: ${JSON.stringify(data)}`); - res.status(200).json({ message: 'Received data received successfully', data }); + const data = req.body; + // Process stuff here + console.log(`Received data: ${JSON.stringify(data)}`); + res + .status(200) + .json({ message: 'Received data received successfully', data }); }); app.get('/code', (req, res) => { - const code = req.query.code; - // Process stuff here - console.log(`Received code: ${code}`); - console.log(`Total response : ${JSON.stringify(req.query)}`); - res.status(200).json({ message: 'Received code received successfully', code }); + const code = req.query.code; + // Process stuff here + console.log(`Received code: ${code}`); + console.log(`Total response : ${JSON.stringify(req.query)}`); + res + .status(200) + .json({ message: 'Received code received successfully', code }); }); app.listen(PORT, async () => { - console.log(`Server is running on port ${PORT}`); + console.log(`Server is running on port ${PORT}`); - try { - const url = await ngrok.connect(PORT); - console.log(`Ngrok tunnel created: ${url}`); - } catch (error) { - console.error(`Error starting ngrok: ${error}`) - } -}); \ No newline at end of file + try { + const url = await ngrok.connect(PORT); + console.log(`Ngrok tunnel created: ${url}`); + } catch (error) { + console.error(`Error starting ngrok: ${error}`); + } +});