From f470119a1bb278033419f5094db39a154e8cba51 Mon Sep 17 00:00:00 2001 From: chenhang Date: Fri, 3 Jul 2026 18:39:00 +0800 Subject: [PATCH] feat(sidebar): add conditional pwa install action --- .../components/sidebar-screen.module.css | 30 ++++++++ src/app/sidebar/sidebar-screen.tsx | 76 +++++++++++++++---- 2 files changed, 90 insertions(+), 16 deletions(-) diff --git a/src/app/sidebar/components/sidebar-screen.module.css b/src/app/sidebar/components/sidebar-screen.module.css index 9d453a60..b9ca512a 100644 --- a/src/app/sidebar/components/sidebar-screen.module.css +++ b/src/app/sidebar/components/sidebar-screen.module.css @@ -123,6 +123,12 @@ text-transform: uppercase; } +.settingsActions { + display: flex; + flex-direction: column; + gap: clamp(10px, 2.222vw, 12px); +} + .logoutCard { display: flex; width: 100%; @@ -141,6 +147,11 @@ transition: background 0.18s ease, box-shadow 0.18s ease, transform 0.16s ease; } +.installCard { + border-color: rgba(246, 87, 160, 0.14); + background: rgba(255, 255, 255, 0.9); +} + .logoutCard:hover { background: #ffffff; box-shadow: 0 16px 34px rgba(55, 36, 44, 0.1); @@ -168,6 +179,11 @@ color: #ef4d64; } +.installIcon { + background: rgba(246, 87, 160, 0.12); + color: #f657a0; +} + .logoutText { display: flex; min-width: 0; @@ -182,6 +198,13 @@ line-height: 1.15; } +.installTitle { + color: #171114; + font-size: var(--responsive-body, 16px); + font-weight: 760; + line-height: 1.15; +} + .logoutSubtitle { color: #817076; font-size: var(--responsive-caption, 13px); @@ -189,6 +212,13 @@ line-height: 1.25; } +.installSubtitle { + color: #817076; + font-size: var(--responsive-caption, 13px); + font-weight: 620; + line-height: 1.25; +} + .revealOne, .revealTwo, .revealThree { diff --git a/src/app/sidebar/sidebar-screen.tsx b/src/app/sidebar/sidebar-screen.tsx index 5bf84037..87c0a518 100644 --- a/src/app/sidebar/sidebar-screen.tsx +++ b/src/app/sidebar/sidebar-screen.tsx @@ -1,7 +1,7 @@ "use client"; -import { useEffect } from "react"; -import { LogOut } from "lucide-react"; +import { useEffect, useState } from "react"; +import { Download, LogOut } from "lucide-react"; import { signOut } from "next-auth/react"; import { BackButton } from "@/app/_components"; @@ -10,6 +10,7 @@ import { ROUTES } from "@/router/routes"; import { useAppNavigator } from "@/router/use-app-navigator"; import { useAuthDispatch, useAuthState } from "@/stores/auth/auth-context"; import { useUserDispatch, useUserState } from "@/stores/user/user-context"; +import { pwaUtil } from "@/utils"; import { SidebarWalletCard, @@ -27,6 +28,7 @@ export function SidebarScreen() { const userDispatch = useUserDispatch(); const auth = useAuthState(); const authDispatch = useAuthDispatch(); + const [canShowInstallApp, setCanShowInstallApp] = useState(false); useEffect(() => { if (!auth.hasInitialized || auth.isLoading) return; @@ -40,6 +42,25 @@ export function SidebarScreen() { userDispatch, ]); + useEffect(() => { + pwaUtil.prepareInstallPrompt(); + const timer = window.setTimeout(() => { + setCanShowInstallApp(pwaUtil.isSupported() && !pwaUtil.isInstalled()); + }, 0); + + return () => { + window.clearTimeout(timer); + }; + }, []); + + const handleInstallAppClick = async () => { + pwaUtil.prepareInstallPrompt(); + const result = await pwaUtil.install(); + if (result === "accepted" || pwaUtil.isInstalled()) { + setCanShowInstallApp(false); + } + }; + const handleLogoutClick = () => { userDispatch({ type: "UserClearLocal" }); authDispatch({ type: "AuthLogoutSubmitted" }); @@ -100,21 +121,44 @@ export function SidebarScreen() { {sidebarState !== "guest" ? (

Other

- + ) : null} + + + + Log out + + End the current session safely + + + +
) : null}