import { Language, License, VideoCategory } from '@/api/queries' import { CommonStore, createStore } from '@/store' import { createId } from '@/utils/createId' import { readFromLocalStorage } from '@/utils/localStorage' export type CommonDraftProps = { id: string channelId: string updatedAt: string seen?: boolean } export type Draft = VideoDraft export type DraftType = 'video' export type VideoDraft = { type: 'video' title?: string | null description?: string | null isPublic?: boolean | null publishedBeforeJoystream?: string | null hasMarketing?: boolean | null isExplicit?: boolean | null language?: Language['iso'] | null category?: VideoCategory['id'] | null licenseCode?: License['code'] | null licenseCustomText?: License['customText'] | null licenseAttribution?: License['attribution'] | null } & CommonDraftProps export type RawDraft = Omit type DraftStoreState = { drafts: Draft[] } type DraftStoreActions = { addDraft: (draft: RawDraft, explicitId?: string) => Draft updateDraft: (draftId: string, draftProps: RawDraft) => void removeDrafts: (draftIds: string[]) => void removeAllDrafts: (channelId: string) => void markAllDraftsAsSeenForChannel: (channelId: string) => void } export const useDraftStore = createStore( { state: { drafts: [], // includes drafts for different channels }, actionsFactory: (set) => ({ addDraft: (draft, explicitId) => { const id = explicitId ?? createId() const updatedAt = new Date().toISOString() const newDraft: Draft = { ...draft, updatedAt, id, seen: false } set((draftState) => { draftState.drafts.unshift(newDraft) }) return newDraft }, updateDraft: (draftId, draftProps) => { const updatedAt = new Date().toISOString() set((draftState) => { const idx = draftState.drafts.findIndex((d) => d.id === draftId) if (idx >= 0) { draftState.drafts[idx] = { ...draftState.drafts[idx], ...draftProps, updatedAt } } }) }, removeDrafts: (draftIds) => { set((draftState) => { draftState.drafts = draftState.drafts.filter((draft) => !draftIds.includes(draft.id)) }) }, removeAllDrafts: (channelId) => { set((draftState) => { draftState.drafts = draftState.drafts.filter((draft) => draft.channelId !== channelId) }) }, markAllDraftsAsSeenForChannel: (channelId) => { set((draftState) => { draftState.drafts = draftState.drafts.map((draft) => ({ ...draft, seen: draft.channelId === channelId ? true : draft.seen, })) }) }, }), }, { persist: { key: 'drafts', whitelist: ['drafts'], version: 1, migrate: (oldState, oldVersion, storageValue) => { // migrate store before zustand was added if (oldVersion === undefined) { const unseenDrafts = readFromLocalStorage< Array<{ draftId: string channelId: string }> >('unseenDrafts') const drafts = [...(storageValue as Array)].map((draft) => { return unseenDrafts?.find((unseen) => unseen.draftId === draft.id) ? { ...draft, seen: false } : { ...draft, seen: true } }) return { drafts: drafts, } } }, }, } ) export const singleDraftSelector = (id: string) => (store: CommonStore) => store.drafts.find((draft) => draft.id === id) export const channelDraftsSelector = (channelId: string) => (store: CommonStore) => store.drafts.filter((d) => d.channelId === channelId) export const chanelUnseenDraftsSelector = (channelId: string) => ( store: CommonStore ) => store.drafts.filter((d) => d.channelId === channelId && d.seen === false)