1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
import { atom } from 'nanostores'
import { ChatMessage, Choice } from '../types'
import { upsertUserSetting } from '../services/directiveApi'
// Document UI feature flag
export const documentUiEnabledStore = atom<boolean>(
(() => {
try {
const saved = localStorage.getItem('document_ui_enabled')
return saved === 'true'
} catch {
return false
}
})()
)
export const setDocumentUiEnabled = async (enabled: boolean) => {
documentUiEnabledStore.set(enabled)
localStorage.setItem('document_ui_enabled', enabled.toString())
// Persist to backend (best-effort)
try {
await upsertUserSetting('document_ui_enabled', enabled)
} catch (err) {
console.error('Failed to persist document UI setting:', err)
}
}
// Authentication state
export const isLoggedInStore = atom<boolean>(false)
// VN Interface state
export const isStandbyStore = atom<boolean>(false)
export const currentTimeStore = atom<Date>(new Date())
export const weatherStore = atom<string>('Tokyo - Sunny 22°C')
export const showChoicesStore = atom<boolean>(false)
export const showSettingsModalStore = atom<boolean>(false)
export const isVisibleStore = atom<boolean>(false)
export const yenBalanceStore = atom<number>(15000)
// VN Page state
export const loadingStore = atom<boolean>(true)
export const loadingCompleteStore = atom<boolean>(false)
export const messagesStore = atom<ChatMessage[]>([
{ id: 'm1', role: 'assistant', content: 'A warm CRT glow fills the room. A figure turns towards you...' },
])
export const choicesStore = atom<Choice[]>([
{ id: 'greet', label: '"Hello?"' },
{ id: 'who', label: '"Who are you?"' },
{ id: 'silence', label: '(Stay silent)' },
])
export const statusStore = atom<string>('OFFLINE')
export const nameStore = atom<string>('???')
export const backgroundStore = atom<string>('/__gaogao__56242cbde8f18ac64522e410bad04e68_waifu2x_art_noise2.png')
export const locationStore = atom<string>('Tokyo')
export const configModalOpenStore = atom<boolean>(false)
// Feature flags
export const documentEditorEnabledStore = atom<boolean>(
(() => {
const saved = localStorage.getItem('documentEditorEnabled')
return saved === 'true'
})()
)
export const skipIntroStore = atom<boolean>(
(() => {
const saved = localStorage.getItem('skipIntro')
return saved === 'true'
})()
)
// Actions
export const login = () => {
isLoggedInStore.set(true)
}
export const logout = () => {
isLoggedInStore.set(false)
}
export const toggleStandby = () => {
isStandbyStore.set(!isStandbyStore.get())
}
export const toggleShowChoices = () => {
showChoicesStore.set(!showChoicesStore.get())
}
export const updateTime = () => {
currentTimeStore.set(new Date())
}
export const addMessage = (message: ChatMessage) => {
messagesStore.set([...messagesStore.get(), message])
}
export const setChoices = (choices: Choice[]) => {
choicesStore.set(choices)
}
export const clearChoices = () => {
choicesStore.set([])
}
export const setBackground = (src: string) => {
backgroundStore.set(src)
}
export const setName = (name: string) => {
nameStore.set(name)
}
export const setStatus = (status: string) => {
statusStore.set(status)
}
export const setSkipIntro = (skip: boolean) => {
skipIntroStore.set(skip)
localStorage.setItem('skipIntro', skip.toString())
}
export const setDocumentEditorEnabled = (enabled: boolean) => {
documentEditorEnabledStore.set(enabled)
localStorage.setItem('documentEditorEnabled', enabled.toString())
}
export const setLoadingComplete = (complete: boolean) => {
loadingCompleteStore.set(complete)
if (complete) {
loadingStore.set(false)
}
}
|