From f39db2cabc7b0946e57bfd573e6a32ecc112b5ac Mon Sep 17 00:00:00 2001 From: Emiel Date: Thu, 5 Sep 2024 01:16:14 +0200 Subject: [PATCH] Fixed tabbar with 0 tabs --- core/assets/js/app.js | 1 + core/assets/js/tabbar.js | 24 +++++++++++--- core/assets/js/viewport.js | 38 ++++++++++++++++++++-- core/frameworks/pixel/components/tabbar.ex | 2 -- core/lib/core_web/live/hook/viewport.ex | 36 ++++++++++++++++---- core/lib/core_web/routes.ex | 1 + core/lib/core_web/viewport_controller.ex | 7 ++++ core/systems/content/html.ex | 14 ++++---- core/test/core_web/ui/timestamp_test.exs | 2 +- 9 files changed, 102 insertions(+), 23 deletions(-) create mode 100644 core/lib/core_web/viewport_controller.ex diff --git a/core/assets/js/app.js b/core/assets/js/app.js index 3b895b357..154e6d4df 100644 --- a/core/assets/js/app.js +++ b/core/assets/js/app.js @@ -36,6 +36,7 @@ window.registerAPNSDeviceToken = registerAPNSDeviceToken; window.addEventListener("phx:page-loading-stop", (info) => { if (info.detail.kind == "initial") { TimeZone.sendToServer(); + Viewport.sendToServer(); } }); diff --git a/core/assets/js/tabbar.js b/core/assets/js/tabbar.js index eff8758db..355fcd436 100644 --- a/core/assets/js/tabbar.js +++ b/core/assets/js/tabbar.js @@ -2,6 +2,7 @@ let tabbarId = ""; export const Tabbar = { mounted() { + console.log("[Tabbar] mounted"); tabbarId = this.el.id; var initialTabId = this.el.dataset.initialTab @@ -21,6 +22,7 @@ export const Tabbar = { }, updated() { + console.log("[Tabbar] updated"); var savedTabId = this.loadActiveTab(); this.show(savedTabId, false); }, @@ -39,22 +41,36 @@ export const Tabbar = { }, saveActiveTab(tabId) { - console.info("saveActiveTab ", tabId); + console.info("[Tabbar] saveActiveTab ", tabId); window.localStorage.setItem(this.getActiveTabKey(), tabId); }, + getTabs() { + return document.querySelectorAll('[id^="tab_"]'); + }, + getFirstTab() { - var firstTab = document.querySelectorAll('[id^="tab_"]')[0]; - return firstTab.id; + var tabs = this.getTabs(); + console.log("tabs", tabs); + if (tabs == undefined) { + return undefined; + } else { + return tabs[0].id; + } }, show(nextTabId, scrollToTop) { + console.log("[Tabbar] nextTabId", nextTabId); + if (nextTabId == undefined) { + return; + } + this.saveActiveTab(nextTabId); var tabs = Array.from(document.querySelectorAll('[id^="tab_"]')); // Skip unknown tab if (!tabs.some((tab) => tab.id === nextTabId)) { - console.warn("Skip unknown tab", nextTabId); + console.warn("[Tabbar] Skip unknown tab", nextTabId); return; } diff --git a/core/assets/js/viewport.js b/core/assets/js/viewport.js index 57ed3f749..a4b108e61 100644 --- a/core/assets/js/viewport.js +++ b/core/assets/js/viewport.js @@ -4,8 +4,8 @@ let resizeHandler; export const Viewport = { mounted() { - // Direct push of current window size to properly update view - this.pushChangeEvent(); + // // Direct push of current window size to properly update view + // this.pushChangeEvent(); window.addEventListener("resize", (event) => { this.pushChangeEvent(); @@ -14,7 +14,7 @@ export const Viewport = { updated() { console.log("[Viewport] updated"); - this.pushChangeEvent(); + // this.pushChangeEvent(); }, pushChangeEvent() { @@ -28,4 +28,36 @@ export const Viewport = { turbolinksDisconnected() { window.removeEventListener("resize", resizeHandler); }, + + sendToServer() { + const viewport = { + width: window.innerWidth, + height: window.innerHeight, + }; + + console.log("[Viewport]", viewport); + + let csrfToken = document + .querySelector("meta[name='csrf-token']") + .getAttribute("content"); + + if (typeof window.localStorage != "undefined") { + try { + var xhr = new XMLHttpRequest(); + xhr.open("POST", "/api/viewport", true); + xhr.setRequestHeader("Content-Type", "application/json"); + xhr.setRequestHeader("x-csrf-token", csrfToken); + xhr.onreadystatechange = function () { + console.log( + "[Veiwport] POST onreadystatechange", + this.status, + this.readyState + ); + }; + xhr.send(`{"viewport": "${viewport}"}`); + } catch (e) { + console.log("[Viewport] Error while sending viewport to server", e); + } + } + }, }; diff --git a/core/frameworks/pixel/components/tabbar.ex b/core/frameworks/pixel/components/tabbar.ex index 06aaf4415..407469f30 100644 --- a/core/frameworks/pixel/components/tabbar.ex +++ b/core/frameworks/pixel/components/tabbar.ex @@ -28,7 +28,6 @@ defmodule Frameworks.Pixel.Tabbar do def container(assigns) do ~H""" - <%= if Enum.count(@tabs) > 0 do %>
<%= if @size == :full do %> <.container_full type={@type} tabs={@tabs} /> @@ -40,7 +39,6 @@ defmodule Frameworks.Pixel.Tabbar do <.container_narrow tabs={@tabs} /> <% end %>
- <% end %> """ end diff --git a/core/lib/core_web/live/hook/viewport.ex b/core/lib/core_web/live/hook/viewport.ex index 0079e9430..361b92b0d 100644 --- a/core/lib/core_web/live/hook/viewport.ex +++ b/core/lib/core_web/live/hook/viewport.ex @@ -12,11 +12,27 @@ defmodule CoreWeb.Live.Hook.Viewport do { :cont, socket + |> set_initial_viewport() |> assign_breakpoint() |> handle_viewport_changed(live_view_module) } end + defp set_initial_viewport(socket) do + case {connected?(socket), get_connect_params(socket)} do + {true, %{"viewport" => viewport}} -> + breakpoint = breakpoint(viewport) + + assign(socket, + viewport: viewport, + breakpoint: breakpoint + ) + + _ -> + socket + end + end + defp handle_viewport_changed(socket, live_view_module) do attach_hook(socket, :handle_viewport_changed, :handle_event, fn "viewport_changed", new_viewport, socket -> @@ -28,14 +44,20 @@ defmodule CoreWeb.Live.Hook.Viewport do end defp update_viewport(socket, live_view_module, new_viewport) do - new_breakpoint = breakpoint(new_viewport) + old_viewport = Map.get(socket.assigns, :viewport, nil) - send(self(), :viewport_updated) + if new_viewport != old_viewport do + new_breakpoint = breakpoint(new_viewport) - socket - |> assign(viewport: new_viewport) - |> assign(breakpoint: new_breakpoint) - |> optional_apply(live_view_module, :update_view_model) - |> optional_apply(live_view_module, :handle_resize) + send(self(), :viewport_updated) + + socket + |> assign(viewport: new_viewport) + |> assign(breakpoint: new_breakpoint) + |> optional_apply(live_view_module, :update_view_model) + |> optional_apply(live_view_module, :handle_resize) + else + socket + end end end diff --git a/core/lib/core_web/routes.ex b/core/lib/core_web/routes.ex index f1571c7cb..0478e3530 100644 --- a/core/lib/core_web/routes.ex +++ b/core/lib/core_web/routes.ex @@ -80,6 +80,7 @@ defmodule CoreWeb.Routes do post("/api/apns-token", APNSDeviceTokenController, :create) post("/api/timezone", TimezoneController, :put_session) + post("/api/viewport", ViewportController, :put_session) end end end diff --git a/core/lib/core_web/viewport_controller.ex b/core/lib/core_web/viewport_controller.ex new file mode 100644 index 000000000..bdd329d3c --- /dev/null +++ b/core/lib/core_web/viewport_controller.ex @@ -0,0 +1,7 @@ +defmodule CoreWeb.ViewportController do + use CoreWeb, :controller + + def put_session(conn, %{"viewport" => viewport}) do + conn |> put_session(:viewport, viewport) |> json(%{}) + end +end diff --git a/core/systems/content/html.ex b/core/systems/content/html.ex index d3fb75559..9bdcee29b 100644 --- a/core/systems/content/html.ex +++ b/core/systems/content/html.ex @@ -103,13 +103,15 @@ defmodule Systems.Content.Html do def tabbar_page(assigns) do ~H""" <.live_workspace title={@title} menus={@menus} modal={@modal} popup={@popup} dialog={@dialog}> - - - + <%= if Enum.count(@tabs) > 0 do %> + + + -
- -
+
+ +
+ <% end %> """ end diff --git a/core/test/core_web/ui/timestamp_test.exs b/core/test/core_web/ui/timestamp_test.exs index 44e3ad4b3..0c74262a5 100644 --- a/core/test/core_web/ui/timestamp_test.exs +++ b/core/test/core_web/ui/timestamp_test.exs @@ -110,6 +110,6 @@ defmodule CoreWeb.Ui.TimestampTest do end def apply_offset(hour, offset) do - Integer.mod(hour + offset, 23) + Integer.mod(hour + offset, 24) end end