feat(sidebar): add conditional pwa install action

This commit is contained in:
2026-07-03 18:39:00 +08:00
parent 27cb2e2c33
commit f470119a1b
2 changed files with 90 additions and 16 deletions
+60 -16
View File
@@ -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" ? (
<section className={`${styles.settingsSlot} ${styles.revealThree}`}>
<p className={styles.settingsLabel}>Other</p>
<button
type="button"
className={styles.logoutCard}
onClick={handleLogoutClick}
>
<span className={styles.logoutIcon} aria-hidden="true">
<LogOut size={19} strokeWidth={2.2} />
</span>
<span className={styles.logoutText}>
<span className={styles.logoutTitle}>Log out</span>
<span className={styles.logoutSubtitle}>
End the current session safely
<div className={styles.settingsActions}>
{canShowInstallApp ? (
<button
type="button"
className={`${styles.logoutCard} ${styles.installCard}`}
onClick={() => void handleInstallAppClick()}
>
<span
className={`${styles.logoutIcon} ${styles.installIcon}`}
aria-hidden="true"
>
<Download size={19} strokeWidth={2.2} />
</span>
<span className={styles.logoutText}>
<span className={styles.installTitle}>Install app</span>
<span className={styles.installSubtitle}>
Add CozSweet to your Home Screen
</span>
</span>
</button>
) : null}
<button
type="button"
className={styles.logoutCard}
onClick={handleLogoutClick}
>
<span className={styles.logoutIcon} aria-hidden="true">
<LogOut size={19} strokeWidth={2.2} />
</span>
</span>
</button>
<span className={styles.logoutText}>
<span className={styles.logoutTitle}>Log out</span>
<span className={styles.logoutSubtitle}>
End the current session safely
</span>
</span>
</button>
</div>
</section>
) : null}
</div>