settings.tsx 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. import { useState, useRef, useEffect } from "react";
  2. import EmojiPicker, { Emoji, Theme as EmojiTheme } from "emoji-picker-react";
  3. import styles from "./settings.module.scss";
  4. import ResetIcon from "../icons/reload.svg";
  5. import CloseIcon from "../icons/close.svg";
  6. import { List, ListItem, Popover } from "./ui-lib";
  7. import { IconButton } from "./button";
  8. import { SubmitKey, useChatStore, Theme } from "../store";
  9. import { Avatar } from "./home";
  10. export function Settings(props: { closeSettings: () => void }) {
  11. const [showEmojiPicker, setShowEmojiPicker] = useState(false);
  12. const [config, updateConfig, resetConfig] = useChatStore((state) => [
  13. state.config,
  14. state.updateConfig,
  15. state.resetConfig,
  16. ]);
  17. return (
  18. <>
  19. <div className={styles["window-header"]}>
  20. <div>
  21. <div className={styles["window-header-title"]}>设置</div>
  22. <div className={styles["window-header-sub-title"]}>设置选项</div>
  23. </div>
  24. <div className={styles["window-actions"]}>
  25. <div className={styles["window-action-button"]}>
  26. <IconButton
  27. icon={<CloseIcon />}
  28. onClick={props.closeSettings}
  29. bordered
  30. title="重置所有选项"
  31. />
  32. </div>
  33. <div className={styles["window-action-button"]}>
  34. <IconButton
  35. icon={<ResetIcon />}
  36. onClick={resetConfig}
  37. bordered
  38. title="重置所有选项"
  39. />
  40. </div>
  41. </div>
  42. </div>
  43. <div className={styles["settings"]}>
  44. <List>
  45. <ListItem>
  46. <div className={styles["settings-title"]}>头像</div>
  47. <Popover
  48. onClose={() => setShowEmojiPicker(false)}
  49. content={
  50. <EmojiPicker
  51. lazyLoadEmojis
  52. theme={EmojiTheme.AUTO}
  53. onEmojiClick={(e) => {
  54. updateConfig((config) => (config.avatar = e.unified));
  55. setShowEmojiPicker(false);
  56. }}
  57. />
  58. }
  59. open={showEmojiPicker}
  60. >
  61. <div
  62. className={styles.avatar}
  63. onClick={() => setShowEmojiPicker(true)}
  64. >
  65. <Avatar role="user" />
  66. </div>
  67. </Popover>
  68. </ListItem>
  69. <ListItem>
  70. <div className={styles["settings-title"]}>发送键</div>
  71. <div className="">
  72. <select
  73. value={config.submitKey}
  74. onChange={(e) => {
  75. updateConfig(
  76. (config) =>
  77. (config.submitKey = e.target.value as any as SubmitKey)
  78. );
  79. }}
  80. >
  81. {Object.values(SubmitKey).map((v) => (
  82. <option value={v} key={v}>
  83. {v}
  84. </option>
  85. ))}
  86. </select>
  87. </div>
  88. </ListItem>
  89. <ListItem>
  90. <div className={styles["settings-title"]}>主题</div>
  91. <div className="">
  92. <select
  93. value={config.theme}
  94. onChange={(e) => {
  95. updateConfig(
  96. (config) => (config.theme = e.target.value as any as Theme)
  97. );
  98. }}
  99. >
  100. {Object.values(Theme).map((v) => (
  101. <option value={v} key={v}>
  102. {v}
  103. </option>
  104. ))}
  105. </select>
  106. </div>
  107. </ListItem>
  108. <ListItem>
  109. <div className={styles["settings-title"]}>紧凑边框</div>
  110. <input
  111. type="checkbox"
  112. checked={config.tightBorder}
  113. onChange={(e) =>
  114. updateConfig(
  115. (config) => (config.tightBorder = e.currentTarget.checked)
  116. )
  117. }
  118. ></input>
  119. </ListItem>
  120. </List>
  121. <List>
  122. <ListItem>
  123. <div className={styles["settings-title"]}>最大上下文消息数</div>
  124. <input
  125. type="range"
  126. title={config.historyMessageCount.toString()}
  127. value={config.historyMessageCount}
  128. min="5"
  129. max="20"
  130. step="5"
  131. onChange={(e) =>
  132. updateConfig(
  133. (config) =>
  134. (config.historyMessageCount = e.target.valueAsNumber)
  135. )
  136. }
  137. ></input>
  138. </ListItem>
  139. <ListItem>
  140. <div className={styles["settings-title"]}>
  141. 上下文中包含机器人消息
  142. </div>
  143. <input
  144. type="checkbox"
  145. checked={config.sendBotMessages}
  146. onChange={(e) =>
  147. updateConfig(
  148. (config) => (config.sendBotMessages = e.currentTarget.checked)
  149. )
  150. }
  151. ></input>
  152. </ListItem>
  153. </List>
  154. </div>
  155. </>
  156. );
  157. }