Files
cozsweet-frontend-nextjs/src/app/chat/deviceid/[deviceId]/DeepLinkPersist.tsx
T

70 lines
2.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
/**
* 深链落地:把 deviceId + fbid/avatarUrl 写进本地存储,然后跳 `/chat`。
*
* 设计:
* - 不走 Server `redirect()`:避免把 fbid 暴露在 URL 里。
* - deviceId / fbid 都走 `AuthStorage.getInstance().setXxx`(与 `token_interceptor.ts` 同源)
* - avatarUrl 写入 UserStorage 的头像 slot,外部浏览器首次恢复时可带给后端。
* - 写入完成后 `router.replace('/chat')`URL 不留深链痕迹。
*/
import { useEffect, useState } from "react";
import { useRouter } from "next/navigation";
import { AuthStorage } from "@/data/storage/auth/auth_storage";
import { UserStorage } from "@/data/storage/user/user_storage";
import { ROUTES } from "@/router/routes";
import { Logger } from "@/utils";
const log = new Logger("AppChatDeviceidDeviceIdDeepLinkPersist");
interface DeepLinkPersistProps {
deviceId: string;
fbid: string | null;
avatarUrl: string | null;
}
export default function DeepLinkPersist({
deviceId,
fbid,
avatarUrl,
}: DeepLinkPersistProps) {
const router = useRouter();
const [done, setDone] = useState(false);
useEffect(() => {
void (async () => {
try {
await AuthStorage.getInstance().setDeviceId(deviceId);
if (fbid && fbid.length > 0) {
await AuthStorage.getInstance().setFacebookId(fbid);
}
if (avatarUrl && avatarUrl.length > 0) {
await UserStorage.getInstance().setAvatarUrl(avatarUrl);
}
} catch (err) {
// 写不进 localStorage 时(例如隐私模式)也不阻塞跳转;记录到 console 即可。
log.warn("[DeepLinkPersist] failed to persist", err);
} finally {
setDone(true);
router.replace(ROUTES.chat);
}
})();
}, [avatarUrl, deviceId, fbid, router]);
return (
<div
className="flex flex-1 items-center justify-center"
style={{ minHeight: "100dvh" }}
>
<div
aria-label={done ? "Redirecting" : "Loading"}
className="size-10 animate-spin rounded-full border-4 border-t-transparent"
style={{ borderColor: "var(--color-accent)" }}
/>
</div>
);
}