@liujitcn/kratos-taro-app-system 0.0.78 → 0.0.80

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +1 -1
  2. package/dist/build.mjs +2 -2
  3. package/dist/module.mjs +54 -6
  4. package/package.json +3 -3
  5. package/src/api/base/v1/ai_knowledge.ts +25 -0
  6. package/src/locales/en-US.json +13 -1
  7. package/src/locales/ja-JP.json +13 -1
  8. package/src/locales/zh-CN.json +13 -1
  9. package/src/locales/zh-TW.json +13 -1
  10. package/src/pages.ts +2 -2
  11. package/src/rpc/base/v1/ai_knowledge.ts +33 -0
  12. package/src/rpc/base/v1/ai_message.ts +1 -1
  13. package/src/rpc/base/v1/ai_provider.ts +1 -1
  14. package/src/rpc/base/v1/ai_search.ts +1 -1
  15. package/src/rpc/base/v1/ai_session.ts +1 -1
  16. package/src/rpc/base/v1/ai_tool.ts +1 -1
  17. package/src/rpc/base/v1/notification.ts +1 -1
  18. package/src/rpc/google/protobuf/empty.ts +1 -1
  19. package/src/rpc/google/protobuf/timestamp.ts +1 -1
  20. package/src/views/pages/my/my.scss +28 -109
  21. package/src/views/pages/my/my.tsx +62 -49
  22. package/src/views/pagesMember/ai/components/Composer.tsx +52 -3
  23. package/src/views/pagesMember/ai/components/KnowledgePicker.tsx +58 -0
  24. package/src/views/pagesMember/ai/components/SessionDrawer.tsx +8 -5
  25. package/src/views/pagesMember/ai/components/WelcomePanel.tsx +7 -4
  26. package/src/views/pagesMember/ai/components/composer.scss +28 -23
  27. package/src/views/pagesMember/ai/components/knowledge-picker.scss +139 -0
  28. package/src/views/pagesMember/ai/components/model-picker.scss +24 -18
  29. package/src/views/pagesMember/ai/components/session-drawer.scss +44 -22
  30. package/src/views/pagesMember/ai/components/welcome-panel.scss +28 -17
  31. package/src/views/pagesMember/ai/index.scss +35 -72
  32. package/src/views/pagesMember/ai/index.tsx +47 -14
  33. package/src/views/pagesMember/message/detail.tsx +43 -25
  34. package/src/views/pagesMember/message/index.tsx +107 -98
  35. package/src/views/pagesMember/message/message.scss +78 -179
  36. package/src/views/pagesMember/profile/profile.scss +43 -99
  37. package/src/views/pagesMember/profile/profile.tsx +68 -48
  38. package/src/views/pagesMember/settings/components/PasswordVerifyDialog.scss +14 -13
  39. package/src/views/pagesMember/settings/settings.scss +27 -68
  40. package/src/views/pagesMember/settings/settings.tsx +161 -36
@@ -1,12 +1,15 @@
1
- import { Button, Picker, Text, View } from '@tarojs/components'
1
+ import { Button, Image, Picker, Text, View } from '@tarojs/components'
2
2
  import Taro, { useLoad } from '@tarojs/taro'
3
- import { useEffect, useMemo, useState } from 'react'
3
+ import { useMemo, useState } from 'react'
4
4
  import {
5
5
  useLocaleStore,
6
6
  navigateToLogin,
7
7
  type SupportedLocale,
8
8
  useI18n,
9
+ useThemeStore,
9
10
  useUserStore,
11
+ type ThemeMode,
12
+ homeTabPage,
10
13
  } from '@liujitcn/kratos-taro-app-core'
11
14
  import { defMfaService } from '@liujitcn/kratos-taro-app-core/api/base/v1/mfa'
12
15
  import { isAuthExpiredError } from '@liujitcn/kratos-taro-app-core/utils/http'
@@ -16,6 +19,14 @@ import './settings.scss'
16
19
  /** 应用设置页。 */
17
20
  export default function SettingsPage() {
18
21
  const { locale, setLocale, t } = useI18n()
22
+ const themeStore = useThemeStore()
23
+ const themeModeOptions: ThemeMode[] = ['auto', 'dark', 'light']
24
+ const themeModeLabels = [
25
+ t('system.settings.theme_auto'),
26
+ t('system.settings.theme_dark'),
27
+ t('system.settings.theme_light'),
28
+ ]
29
+ const themeModeIndex = Math.max(0, themeModeOptions.indexOf(themeStore.mode))
19
30
  const languageOptions = useLocaleStore((state) => state.languageOptions)
20
31
  const [logoutLoading, setLogoutLoading] = useState(false)
21
32
  const [mfaStatusLoading, setMfaStatusLoading] = useState(false)
@@ -34,10 +45,29 @@ export default function SettingsPage() {
34
45
  0,
35
46
  languageOptions.findIndex((item) => item.language_code === locale),
36
47
  )
48
+ const settingsIcons = useMemo(() => {
49
+ const primary = themeStore.theme === 'light' ? '#039e8c' : '#28f0d4'
50
+ const warning = themeStore.theme === 'light' ? '#d9880f' : '#ffb648'
51
+ const violet = themeStore.theme === 'light' ? '#5f4fe0' : '#9b8cff'
52
+ const createIcon = (body: string, color: string) =>
53
+ 'data:image/svg+xml;charset=utf-8,' +
54
+ encodeURIComponent(
55
+ '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="' +
56
+ color +
57
+ '" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">' +
58
+ body +
59
+ '</svg>',
60
+ )
37
61
 
38
- useEffect(() => {
39
- void Taro.setNavigationBarTitle({ title: t('system.settings.title') })
40
- }, [locale, t])
62
+ return {
63
+ theme: createIcon('<path d="M21 12.8A8.5 8.5 0 1 1 11.2 3a6.5 6.5 0 0 0 9.8 9.8Z"/>', primary),
64
+ mfa: createIcon('<path d="M12 3 4 6v6c0 5 3.5 8 8 9 4.5-1 8-4 8-9V6l-8-3Z"/><path d="m9 12 2 2 4-4"/>', primary),
65
+ language: createIcon('<circle cx="12" cy="12" r="9"/><path d="M3 12h18M12 3c3 3 3 15 0 18M12 3c-3 3-3 15 0 18"/>', primary),
66
+ authorization: createIcon('<circle cx="8" cy="15" r="4"/><path d="m11 12 7-7 3 3-7 7"/><path d="m15 8 2 2"/>', warning),
67
+ feedback: createIcon('<path d="M4 5h16v12H8l-4 4z"/>', violet),
68
+ contact: createIcon('<path d="M4 5c0 9 6 15 15 15 1 0 2-1 2-2v-2l-4-2-2 2a11 11 0 0 1-5-5l2-2-2-4H6c-1 0-2 1-2 2Z"/>', primary),
69
+ }
70
+ }, [themeStore.theme])
41
71
 
42
72
  const loadMfaStatus = async (force = false) => {
43
73
  if (!useUserStore.getState().isAuthenticated() || (mfaStatusLoading && !force)) return
@@ -110,11 +140,19 @@ export default function SettingsPage() {
110
140
  void loadMfaStatus()
111
141
  })
112
142
 
143
+ /** 返回个人中心,页面栈不可返回时回到首页。 */
144
+ const onBack = () => {
145
+ void Taro.navigateBack({
146
+ fail: () => void Taro.reLaunch({ url: homeTabPage }),
147
+ })
148
+ }
149
+
113
150
  const onLogout = async () => {
114
151
  if (logoutLoading) return
115
152
  const result = await Taro.showModal({
116
153
  content: t('system.settings.logout_confirm'),
117
- confirmColor: '#27BA9B',
154
+ confirmColor: themeStore.theme === 'light' ? '#039e8c' : '#28f0d4',
155
+ cancelColor: themeStore.theme === 'light' ? '#5a7083' : '#8aa0b4',
118
156
  })
119
157
  if (!result.confirm) return
120
158
  setLogoutLoading(true)
@@ -132,29 +170,58 @@ export default function SettingsPage() {
132
170
 
133
171
  return (
134
172
  <>
135
- <View className='settings-viewport'>
136
- {process.env.TARO_ENV === 'weapp' ? (
137
- <View className='settings-list'>
138
- <Button
139
- className='settings-item settings-arrow'
140
- hoverClass='none'
141
- openType='openSetting'
142
- >
143
- {t('system.settings.authorization')}
144
- </Button>
145
- <Button className='settings-item settings-arrow' hoverClass='none' openType='feedback'>
146
- {t('system.settings.feedback')}
147
- </Button>
148
- <Button className='settings-item settings-arrow' hoverClass='none' openType='contact'>
149
- {t('system.settings.contact')}
150
- </Button>
173
+ <View
174
+ className={`settings-viewport ${
175
+ themeStore.theme === 'light' ? 'theme-light' : 'theme-dark'
176
+ }`}
177
+ >
178
+ <View className={`k-page-nav ${process.env.TARO_ENV === 'weapp' ? 'k-page-nav--weapp' : ''}`}>
179
+ <View className='k-page-nav__back' aria-label={t('common.action.back')} onClick={onBack}>
151
180
  </View>
152
- ) : null}
153
- <View className='settings-list'>
181
+ <View className='k-page-nav__title'>{t('system.settings.title')}</View>
182
+ <View className='k-page-nav__side' aria-hidden />
183
+ </View>
184
+
185
+ <View className='settings-content'>
186
+ <View className='k-set-cat'>{t('system.settings.section_appearance')}</View>
187
+ <Picker
188
+ mode='selector'
189
+ range={themeModeLabels}
190
+ value={themeModeIndex}
191
+ onChange={(event) => {
192
+ const nextMode = themeModeOptions[Number(event.detail.value)]
193
+ if (nextMode) themeStore.setMode(nextMode)
194
+ }}
195
+ >
196
+ <View className='k-set-row k-set-row--arrow'>
197
+ <View className='k-set-row__lead'>
198
+ <View className='k-set-row__icon'>
199
+ <Image className='settings-row__icon' src={settingsIcons.theme} mode='aspectFit' />
200
+ </View>
201
+ <Text className='k-set-row__title'>{t('system.settings.theme')}</Text>
202
+ </View>
203
+ <Text className='k-set-row__value settings-row__value'>
204
+ {themeModeLabels[themeModeIndex]}
205
+ </Text>
206
+ </View>
207
+ </Picker>
208
+
209
+ <View className='k-set-cat'>{t('system.settings.section_security')}</View>
154
210
  {authenticated ? (
155
- <View className='settings-item settings-arrow settings-mfa' onClick={onMfaTap}>
156
- <Text>{t('system.settings.mfa_title')}</Text>
157
- <Text className='settings-mfa__value'>{mfaStatusText}</Text>
211
+ <View className='k-set-row k-set-row--arrow' onClick={onMfaTap}>
212
+ <View className='k-set-row__lead'>
213
+ <View className='k-set-row__icon'>
214
+ <Image className='settings-row__icon' src={settingsIcons.mfa} mode='aspectFit' />
215
+ </View>
216
+ <Text className='k-set-row__title'>{t('system.settings.mfa_title')}</Text>
217
+ </View>
218
+ <Text
219
+ className={`k-set-row__value settings-row__value ${
220
+ mfaEnabled ? 'k-set-row__value--on' : ''
221
+ }`}
222
+ >
223
+ {mfaStatusText}
224
+ </Text>
158
225
  </View>
159
226
  ) : null}
160
227
  <Picker
@@ -168,19 +235,77 @@ export default function SettingsPage() {
168
235
  if (nextLocale) void setLocale(nextLocale)
169
236
  }}
170
237
  >
171
- <View className='settings-item settings-arrow settings-locale'>
172
- <Text>{t('common.field.language')}</Text>
173
- <Text className='settings-locale__value'>{localeLabels[localeIndex]}</Text>
238
+ <View className='k-set-row k-set-row--arrow'>
239
+ <View className='k-set-row__lead'>
240
+ <View className='k-set-row__icon'>
241
+ <Image className='settings-row__icon' src={settingsIcons.language} mode='aspectFit' />
242
+ </View>
243
+ <Text className='k-set-row__title'>{t('common.field.language')}</Text>
244
+ </View>
245
+ <Text className='k-set-row__value settings-row__value'>{localeLabels[localeIndex]}</Text>
174
246
  </View>
175
247
  </Picker>
176
- </View>
177
- {authenticated ? (
178
- <View className='settings-action'>
179
- <View className='settings-button' onClick={() => void onLogout()}>
248
+
249
+ {process.env.TARO_ENV === 'weapp' ? (
250
+ <>
251
+ <View className='k-set-cat'>{t('system.settings.section_more')}</View>
252
+ <Button
253
+ className='k-set-row k-set-row--arrow settings-row--button'
254
+ hoverClass='none'
255
+ openType='openSetting'
256
+ >
257
+ <View className='k-set-row__lead'>
258
+ <View className='k-set-row__icon'>
259
+ <Image
260
+ className='settings-row__icon'
261
+ src={settingsIcons.authorization}
262
+ mode='aspectFit'
263
+ />
264
+ </View>
265
+ <Text className='k-set-row__title'>{t('system.settings.authorization')}</Text>
266
+ </View>
267
+ </Button>
268
+ <Button
269
+ className='k-set-row k-set-row--arrow settings-row--button'
270
+ hoverClass='none'
271
+ openType='feedback'
272
+ >
273
+ <View className='k-set-row__lead'>
274
+ <View className='k-set-row__icon'>
275
+ <Image
276
+ className='settings-row__icon'
277
+ src={settingsIcons.feedback}
278
+ mode='aspectFit'
279
+ />
280
+ </View>
281
+ <Text className='k-set-row__title'>{t('system.settings.feedback')}</Text>
282
+ </View>
283
+ </Button>
284
+ <Button
285
+ className='k-set-row k-set-row--arrow settings-row--button'
286
+ hoverClass='none'
287
+ openType='contact'
288
+ >
289
+ <View className='k-set-row__lead'>
290
+ <View className='k-set-row__icon'>
291
+ <Image
292
+ className='settings-row__icon'
293
+ src={settingsIcons.contact}
294
+ mode='aspectFit'
295
+ />
296
+ </View>
297
+ <Text className='k-set-row__title'>{t('system.settings.contact')}</Text>
298
+ </View>
299
+ </Button>
300
+ </>
301
+ ) : null}
302
+
303
+ {authenticated ? (
304
+ <View className='k-set-logout' onClick={() => void onLogout()}>
180
305
  {t('common.action.logout')}
181
306
  </View>
182
- </View>
183
- ) : null}
307
+ ) : null}
308
+ </View>
184
309
  </View>
185
310
  <PasswordVerifyDialog
186
311
  open={mfaDialogOpen}