From 1b22858f1f20a773543503ac97c256ba6ca83aa0 Mon Sep 17 00:00:00 2001 From: Albin Medoc Date: Sun, 12 Feb 2023 07:51:52 +0100 Subject: [PATCH 1/2] Allow specifying exact tab --- src/swipe-navigation.ts | 74 +++++++++++++++++++++++++++++++++++------ 1 file changed, 63 insertions(+), 11 deletions(-) diff --git a/src/swipe-navigation.ts b/src/swipe-navigation.ts index d1e51ea..1912751 100644 --- a/src/swipe-navigation.ts +++ b/src/swipe-navigation.ts @@ -149,6 +149,21 @@ class Config { static skip_tabs: number[] = []; static swipe_amount = 0.15; static wrap = true; + // TODO: Load this from yaml config + static specificSwipeConfig = [ + { + swipe_back_index: undefined, + swipe_forward_index: undefined + }, + { + swipe_back_index: 0, + swipe_forward_index: undefined + }, + { + swipe_back_index: 0, + swipe_forward_index: 6 + } + ]; static parseConfig(rawConfig: unknown) { if (instanceOfSwipeNavigationConfig(rawConfig)) { @@ -514,11 +529,23 @@ class SwipeManager { } else { const directionLeft = this.#xDiff < 0; + let nextTabIndex = -1; + + const currentTabIndex = this.#getActiveTabIndex(); + const specificIndex = directionLeft ? Config.specificSwipeConfig[currentTabIndex].swipe_back_index : Config.specificSwipeConfig[currentTabIndex].swipe_forward_index; + if(specificIndex !== undefined) { + if(specificIndex === null) { + logi("Swipe " + (directionLeft ? "left" : "right") + " ignored, disabled on current tab."); + return; + } + logi("Swipe detected, changing tab to specific tab " + specificIndex + "."); + nextTabIndex = specificIndex; + } else { + logi("Swipe detected, changing tab to the " + (directionLeft ? "left" : "right") + "."); - logi("Swipe detected, changing tab to the " + (directionLeft ? "left" : "right") + "."); - - const rtl = PageObjectManager.ha.getDomNode()?.style.direction == "rtl"; - const nextTabIndex = this.#getNextTabIndex(rtl ? !directionLeft : directionLeft); + const rtl = PageObjectManager.ha.getDomNode()?.style.direction == "rtl"; + nextTabIndex = this.#getNextTabIndex(rtl ? !directionLeft : directionLeft); + } if (nextTabIndex >= 0) { this.#click(nextTabIndex, directionLeft); } @@ -532,10 +559,16 @@ class SwipeManager { return Array.from(PageObjectManager.tabsContainer.getDomNode()?.querySelectorAll("paper-tab") ?? []); } - static #getNextTabIndex(directionLeft: boolean) { + static #getActiveTabIndex(): number { const tabs = this.#getTabsArray(); const activeTab = PageObjectManager.tabsContainer.getDomNode()?.querySelector(".iron-selected"); const activeTabIndex = activeTab != null ? tabs.indexOf(activeTab) : -1; + return activeTabIndex; + } + + static #getNextTabIndex(directionLeft: boolean) { + const tabs = this.#getTabsArray(); + const activeTabIndex = this.#getActiveTabIndex(); let nextTabIndex = activeTabIndex; let stopReason = null; @@ -660,14 +693,33 @@ async function getConfiguration() { while (!configRead && configReadingAttempts < 300) { configReadingAttempts++; try { - const rawConfig = ( - ( + const lovelaceConfig = ( PageObjectManager.haPanelLovelace.getDomNode() as ( - HTMLElement & { lovelace: undefined | { config: undefined | { swipe_nav: unknown } } } + HTMLElement & { lovelace: undefined | { config: undefined | {swipe_nav: unknown, views: Array<{path: string; swipe_back?: string | number | null, swipe_forward?: string | number | null}>} } } ) - )?.lovelace?.config?.swipe_nav - ) ?? {}; - Config.parseConfig(rawConfig); + )?.lovelace?.config; + + const lovelaceViews = lovelaceConfig?.views; + + const getIndexByPath = (path: string) => { + return lovelaceViews?.findIndex((view) => view.path === path); + }; + + const globalSwipeConfig = lovelaceConfig?.swipe_nav; + // TODO: Actually load this, save to config. + const specificSwipeConfig = lovelaceViews?.map((view) => { + const back = view.swipe_back; + const forward = view.swipe_forward; + + const back_index = typeof(back) === "string" ? getIndexByPath(back) : back; + const forward_index = typeof(forward) === "string" ? getIndexByPath(forward) : forward; + + return { + swipe_back_index: back_index, + swipe_forward_index: forward_index + }; + }); + Config.parseConfig(globalSwipeConfig); configRead = true; } catch (e) { logw("Error while obtaining config: " + (e instanceof Error ? e.message : e) + ". Retrying..."); From 6689cefa0cc8b65f33b6a6bbb47f5423d007e277 Mon Sep 17 00:00:00 2001 From: Albin Medoc Date: Mon, 13 Feb 2023 11:59:05 +0100 Subject: [PATCH 2/2] feat: allow specifying exact swipe navigation --- src/swipe-navigation.ts | 102 ++++++++++++++++++++++------------------ 1 file changed, 57 insertions(+), 45 deletions(-) diff --git a/src/swipe-navigation.ts b/src/swipe-navigation.ts index 1912751..a9d844a 100644 --- a/src/swipe-navigation.ts +++ b/src/swipe-navigation.ts @@ -131,7 +131,17 @@ const SwipeNavigationConfigSchema = z.object({ skip_hidden: z.boolean().optional(), skip_tabs: z.string().optional(), swipe_amount: z.number().optional(), - wrap: z.boolean().optional() + wrap: z.boolean().optional(), + specific_swipe: z.record(z.object({ + swipe_back: z.nullable(z.union([ + z.number(), + z.string() + ]).optional()), + swipe_forward: z.nullable(z.union([ + z.number(), + z.string() + ]).optional()) + })).optional() }); type SwipeNavigationConfig = z.infer; function instanceOfSwipeNavigationConfig(obj: unknown): obj is SwipeNavigationConfig { @@ -149,23 +159,12 @@ class Config { static skip_tabs: number[] = []; static swipe_amount = 0.15; static wrap = true; - // TODO: Load this from yaml config - static specificSwipeConfig = [ - { - swipe_back_index: undefined, - swipe_forward_index: undefined - }, - { - swipe_back_index: 0, - swipe_forward_index: undefined - }, - { - swipe_back_index: 0, - swipe_forward_index: 6 - } - ]; + static specificSwipeConfig: Record = {}; - static parseConfig(rawConfig: unknown) { + static parseConfig(rawConfig: unknown, lovelaceViews?: Array<{path: string; swipe_back?: string | number | null, swipe_forward?: string | number | null}>) { + if(rawConfig == undefined || lovelaceViews == undefined) { + throw new Error("Config not loaded"); + } if (instanceOfSwipeNavigationConfig(rawConfig)) { if (rawConfig?.animate != undefined) Config.animate = rawConfig.animate; if (rawConfig.logger_level != undefined) { @@ -207,6 +206,34 @@ class Config { if (rawConfig?.swipe_amount != undefined) Config.swipe_amount = rawConfig.swipe_amount / 100.0; if (rawConfig?.wrap != undefined) Config.wrap = rawConfig.wrap; + const mapValueToTabIndex = (value?: number | string | null): number | null | undefined => { + if(typeof(value) != "string") { + return value; + } + let tabIndex = parseInt(value); + if(isNaN(tabIndex)){ + tabIndex = lovelaceViews?.findIndex((view) => view.path === value) ?? undefined; + } + return tabIndex; + }; + + lovelaceViews.map((viewConfig) => { + Config.specificSwipeConfig[(mapValueToTabIndex(viewConfig.path) ?? "").toString()] = { + swipe_back: mapValueToTabIndex(viewConfig.swipe_back), + swipe_forward: mapValueToTabIndex(viewConfig.swipe_forward) + }; + }); + + if(rawConfig?.specific_swipe != undefined) { + Object.keys(rawConfig?.specific_swipe).forEach(viewKey => { + if(rawConfig?.specific_swipe != undefined) { + Config.specificSwipeConfig[(mapValueToTabIndex(viewKey) ?? "").toString()] = { + swipe_back: mapValueToTabIndex(rawConfig?.specific_swipe[viewKey].swipe_back), + swipe_forward: mapValueToTabIndex(rawConfig?.specific_swipe[viewKey].swipe_forward) + }; + } + }); + } return true; } else { loge("Found invalid configuration."); @@ -532,15 +559,18 @@ class SwipeManager { let nextTabIndex = -1; const currentTabIndex = this.#getActiveTabIndex(); - const specificIndex = directionLeft ? Config.specificSwipeConfig[currentTabIndex].swipe_back_index : Config.specificSwipeConfig[currentTabIndex].swipe_forward_index; - if(specificIndex !== undefined) { - if(specificIndex === null) { - logi("Swipe " + (directionLeft ? "left" : "right") + " ignored, disabled on current tab."); - return; + if(Config.specificSwipeConfig != undefined) { + const specificIndex = directionLeft ? Config.specificSwipeConfig[currentTabIndex]?.swipe_back : Config.specificSwipeConfig[currentTabIndex]?.swipe_forward; + if(typeof(specificIndex) !== "undefined") { + if(specificIndex === null) { + logi("Swipe " + (directionLeft ? "left" : "right") + " ignored, disabled on current tab."); + return; + } + logi("Swipe detected, changing tab to specific tab " + specificIndex + "."); + nextTabIndex = specificIndex; } - logi("Swipe detected, changing tab to specific tab " + specificIndex + "."); - nextTabIndex = specificIndex; - } else { + } + if(nextTabIndex == -1) { logi("Swipe detected, changing tab to the " + (directionLeft ? "left" : "right") + "."); const rtl = PageObjectManager.ha.getDomNode()?.style.direction == "rtl"; @@ -690,7 +720,7 @@ async function getConfiguration() { if (PageObjectManager.haPanelLovelace.getDomNode() != null) { let configReadingAttempts = 0; - while (!configRead && configReadingAttempts < 300) { + while (!configRead && configReadingAttempts < 10000) { configReadingAttempts++; try { const lovelaceConfig = ( @@ -700,26 +730,8 @@ async function getConfiguration() { )?.lovelace?.config; const lovelaceViews = lovelaceConfig?.views; - - const getIndexByPath = (path: string) => { - return lovelaceViews?.findIndex((view) => view.path === path); - }; - const globalSwipeConfig = lovelaceConfig?.swipe_nav; - // TODO: Actually load this, save to config. - const specificSwipeConfig = lovelaceViews?.map((view) => { - const back = view.swipe_back; - const forward = view.swipe_forward; - - const back_index = typeof(back) === "string" ? getIndexByPath(back) : back; - const forward_index = typeof(forward) === "string" ? getIndexByPath(forward) : forward; - - return { - swipe_back_index: back_index, - swipe_forward_index: forward_index - }; - }); - Config.parseConfig(globalSwipeConfig); + Config.parseConfig(globalSwipeConfig, lovelaceViews); configRead = true; } catch (e) { logw("Error while obtaining config: " + (e instanceof Error ? e.message : e) + ". Retrying...");