* 单个快捷设置项按钮
({
settingKey,
isHovered,
}: {
settingKey: keyof typeof settingsSchema.shape;
isHovered: boolean;
})
| 169 | * 单个快捷设置项按钮 |
| 170 | */ |
| 171 | function QuickSettingButton({ |
| 172 | settingKey, |
| 173 | isHovered, |
| 174 | }: { |
| 175 | settingKey: keyof typeof settingsSchema.shape; |
| 176 | isHovered: boolean; |
| 177 | }) { |
| 178 | const { t } = useTranslation("settings"); |
| 179 | const [showDialog, setShowDialog] = useState(false); |
| 180 | const settingType = QuickSettingsManager.getSettingType(settingKey as string); |
| 181 | |
| 182 | // Boolean 类型用于图标 opacity 动态显示 |
| 183 | const [boolValue, setBoolValue] = useState<boolean>( |
| 184 | settingType === "boolean" ? (Settings[settingKey] as boolean) : false, |
| 185 | ); |
| 186 | |
| 187 | useEffect(() => { |
| 188 | if (settingType !== "boolean") return; |
| 189 | const unwatch = Settings.watch(settingKey, (newValue) => { |
| 190 | if (typeof newValue === "boolean") setBoolValue(newValue); |
| 191 | }); |
| 192 | return unwatch; |
| 193 | }, [settingKey, settingType]); |
| 194 | |
| 195 | const Icon = settingsIcons[settingKey as keyof typeof settingsIcons] ?? Fragment; |
| 196 | const title = t(`${settingKey as string}.title` as string); |
| 197 | const description = t(`${settingKey as string}.description` as string); |
| 198 | |
| 199 | if (Icon === Fragment) return null; |
| 200 | |
| 201 | // 图标 opacity:boolean 用 on/off 状态;enum/number 始终半透明 |
| 202 | const iconOpacityClass = |
| 203 | settingType === "boolean" |
| 204 | ? cn("opacity-50 transition-opacity hover:opacity-100", boolValue && "opacity-100") |
| 205 | : "opacity-70 transition-opacity hover:opacity-100"; |
| 206 | |
| 207 | return ( |
| 208 | <> |
| 209 | <Tooltip> |
| 210 | <TooltipTrigger asChild> |
| 211 | <div className="flex items-center gap-1.5"> |
| 212 | <Button className={iconOpacityClass} variant="ghost" size="icon" onClick={() => setShowDialog(true)}> |
| 213 | <Icon /> |
| 214 | </Button> |
| 215 | |
| 216 | {/* 根据类型展示不同控件 */} |
| 217 | {settingType === "boolean" && <BooleanQuickSettingControl settingKey={settingKey} isHovered={isHovered} />} |
| 218 | {settingType === "enum" && <EnumQuickSettingControl settingKey={settingKey} isHovered={isHovered} />} |
| 219 | {settingType === "number" && <NumberQuickSettingControl settingKey={settingKey} isHovered={isHovered} />} |
| 220 | </div> |
| 221 | </TooltipTrigger> |
| 222 | <TooltipContent side="left">{title}</TooltipContent> |
| 223 | </Tooltip> |
| 224 | |
| 225 | <Dialog open={showDialog} onOpenChange={setShowDialog}> |
| 226 | <DialogContent> |
| 227 | <DialogHeader> |
| 228 | <DialogTitle className="flex items-center gap-2"> |