75 lines
2.2 KiB
TypeScript
75 lines
2.2 KiB
TypeScript
|
|
import { atom, map, computed, onMount } from 'nanostores'
|
||
|
|
import { createFetcherStore, createBlogMutatorStore } from './fetcher'
|
||
|
|
import type { InteractionConfig } from '../types'
|
||
|
|
|
||
|
|
const defaultConfig: InteractionConfig = {
|
||
|
|
comments_enabled: false,
|
||
|
|
reactions_enabled: false,
|
||
|
|
reaction_mode: 'emoji',
|
||
|
|
reaction_emojis: '👍,❤️,🎉,🚀',
|
||
|
|
upvote_icon: 'arrow',
|
||
|
|
reactions_require_auth: false,
|
||
|
|
}
|
||
|
|
|
||
|
|
export const $interactionsData = createFetcherStore<InteractionConfig>(['/api/studio/interaction-config'])
|
||
|
|
|
||
|
|
export const $interactions = map<InteractionConfig>({ ...defaultConfig })
|
||
|
|
export const $initialInteractions = atom<InteractionConfig | null>(null)
|
||
|
|
|
||
|
|
export const $hasInteractionChanges = computed(
|
||
|
|
[$interactions, $initialInteractions],
|
||
|
|
(current, initial) => initial !== null && JSON.stringify(current) !== JSON.stringify(initial)
|
||
|
|
)
|
||
|
|
|
||
|
|
export const $changedInteractionFields = computed(
|
||
|
|
[$interactions, $initialInteractions],
|
||
|
|
(current, initial) => {
|
||
|
|
if (!initial) return []
|
||
|
|
const changes: string[] = []
|
||
|
|
const labels: Record<string, string> = {
|
||
|
|
comments_enabled: 'Comments',
|
||
|
|
reactions_enabled: 'Reactions',
|
||
|
|
reaction_mode: 'Reaction mode',
|
||
|
|
reaction_emojis: 'Emojis',
|
||
|
|
upvote_icon: 'Upvote icon',
|
||
|
|
reactions_require_auth: 'Auth required',
|
||
|
|
}
|
||
|
|
for (const key of Object.keys(current) as (keyof InteractionConfig)[]) {
|
||
|
|
if (current[key] !== initial[key]) {
|
||
|
|
changes.push(labels[key] || key)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return changes
|
||
|
|
}
|
||
|
|
)
|
||
|
|
|
||
|
|
onMount($interactionsData, () => {
|
||
|
|
$interactionsData.listen(({ data }) => {
|
||
|
|
if (data) {
|
||
|
|
const merged = { ...defaultConfig, ...data }
|
||
|
|
$interactions.set(merged)
|
||
|
|
$initialInteractions.set(merged)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
})
|
||
|
|
|
||
|
|
export const $saveInteractions = createBlogMutatorStore<InteractionConfig>(
|
||
|
|
async ({ data: config }) => {
|
||
|
|
const previous = $initialInteractions.get()
|
||
|
|
$initialInteractions.set({ ...config })
|
||
|
|
|
||
|
|
const res = await fetch('/api/studio/interaction-config', {
|
||
|
|
method: 'PUT',
|
||
|
|
headers: { 'Content-Type': 'application/json' },
|
||
|
|
body: JSON.stringify(config),
|
||
|
|
})
|
||
|
|
|
||
|
|
if (!res.ok) {
|
||
|
|
$initialInteractions.set(previous)
|
||
|
|
throw new Error('Failed to save interactions')
|
||
|
|
}
|
||
|
|
|
||
|
|
return config
|
||
|
|
}
|
||
|
|
)
|