feat(chat): add promotional external entry flow
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
import { AuthStorage } from "@/data/storage/auth/auth_storage";
|
||||
import { UserStorage } from "@/data/storage/user/user_storage";
|
||||
import type { PendingChatPromotionType } from "@/data/storage/navigation";
|
||||
import { ROUTES } from "@/router/routes";
|
||||
|
||||
export type ExternalEntryTarget =
|
||||
@@ -18,21 +19,34 @@ export interface ExternalEntryPayload {
|
||||
|
||||
export interface ExternalEntryTargetInput {
|
||||
target?: string | null;
|
||||
redirect?: string | null;
|
||||
next?: string | null;
|
||||
}
|
||||
|
||||
export interface ExternalEntryPromotionInput {
|
||||
mode?: string | null;
|
||||
promotionType?: string | null;
|
||||
}
|
||||
|
||||
export function resolveExternalEntryPromotionType({
|
||||
mode,
|
||||
promotionType,
|
||||
}: ExternalEntryPromotionInput): PendingChatPromotionType | null {
|
||||
if (mode?.trim().toLowerCase() !== "promotion") return null;
|
||||
|
||||
const normalizedType = promotionType?.trim().toLowerCase();
|
||||
if (
|
||||
normalizedType === "voice" ||
|
||||
normalizedType === "image" ||
|
||||
normalizedType === "private"
|
||||
) {
|
||||
return normalizedType;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export function resolveExternalEntryTarget({
|
||||
target,
|
||||
redirect,
|
||||
next,
|
||||
}: ExternalEntryTargetInput): ExternalEntryTarget {
|
||||
return (
|
||||
resolveExplicitRoute(redirect) ??
|
||||
resolveExplicitRoute(next) ??
|
||||
resolveTargetAlias(target) ??
|
||||
ROUTES.chat
|
||||
);
|
||||
return resolveTarget(target) ?? ROUTES.chat;
|
||||
}
|
||||
|
||||
export async function persistExternalEntryPayload({
|
||||
@@ -61,44 +75,19 @@ export async function persistExternalEntryPayload({
|
||||
await Promise.all(tasks);
|
||||
}
|
||||
|
||||
function resolveExplicitRoute(
|
||||
value: string | null | undefined,
|
||||
): ExternalEntryTarget | null {
|
||||
if (!value) return null;
|
||||
const route = normalizeRoute(value);
|
||||
if (
|
||||
route === ROUTES.chat ||
|
||||
route === ROUTES.tip ||
|
||||
route === ROUTES.privateRoom
|
||||
) {
|
||||
return route;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function resolveTargetAlias(
|
||||
function resolveTarget(
|
||||
value: string | null | undefined,
|
||||
): ExternalEntryTarget | null {
|
||||
if (!value) return null;
|
||||
const target = value.trim().toLowerCase();
|
||||
|
||||
if (target === "chat") return ROUTES.chat;
|
||||
if (target === "tip" || target === "tips") {
|
||||
return ROUTES.tip;
|
||||
}
|
||||
if (target === "private-room") {
|
||||
return ROUTES.privateRoom;
|
||||
}
|
||||
if (target === "tip") return ROUTES.tip;
|
||||
if (target === "private-room") return ROUTES.privateRoom;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function normalizeRoute(value: string): string {
|
||||
const trimmed = value.trim();
|
||||
if (!trimmed.startsWith("/") || trimmed.startsWith("//")) return "";
|
||||
return trimmed.split(/[?#]/, 1)[0] ?? "";
|
||||
}
|
||||
|
||||
function hasValue(value: string | null | undefined): value is string {
|
||||
return typeof value === "string" && value.trim().length > 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user