summaryrefslogtreecommitdiff
path: root/frontend/src/stores/index.ts
blob: 5ee9b08b819959ae7a812f7597d9ea13e1518c1a (plain) (blame)
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
import { atom } from 'nanostores'
import { ChatMessage, Choice } from '../types'

// 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)
export const skipIntroStore = atom<boolean>(
  (() => {
    const saved = localStorage.getItem('skipIntro')
    return saved === 'true'
  })()
)

// 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 = (enabled: boolean) => {
  documentUiEnabledStore.set(enabled)
  localStorage.setItem('document_ui_enabled', JSON.stringify(enabled))
  // Persist to backend (fire-and-forget)
  fetch('/api/v1/settings', {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ key: 'document_ui_enabled', value: enabled }),
  }).catch((err) => console.error('Failed to persist document_ui_enabled:', err))
}

// 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 setLoadingComplete = (complete: boolean) => {
  loadingCompleteStore.set(complete)
  if (complete) {
    loadingStore.set(false)
  }
}