refactor(app): tighten feature boundaries
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
"use client";
|
||||
|
||||
import { AuthStorage } from "@/data/storage/auth/auth_storage";
|
||||
|
||||
export async function hasBusinessLoginToken(): Promise<boolean> {
|
||||
const result = await AuthStorage.getInstance().getLoginToken();
|
||||
return result.success && Boolean(result.data);
|
||||
}
|
||||
@@ -52,3 +52,17 @@ export async function openChatInExternalBrowser(): Promise<void> {
|
||||
|
||||
UrlLauncherUtil.openUrlWithExternalBrowser(ROUTES.splash);
|
||||
}
|
||||
|
||||
export async function persistExternalBrowserChatDeepLink(input: {
|
||||
deviceId: string;
|
||||
facebookId?: string | null;
|
||||
avatarUrl?: string | null;
|
||||
}): Promise<void> {
|
||||
await AuthStorage.getInstance().setDeviceId(input.deviceId);
|
||||
if (input.facebookId && input.facebookId.length > 0) {
|
||||
await AuthStorage.getInstance().setFacebookId(input.facebookId);
|
||||
}
|
||||
if (input.avatarUrl && input.avatarUrl.length > 0) {
|
||||
await UserStorage.getInstance().setAvatarUrl(input.avatarUrl);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
"use client";
|
||||
|
||||
const STORAGE_KEY = "cozsweet.chat.pendingImageReturn";
|
||||
const MAX_AGE_MS = 30 * 60 * 1000;
|
||||
|
||||
export interface PendingChatImageReturn {
|
||||
reason: "image_paywall";
|
||||
messageId: string;
|
||||
returnUrl: string;
|
||||
createdAt: number;
|
||||
}
|
||||
|
||||
export function savePendingChatImageReturn(input: {
|
||||
messageId: string;
|
||||
returnUrl: string;
|
||||
}): void {
|
||||
if (typeof window === "undefined") return;
|
||||
const payload: PendingChatImageReturn = {
|
||||
reason: "image_paywall",
|
||||
messageId: input.messageId,
|
||||
returnUrl: input.returnUrl,
|
||||
createdAt: Date.now(),
|
||||
};
|
||||
window.sessionStorage.setItem(STORAGE_KEY, JSON.stringify(payload));
|
||||
}
|
||||
|
||||
export function consumePendingChatImageReturn(): PendingChatImageReturn | null {
|
||||
if (typeof window === "undefined") return null;
|
||||
|
||||
const raw = window.sessionStorage.getItem(STORAGE_KEY);
|
||||
window.sessionStorage.removeItem(STORAGE_KEY);
|
||||
if (!raw) return null;
|
||||
|
||||
try {
|
||||
const value = JSON.parse(raw) as Partial<PendingChatImageReturn>;
|
||||
if (value.reason !== "image_paywall") return null;
|
||||
if (typeof value.messageId !== "string" || value.messageId.length === 0) {
|
||||
return null;
|
||||
}
|
||||
if (typeof value.returnUrl !== "string" || value.returnUrl.length === 0) {
|
||||
return null;
|
||||
}
|
||||
if (typeof value.createdAt !== "number") return null;
|
||||
if (Date.now() - value.createdAt > MAX_AGE_MS) return null;
|
||||
|
||||
return {
|
||||
reason: value.reason,
|
||||
messageId: value.messageId,
|
||||
returnUrl: value.returnUrl,
|
||||
createdAt: value.createdAt,
|
||||
};
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
PendingPaymentOrderStorage,
|
||||
type PendingPaymentOrder,
|
||||
} from "@/data/storage";
|
||||
import { ROUTES } from "@/router/routes";
|
||||
import type { Result } from "@/utils";
|
||||
|
||||
export type PendingPaymentSubscriptionType =
|
||||
PendingPaymentOrder["subscriptionType"];
|
||||
export type PendingPaymentReturnTo = PendingPaymentOrder["returnTo"];
|
||||
|
||||
export function savePendingEzpayOrder(input: {
|
||||
orderId: string;
|
||||
subscriptionType: PendingPaymentSubscriptionType;
|
||||
returnTo?: PendingPaymentReturnTo;
|
||||
createdAt?: number;
|
||||
}): Promise<Result<void>> {
|
||||
return PendingPaymentOrderStorage.setPendingOrder({
|
||||
orderId: input.orderId,
|
||||
payChannel: "ezpay",
|
||||
subscriptionType: input.subscriptionType,
|
||||
...(input.returnTo ? { returnTo: input.returnTo } : {}),
|
||||
createdAt: input.createdAt ?? Date.now(),
|
||||
});
|
||||
}
|
||||
|
||||
export function getPendingPaymentOrder(): Promise<
|
||||
Result<PendingPaymentOrder | null>
|
||||
> {
|
||||
return PendingPaymentOrderStorage.getPendingOrder();
|
||||
}
|
||||
|
||||
export function getPendingPaymentOrderForType(
|
||||
subscriptionType: PendingPaymentSubscriptionType,
|
||||
): Promise<Result<PendingPaymentOrder | null>> {
|
||||
return PendingPaymentOrderStorage.getPendingOrderForType(subscriptionType);
|
||||
}
|
||||
|
||||
export function clearPendingPaymentOrder(): Promise<Result<void>> {
|
||||
return PendingPaymentOrderStorage.clearPendingOrder();
|
||||
}
|
||||
|
||||
export function buildPendingPaymentSubscriptionUrl(
|
||||
order: Pick<PendingPaymentOrder, "subscriptionType" | "returnTo">,
|
||||
): string {
|
||||
const params = new URLSearchParams({
|
||||
type: order.subscriptionType,
|
||||
paymentReturn: "1",
|
||||
});
|
||||
if (order.returnTo) params.set("returnTo", order.returnTo);
|
||||
return `${ROUTES.subscription}?${params.toString()}`;
|
||||
}
|
||||
Reference in New Issue
Block a user