feat: 添加 PWA 安装提示功能,更新 Navbar 以支持安装应用选项,增加多语言支持

This commit is contained in:
CHENPrime committed 2025-06-03 10:21:25 +08:00
1 parent df4833aea8
commit 0068d85729
5 files changed
+93 -3

No files matched your search

+18
View File
@@ -29,6 +29,7 @@ import { useAuth } from "../providers/AuthProvider";
import { useState, useEffect } from "react";
import { useTranslation } from "react-i18next";
import LanguageSelector from "./LanguageSelector";
import { canInstallPWA, promptPWAInstall } from "@/utils/pwaInstallHandler";
const Navbar = () => {
const navigate = useNavigate();
@@ -120,6 +121,14 @@ const Navbar = () => {
</Text>
</Flex>
</DropdownMenuItem>
<DropdownMenuItem onClick={promptPWAInstall}>
<Flex gap="2" align="center">
<DownloadIcon width="14" height="14" />
<Text className="pl-2" size="2">
{t("navbar.installApp")}
</Text>
</Flex>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</Box>
@@ -219,6 +228,15 @@ const Navbar = () => {
</Text>
</Button>
</Link>
<Button onClick={promptPWAInstall} variant="ghost">
<Flex gap="2" align="center">
<DownloadIcon width="14" height="14" />
<Text className="pl-2" size="2">
{t("navbar.installApp")}
</Text>
</Flex>
</Button>
</Flex>
<Separator orientation="vertical" className="!h-6 hidden lg:block" />
+1
View File
@@ -6,6 +6,7 @@ const enUS = {
"navbar.agentMonitors": "Agent Monitors",
"navbar.statusPage": "Status Page",
"navbar.notifications": "Notifications",
"navbar.installApp": "Install App",
"navbar.userManagement": "User Management",
"navbar.profile": "Profile",
"navbar.logout": "Logout",
+1
View File
@@ -6,6 +6,7 @@ const zhCN = {
"navbar.agentMonitors": "客户端监控",
"navbar.statusPage": "状态页",
"navbar.notifications": "通知",
"navbar.installApp": "安装应用",
"navbar.userManagement": "用户管理",
"navbar.profile": "个人资料",
"navbar.logout": "退出登录",
+5 -3
View File
@@ -34,9 +34,11 @@ const Home = () => {
<Flex gap="4" mt="4">
{isAuthenticated ? (
<Button asChild>
<Link to="/dashboard">{t("home.getStarted")}</Link>
</Button>
<>
<Button asChild>
<Link to="/dashboard">{t("home.getStarted")}</Link>
</Button>
</>
) : (
<>
<Button asChild>
+68
View File
@@ -0,0 +1,68 @@
let deferredPrompt: any; // 用于存储 beforeinstallprompt 事件
/**
* 监听 'beforeinstallprompt' 事件。
* 当浏览器准备好提示用户安装 PWA 时,此事件会触发。
*/
window.addEventListener('beforeinstallprompt', (e) => {
// 阻止浏览器默认的迷你信息栏提示 (在某些移动浏览器上)
e.preventDefault();
// 保存事件,以便稍后可以触发它
deferredPrompt = e;
// 派发一个自定义事件,通知应用 PWA 可以安装了
// 这允许 UI 组件(如 Navbar)更新其状态
window.dispatchEvent(new CustomEvent('pwaInstallReady', { detail: { canInstall: true } }));
console.log('`beforeinstallprompt` 事件已触发。PWA 可以安装。');
});
/**
* 检查 PWA 是否可以被安装。
* @returns {boolean} 如果可以安装则返回 true,否则返回 false。
*/
export const canInstallPWA = (): boolean => {
return !!deferredPrompt;
};
/**
* 触发 PWA 安装提示。
* @returns {Promise<boolean>} 如果用户接受了安装提示,则解析为 true,否则为 false。
*/
export const promptPWAInstall = async (): Promise<boolean> => {
if (!deferredPrompt) {
console.warn('PWA 安装提示不可用或已被使用。');
return false;
}
// 显示安装提示
deferredPrompt.prompt();
// 等待用户对提示做出响应
try {
const { outcome } = await deferredPrompt.userChoice;
if (outcome === 'accepted') {
console.log('用户接受了 PWA 安装提示');
} else {
console.log('用户拒绝了 PWA 安装提示');
}
// 清除 deferredPrompt,因为它只能使用一次
deferredPrompt = null;
// 派发自定义事件,通知 PWA 安装状态已更改
window.dispatchEvent(new CustomEvent('pwaInstallReady', { detail: { canInstall: false } }));
return outcome === 'accepted';
} catch (error) {
console.error('PWA 安装提示时发生错误:', error);
deferredPrompt = null;
window.dispatchEvent(new CustomEvent('pwaInstallReady', { detail: { canInstall: false } }));
return false;
}
};
/**
* 监听 'appinstalled' 事件。
* 当 PWA 成功安装后,此事件会触发。
*/
window.addEventListener('appinstalled', () => {
console.log('PWA 已成功安装!');
// PWA 安装后,deferredPrompt 通常应为 null,
// 因为 beforeinstallprompt 不会再次触发,直到应用被卸载(在某些情况下)
deferredPrompt = null;
window.dispatchEvent(new CustomEvent('pwaInstallReady', { detail: { canInstall: false } }));
});