返回 AiToEarn
index.ts
1 import type { PlatformInfo, PlatformMetadataVo } from '@/api/channels/channel.types'
2 import type { PlatType } from '@/app/config/platConfig'
3 import { create } from 'zustand'
4 import { combine } from 'zustand/middleware'
5 import { getChannelPlatformsApi } from '@/api/channels/channel.api'
6 import {
7 getChannelPlatformInfos,
8 getEnabledPlatformInfos,
9 getPublishPlatformInfos,
10 getTaskPlatformInfos,
11 isPlatCollectSupported,
12 isPlatformAvailable,
13 isPlatformComingSoon,
14 isPlatViewSupported,
15 isTaskPlatformSupported,
16 normalizePlatformMetadataList,
17 } from '@/store/platformMetadata/utils'
18
19 type PlatformMetadataStatus = 'idle' | 'loading' | 'success' | 'error'
20
21 interface PlatformMetadataState {
22 rawList: PlatformMetadataVo[]
23 list: PlatformInfo[]
24 map: Map<PlatType, PlatformInfo>
25 status: PlatformMetadataStatus
26 loadedLng?: string
27 errorMessage?: string
28 }
29
30 const initialState: PlatformMetadataState = {
31 rawList: [],
32 list: [],
33 map: new Map(),
34 status: 'idle',
35 loadedLng: undefined,
36 errorMessage: undefined,
37 }
38
39 let latestRequestedLng: string | undefined
40 let latestFetchVersion = 0
41
42 async function fetchPlatformMetadata(options?: { fresh?: boolean }) {
43 try {
44 const res = await getChannelPlatformsApi(options)
45 if (Number(res?.code) !== 0 || !res?.data) {
46 return {
47 rawList: undefined,
48 errorMessage: res?.message,
49 }
50 }
51 return {
52 rawList: res.data,
53 errorMessage: undefined,
54 }
55 }
56 catch (error: unknown) {
57 return {
58 rawList: undefined,
59 errorMessage: error instanceof Error ? error.message : undefined,
60 }
61 }
62 }
63
64 let pendingRequest: Promise<Awaited<ReturnType<typeof fetchPlatformMetadata>>> | null = null
65
66 function createPlatformMetadataRequest(options?: { fresh?: boolean }) {
67 const version = ++latestFetchVersion
68 const request = fetchPlatformMetadata(options).finally(() => {
69 if (pendingRequest === request)
70 pendingRequest = null
71 })
72 pendingRequest = request
73
74 return { request, version }
75 }
76
77 function createPlatformMetadataState(rawList: PlatformMetadataVo[], lng: string): PlatformMetadataState {
78 const { list, map } = normalizePlatformMetadataList(rawList, lng)
79
80 if (typeof window !== 'undefined') {
81 console.info('[PlatformMetadata] initialized', {
82 lng,
83 rawList,
84 list,
85 })
86 }
87
88 return {
89 rawList,
90 list,
91 map,
92 status: 'success',
93 loadedLng: lng,
94 errorMessage: undefined,
95 }
96 }
97
98 export const usePlatformMetadataStore = create(
99 combine(initialState, (set, get) => ({
100 async ensureLoaded(lng: string, options?: { force?: boolean }) {
101 latestRequestedLng = lng
102 const force = options?.force === true
103 const state = get()
104 if (!force && state.status === 'success' && state.loadedLng === lng)
105 return true
106 if (!force && state.rawList.length > 0) {
107 set(createPlatformMetadataState(state.rawList, lng))
108 return true
109 }
110
111 let request = pendingRequest
112 let version = latestFetchVersion
113
114 if (force) {
115 ;({ request, version } = createPlatformMetadataRequest({ fresh: true }))
116 }
117 else if (!request) {
118 set({ status: 'loading', errorMessage: undefined })
119 ;({ request, version } = createPlatformMetadataRequest())
120 }
121
122 const { rawList, errorMessage } = await request!
123 if (!rawList) {
124 if (version === latestFetchVersion) {
125 set({
126 status: 'error',
127 errorMessage,
128 })
129 }
130 return false
131 }
132
133 if (version !== latestFetchVersion || latestRequestedLng !== lng)
134 return false
135
136 set(createPlatformMetadataState(rawList, lng))
137
138 return true
139 },
140 })),
141 )
142
143 export function getPlatformInfoSync(platType?: PlatType | null) {
144 if (!platType)
145 return undefined
146 return usePlatformMetadataStore.getState().map.get(platType)
147 }
148
149 export function getPlatformInfoMapSync() {
150 return usePlatformMetadataStore.getState().map
151 }
152
153 export function getPlatformInfoListSync() {
154 return usePlatformMetadataStore.getState().list
155 }
156
157 export function getEnabledPlatformInfosSync() {
158 return getEnabledPlatformInfos(usePlatformMetadataStore.getState().list)
159 }
160
161 export function getChannelPlatformInfosSync() {
162 return getChannelPlatformInfos(usePlatformMetadataStore.getState().list)
163 }
164
165 export function getPublishPlatformInfosSync() {
166 return getPublishPlatformInfos(usePlatformMetadataStore.getState().list)
167 }
168
169 export function getTaskPlatformInfosSync() {
170 return getTaskPlatformInfos(usePlatformMetadataStore.getState().list)
171 }
172
173 export function isPlatformMetadataReadySync() {
174 return usePlatformMetadataStore.getState().status === 'success'
175 }
176
177 export function isPlatformEnabledSync(platType?: PlatType | null) {
178 const platformInfo = getPlatformInfoSync(platType)
179 return isPlatformAvailable(platformInfo)
180 }
181
182 export function isPlatformDisabledSync(platType?: PlatType | null) {
183 const platformInfo = getPlatformInfoSync(platType)
184 return isPlatformComingSoon(platformInfo)
185 }
186
187 export {
188 isPlatCollectSupported,
189 isPlatViewSupported,
190 isTaskPlatformSupported,
191 }
192
192 lines TYPESCRIPT