import { setOpenInAppDeeplink } from "@client/atoms/app" import type { FeedOrListRespModel } from "@follow/models/types" import { DEEPLINK_SCHEME } from "@follow/shared/constants" import type { ApiClient } from "~/lib/api-client" import type { defineMetadata } from "~/meta-handler" export const getPreferredTitle = (feed?: FeedOrListRespModel | null) => { if (!feed?.id) { return feed?.title } return feed.title } export const getHydrateData = (key: string) => { return window.__HYDRATE__?.[key] } // type ExtractHydrateData = T extends readonly (infer Item)[] // ? Item extends { readonly type: "hydrate"; readonly data: infer D } // ? D // : never // : never // export type GetHydrateData = T extends (...args: any[]) => Promise // ? ExtractHydrateData // : T extends Promise // ? ExtractHydrateData // : ExtractHydrateData type ExtractHydrateData = T extends readonly (infer Item)[] ? Item extends { readonly type: "hydrate"; readonly data: infer D } ? D : never : never type UnwrapMetadataFn = T extends

>(args: { params: P apiClient: ApiClient origin: string throwError: (status: number, message: any) => never }) => Promise | infer R ? R : never export type GetHydrateData = T extends (...args: any[]) => Promise ? ExtractHydrateData : T extends (...args: any[]) => infer R ? ExtractHydrateData : T extends Promise ? ExtractHydrateData : T extends typeof defineMetadata ? ExtractHydrateData[0]>> : ExtractHydrateData export const askOpenInFollowApp = (deeplink: string, fallback?: () => string): Promise => { return new Promise(() => { const deeplinkUrl = `${DEEPLINK_SCHEME}${deeplink}` setOpenInAppDeeplink({ deeplink: deeplinkUrl, fallbackUrl: fallback ? fallback() : undefined, }) }) } export const openInFollowApp = ({ deeplink, fallback, alwaysFallback, fallbackUrl, }: { deeplink: string fallback: () => void alwaysFallback?: boolean fallbackUrl?: string }): Promise => { return new Promise((resolve) => { const timeout = 500 let isAppOpened = false const handleBlur = () => { isAppOpened = true cleanup() resolve(true) } const cleanup = () => { window.removeEventListener("blur", handleBlur) } window.addEventListener("blur", handleBlur) const deeplinkUrl = `${DEEPLINK_SCHEME}${deeplink}` console.info("Open deeplink:", deeplinkUrl) window.location.href = deeplinkUrl setTimeout(() => { cleanup() if (!isAppOpened && !alwaysFallback) { fallback() resolve(false) return } setOpenInAppDeeplink({ deeplink: deeplinkUrl, fallbackUrl, }) }, timeout) }) }