[FEATURE] 写了一点设置页面
This commit is contained in:
parent
68bec5b9a5
commit
9eb4a1c991
6
.idea/inspectionProfiles/Project_Default.xml
Normal file
6
.idea/inspectionProfiles/Project_Default.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="Eslint" enabled="false" level="TEXT ATTRIBUTES" enabled_by_default="false" editorAttributes="TEXT_STYLE_SUGGESTION" />
|
||||
</profile>
|
||||
</component>
|
@ -4,7 +4,7 @@
|
||||
* Private Build for Chongqing Banan Middle School
|
||||
* */
|
||||
import toast, { Toaster } from 'react-hot-toast';
|
||||
import {useCallback, useReducer, useState} from 'react'
|
||||
import { useCallback, useReducer, useRef, useState } from 'react'
|
||||
import {Transition} from '@headlessui/react'
|
||||
import {Slider, SliderThumb, SliderTrack} from 'react-aria-components';
|
||||
import ChangedEasterEgg1 from "./assets/changed-1.png"
|
||||
@ -17,6 +17,7 @@ import ChangedEasterEgg7 from "./assets/changed-7.png"
|
||||
import PPT2021 from "./icons/powerpoint2019-365.png"
|
||||
|
||||
import '@radix-ui/themes/styles.css';
|
||||
import YasatSettingsWindow from './YasatSettingsWindow.jsx'
|
||||
|
||||
function YasatToolbarReducer(state, action) {
|
||||
switch (action.action) {
|
||||
@ -1133,6 +1134,9 @@ function EmptyInkSlider(p) {
|
||||
}
|
||||
|
||||
export default function YasatMainWindow(props) {
|
||||
|
||||
const YasatSettingsWindowRef = useRef(null);
|
||||
|
||||
const [state, dispatch] = useReducer(YasatToolbarReducer, {
|
||||
activedTool: "cursor",
|
||||
displayPenMenu: false,
|
||||
@ -1153,36 +1157,62 @@ export default function YasatMainWindow(props) {
|
||||
eraserMode: "circle",
|
||||
eraserSize: 75,
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* 设置默认笔的墨迹大小
|
||||
* @param size {number} 墨迹大小
|
||||
* @param isHighlight {boolean} 是否为荧光笔设置墨迹大小
|
||||
* @imprue
|
||||
* */
|
||||
const setPenSize = useCallback((size, isHighlight) => {
|
||||
dispatch({
|
||||
action: isHighlight ? "setHighlightSize" : "setPenSize",
|
||||
size: size,
|
||||
})
|
||||
}, []);
|
||||
|
||||
|
||||
/**
|
||||
* 设置默认激光笔墨迹的消逝时长
|
||||
* @param time {number} 消逝时长
|
||||
* @imprue
|
||||
* */
|
||||
const setLaserFadeOutTime = useCallback((time) => {
|
||||
dispatch({
|
||||
action: "setLaserFadeOutTime",
|
||||
time: time,
|
||||
})
|
||||
}, []);
|
||||
|
||||
|
||||
/**
|
||||
* 设置所有笔墨迹的Alpha通道值
|
||||
* @param alpha {number} Alpha通道值
|
||||
* @imprue
|
||||
* */
|
||||
const setPenAlpha = useCallback((alpha) => {
|
||||
dispatch({
|
||||
action: "setPenAlpha",
|
||||
alpha: alpha,
|
||||
})
|
||||
}, []);
|
||||
|
||||
|
||||
/**
|
||||
* 设置面积擦橡皮面积大小
|
||||
* @param size {number} 橡皮擦大小
|
||||
* @imprue
|
||||
* */
|
||||
const setEraserSize = useCallback((size) => {
|
||||
dispatch({
|
||||
action: "setEraserSize",
|
||||
size: size,
|
||||
})
|
||||
}, []);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 根据颜色名称获取在penType==="pen"的情况下的颜色
|
||||
* @param color {string} 颜色名称
|
||||
* @return {string} 颜色HEX值
|
||||
* @prue
|
||||
* */
|
||||
const getPenColor = useCallback((color) => {
|
||||
const colorMap = {
|
||||
red: "#dc2626",
|
||||
@ -1197,7 +1227,13 @@ export default function YasatMainWindow(props) {
|
||||
}
|
||||
return colorMap[color] ?? color
|
||||
}, [])
|
||||
|
||||
|
||||
/**
|
||||
* 根据颜色名称获取在penType==="highlight"的情况下的颜色
|
||||
* @param color {string} 颜色名称
|
||||
* @return {string} 颜色HEX值
|
||||
* @prue
|
||||
* */
|
||||
const getHighlightColor = useCallback((color) => {
|
||||
const colorMap = {
|
||||
yellow: "#FDE047",
|
||||
@ -1211,6 +1247,56 @@ export default function YasatMainWindow(props) {
|
||||
}
|
||||
return colorMap[color] ?? color
|
||||
}, [])
|
||||
|
||||
/**
|
||||
* 根据颜色名称获取当前penType以及penColor的颜色
|
||||
* @param isName {string} 是否返回颜色名称而不是对应的HEX值
|
||||
* @return {string} 颜色HEX值
|
||||
* */
|
||||
const getActivedPenTypeColor = useCallback(
|
||||
(isName) => {
|
||||
let ret;
|
||||
if (state.penType==="pen"){
|
||||
ret = !isName?getPenColor(state.penColor):state.penColor;
|
||||
} else if (state.penType==="highlight"){
|
||||
ret = !isName?getHighlightColor(state.highlightColor):state.highlightColor;
|
||||
} else if (state.penType==="laser"){
|
||||
ret = !isName?({
|
||||
"red": "#FF0000",
|
||||
"blue": "#0000FF",
|
||||
"green": "#00FF00",
|
||||
})[state.laserColor]:state.laserColor;
|
||||
}
|
||||
return ret;
|
||||
},
|
||||
[state.penType,state.highlightColor,state.penColor,state.laserColor],
|
||||
);
|
||||
|
||||
/**
|
||||
* 根据颜色名称获取其中文描述性名称
|
||||
* @param name {string} 颜色名称
|
||||
* @return {string} 颜色中文名称
|
||||
* @pure
|
||||
* */
|
||||
const getColorNameChineseLabel = useCallback(
|
||||
(name) => {
|
||||
return ({
|
||||
"red": "红色",
|
||||
"yellow": "黄色",
|
||||
"orange": "橙色",
|
||||
"green": "绿色",
|
||||
"cyan": "青色",
|
||||
"blue": "蓝色",
|
||||
"indigo": "靛蓝",
|
||||
"purple": "紫色",
|
||||
"pink": "粉色",
|
||||
"white": "白色",
|
||||
"black": "黑色",
|
||||
})[name]
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -2672,8 +2758,8 @@ export default function YasatMainWindow(props) {
|
||||
<div className="text-lg text-white mt-2.5">{state.penType==="pen"?"笔":state.penType==="highlight"?"荧光笔":"激光笔"} <span className="font-bold">批注</span> 模式</div>
|
||||
<div className="text-md text-white mt-1 flex items-center space-x-2">
|
||||
<div className="h-4.5 w-4.5 rounded-full brightness-120" style={{backgroundColor:state.penType==="pen"?getPenColor(state.penColor):state.penType==="highlight"?getHighlightColor(state.highlightColor):state.penType==="laser"?state.laserColor:"white"}}></div>
|
||||
<div className="brightness-200" style={{color:state.penType==="pen"?getPenColor(state.penColor):state.penType==="highlight"?getHighlightColor(state.highlightColor):state.penType==="laser"?state.laserColor:"white"}}>{(state.penType==="pen"?state.penColor:state.penType==="highlight"?state.highlightColor:state.laserColor)==="red"?"红色":(state.penType==="pen"?state.penColor:state.penType==="highlight"?state.highlightColor:state.laserColor)==="orange"?"橙色":(state.penType==="pen"?state.penColor:state.penType==="highlight"?state.highlightColor:state.laserColor)==="green"?"绿色":(state.penType==="pen"?state.penColor:state.penType==="highlight"?state.highlightColor:state.laserColor)==="cyan"?"靛青":(state.penType==="pen"?state.penColor:state.penType==="highlight"?state.highlightColor:state.laserColor)==="blue"?"蓝色":(state.penType==="pen"?state.penColor:state.penType==="highlight"?state.highlightColor:state.laserColor)==="indigo"?"靛蓝":(state.penType==="pen"?state.penColor:state.penType==="highlight"?state.highlightColor:state.laserColor)==="purple"?"紫色":(state.penType==="pen"?state.penColor:state.penType==="highlight"?state.highlightColor:state.laserColor)==="pink"?"粉色":(state.penType==="pen"?state.penColor:state.penType==="highlight"?state.highlightColor:state.laserColor)==="yellow"?"黄色":(state.penType==="pen"?state.penColor:state.penType==="highlight"?state.highlightColor:state.laserColor)==="black"?"黑色":(state.penType==="pen"?state.penColor:state.penType==="highlight"?state.highlightColor:state.laserColor)==="white"?"白色":""}</div>
|
||||
<div className="text-white font-bold">{state.penSize}点</div>
|
||||
<div className="brightness-200" style={{color:getActivedPenTypeColor(false)}}>{getColorNameChineseLabel(getActivedPenTypeColor(true))}</div>
|
||||
<div className="text-white font-bold">{state.penType==="pen"?state.penSize:state.penType==="highlight"?state.highlightSize:state.penType==="laser"?state.penSize:state.penSize}点</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@ -2810,6 +2896,25 @@ export default function YasatMainWindow(props) {
|
||||
) : (
|
||||
<div onClick={() => {
|
||||
toast.remove()
|
||||
if (state.activedTool!=="cursor") {
|
||||
toast.custom(
|
||||
<div className="flex flex-col bg-zinc-800/50 h-42 w-42 rounded-md items-center justify-center select-none pointer-events-none backdrop-blur-md">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
strokeWidth={1.5}
|
||||
fill="currentColor"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
className="h-16 w-16 text-white"
|
||||
>
|
||||
<path d="M7 21l-4.3-4.3c-1-1-1-2.5 0-3.4l9.6-9.6c1-1 2.5-1 3.4 0l5.6 5.6c1 1 1 2.5 0 3.4L13 21M22 21H7M5 11l9 9" />
|
||||
</svg>
|
||||
<div className="text-lg text-white mt-4">当前 <span className="font-bold">橡皮</span> 模式</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
dispatch({
|
||||
action: "hideAllMenu",
|
||||
})
|
||||
@ -3249,7 +3354,9 @@ export default function YasatMainWindow(props) {
|
||||
<div className="text-sm">切换演讲者视图</div>
|
||||
</div>
|
||||
<div className="w-full h-px bg-zinc-300 my-1"></div>
|
||||
<div className="active:(bg-blue-600 text-white scale-97) transition-transform text-zinc-800 rounded-md mx-1 flex space-x-2 items-center px-1.75 py-1.5">
|
||||
<div onClick={()=>{
|
||||
YasatSettingsWindowRef.current.openSettingsWindow();
|
||||
}} className="active:(bg-blue-600 text-white scale-97) transition-transform text-zinc-800 rounded-md mx-1 flex space-x-2 items-center px-1.75 py-1.5">
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
className="h-5 w-5"
|
||||
viewBox="0 0 24 24"
|
||||
@ -3390,6 +3497,8 @@ export default function YasatMainWindow(props) {
|
||||
</div>
|
||||
</Transition>
|
||||
</div>
|
||||
|
||||
{/*LeftToolBar*/}
|
||||
<div className="flex h-fit w-fit items-center justify-center space-x-1">
|
||||
<div className="rounded-lg transition-all bg-zinc-50 border border-zinc-300 shadow-md flex w-fit items-center justify-center select-none overflow-clip">
|
||||
<div onClick={() => {
|
||||
@ -3577,6 +3686,7 @@ export default function YasatMainWindow(props) {
|
||||
</div>
|
||||
|
||||
<Toaster position="bottom-center" containerClassName="mb-18" />
|
||||
<YasatSettingsWindow ref={YasatSettingsWindowRef}/>
|
||||
</>
|
||||
)
|
||||
}
|
550
frontend/dot-yasat/src/YasatSettingsWindow.jsx
Normal file
550
frontend/dot-yasat/src/YasatSettingsWindow.jsx
Normal file
@ -0,0 +1,550 @@
|
||||
/*
|
||||
* Copyright 2023-2024 KriaStans
|
||||
* Copyright 2023-2024 HARKOTEK
|
||||
* Private Build for Chongqing Banan Middle School
|
||||
* */
|
||||
import {Transition} from '@headlessui/react'
|
||||
import { forwardRef, useImperativeHandle, useReducer, useState } from 'react'
|
||||
import { ReactLenis } from '@studio-freight/react-lenis'
|
||||
import { Slider, SliderThumb, SliderTrack } from 'react-aria-components'
|
||||
import logo from "./assets/dot-yasat-logo.png"
|
||||
|
||||
function YasatSettingsWindowReducer(state, action){
|
||||
return {...state,[action.key]:action.value};
|
||||
}
|
||||
|
||||
export default forwardRef(function YasatSettingsWindow(props, ref){
|
||||
useImperativeHandle(
|
||||
ref,
|
||||
() => {
|
||||
return {
|
||||
openSettingsWindow: function(){
|
||||
setOpen(true)
|
||||
}
|
||||
}
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
const [state, dispatch] = useReducer(YasatSettingsWindowReducer, {
|
||||
// 是否启用更新
|
||||
"update.enable": true,
|
||||
// 是否启用自动更新
|
||||
"update.autoUpdate": true,
|
||||
// 是否开机启动
|
||||
"start.startOnBoot": false,
|
||||
|
||||
// 显示画笔光标
|
||||
"canvas.displayCursor": true,
|
||||
// 禁用多点触摸
|
||||
"canvas.disableMultiPointTouch": false,
|
||||
// 橡皮默认大小
|
||||
"eraser.defaultSize": 75,
|
||||
// 笔默认大小
|
||||
"pen.defaultSize": 2,
|
||||
// 荧光笔默认大小
|
||||
"highlight.defaultSize": 20,
|
||||
// 模拟笔锋
|
||||
"ink.emulateStroke": true,
|
||||
// 平滑笔锋
|
||||
"ink.smoothStroke": false,
|
||||
// 清屏时清理buffer
|
||||
"canvas.clearBuffer": true,
|
||||
|
||||
// 尝试兼容WPS
|
||||
"wps.compact": false,
|
||||
// 使用WPS-Javascript扩展
|
||||
"wps.javascriptPlugin": false,
|
||||
// 使用LibreOffice-Python扩展
|
||||
"libreoffice.pythonPlugin": false,
|
||||
// 强制365
|
||||
"powerpoint.force365": false,
|
||||
});
|
||||
|
||||
const [open, setOpen] = useState(false)
|
||||
|
||||
return (
|
||||
<>
|
||||
<Transition
|
||||
show={open}
|
||||
enter="delay-200"
|
||||
enterFrom="opacity-0"
|
||||
enterTo="opacity-100"
|
||||
leave=""
|
||||
leaveFrom="opacity-100"
|
||||
leaveTo="opacity-0"
|
||||
>
|
||||
<div className="fixed z-100 left-0 top-0 w-screen h-screen flex flex-shrink-0 shrink-0 items-center justify-center">
|
||||
<div className="w-116 h-70vh bg-white rounded-md p-6 pr-0 py-8 flex flex-col">
|
||||
<div className="flex items-center justify-between mb-6 pr-6">
|
||||
<div className="flex items-center space-x-2 select-none">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-7.5 w-7.5" viewBox="0 0 24 24" strokeWidth={2} stroke="currentColor" fill="none" strokeLinecap="round" strokeLinejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M10.325 4.317c.426 -1.756 2.924 -1.756 3.35 0a1.724 1.724 0 0 0 2.573 1.066c1.543 -.94 3.31 .826 2.37 2.37a1.724 1.724 0 0 0 1.065 2.572c1.756 .426 1.756 2.924 0 3.35a1.724 1.724 0 0 0 -1.066 2.573c.94 1.543 -.826 3.31 -2.37 2.37a1.724 1.724 0 0 0 -2.572 1.065c-.426 1.756 -2.924 1.756 -3.35 0a1.724 1.724 0 0 0 -2.573 -1.066c-1.543 .94 -3.31 -.826 -2.37 -2.37a1.724 1.724 0 0 0 -1.065 -2.572c-1.756 -.426 -1.756 -2.924 0 -3.35a1.724 1.724 0 0 0 1.066 -2.573c-.94 -1.543 .826 -3.31 2.37 -2.37c1 .608 2.296 .07 2.572 -1.065z" />
|
||||
<path d="M9 12a3 3 0 1 0 6 0a3 3 0 0 0 -6 0" />
|
||||
</svg>
|
||||
<div className="text-2xl font-bold">设置</div>
|
||||
</div>
|
||||
<div onClick={()=>{setOpen(false)}} className="rounded-full active:bg-zinc-300/50 p-2 text-zinc-800">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth={2}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
className="h-7 w-7"
|
||||
>
|
||||
<path d="M18 6L6 18M6 6l12 12" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<ReactLenis options={{
|
||||
duraton : 0.05,
|
||||
}} className="select-none pr-6 w-full grow overflow-y-scroll scrollbar scrollbar-thumb-color-zinc-800/50 scrollbar-w-1 scrollbar-rounded overflow-x-clip flex flex-col">
|
||||
<div className="h-fit w-full">
|
||||
<div className="text-center text-sm font-medium text-zinc-800 mb-2 select-none">设置将自动保存,若无特别说明则选项修改后立刻生效</div>
|
||||
<div className="flex flex-col gap-y-2">
|
||||
<div className="flex space-x-2 items-center justify-center p-2 bg-blue-700 text-white rounded-full select-none transition-all active:(scale-98 brightness-90)">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth={1.5}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
className="h-4.5 w-4.5"
|
||||
>
|
||||
<path d="M15 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V7z" />
|
||||
<path d="M14 2v4a2 2 0 002 2h4M8 12h8M10 11v2M8 17h8M14 16v2" />
|
||||
</svg>
|
||||
<div className="text-sm">重置为巴南中学专用配置</div>
|
||||
</div>
|
||||
<div className="flex space-x-2 items-center justify-center p-2 bg-blue-700 text-white rounded-full select-none transition-all active:(scale-98 brightness-90)">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth={1.5}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
className="h-4.5 w-4.5"
|
||||
>
|
||||
<path d="M15 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V7z" />
|
||||
<path d="M14 2v4a2 2 0 002 2h4M8 12h8M10 11v2M8 17h8M14 16v2" />
|
||||
</svg>
|
||||
<div className="text-sm">重置为希沃一体机默认配置</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-x-2">
|
||||
<div className="flex space-x-2 items-center justify-center p-3 bg-red-600 text-white rounded-md select-none transition-all active:(scale-98 brightness-90)">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-4.75 w-4.75" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" fill="none" strokeLinecap="round" strokeLinejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M14 8v-2a2 2 0 0 0 -2 -2h-7a2 2 0 0 0 -2 2v12a2 2 0 0 0 2 2h7a2 2 0 0 0 2 -2v-2" />
|
||||
<path d="M9 12h12l-3 -3" />
|
||||
<path d="M18 15l3 -3" />
|
||||
</svg>
|
||||
<div className="text-sm">关闭软件</div>
|
||||
</div>
|
||||
<div className="flex space-x-2 items-center justify-center p-3 bg-yellow-600 text-white rounded-md select-none transition-all active:(scale-98 brightness-90)">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-4.75 w-4.75" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" fill="none" strokeLinecap="round" strokeLinejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M12 6l0 -3" />
|
||||
<path d="M16.25 7.75l2.15 -2.15" />
|
||||
<path d="M18 12l3 0" />
|
||||
<path d="M16.25 16.25l2.15 2.15" />
|
||||
<path d="M12 18l0 3" />
|
||||
<path d="M7.75 16.25l-2.15 2.15" />
|
||||
<path d="M6 12l-3 0" />
|
||||
<path d="M7.75 7.75l-2.15 -2.15" />
|
||||
</svg>
|
||||
<div className="text-sm">重启软件</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2 select-none mb-3 mt-6">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth={1.75}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
className="h-5.25 w-5.25"
|
||||
>
|
||||
<circle cx={12} cy={12} r={10} />
|
||||
<path d="M10 8L16 12 10 16 10 8z" />
|
||||
</svg>
|
||||
<div className="text-xl">启动</div>
|
||||
</div>
|
||||
<div className="flex flex-col gap-y-4">
|
||||
<div className="flex flex-col">
|
||||
<div className="text-base font-bold text-zinc-800">允许软件联网更新</div>
|
||||
<div className="text-sm text-zinc-500">关闭后将不会联网检查更新且禁用更新功能</div>
|
||||
<div className="flex items-center space-x-2 mt-1">
|
||||
<div onClick={() => {
|
||||
dispatch({
|
||||
key: "update.enable",
|
||||
value: !state["update.enable"]
|
||||
})
|
||||
}}
|
||||
className={"rounded-full h-5.625 w-10 flex group items-center px-0.8125 transition-all " + (state["update.enable"] === true ? "bg-blue-600 border-1 border-blue-800/50 justify-end" : "bg-zinc-500/50 border-1 border-zinc-600/50 justify-start")}>
|
||||
<div className={"h-3.75 w-3.75 bg-white rounded-full group-active:(w-5) transition-all"}></div>
|
||||
</div>
|
||||
<div className="text-sm">{state["update.enable"]?"开":"关"}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<div className="text-base font-bold text-zinc-800">自动检查更新</div>
|
||||
<div className="text-sm text-zinc-500">每次软件启动时检查更新</div>
|
||||
<div className="flex items-center space-x-2 mt-1">
|
||||
<div onClick={() => {
|
||||
dispatch({
|
||||
key: "update.autoUpdate",
|
||||
value: !state["update.autoUpdate"]
|
||||
})
|
||||
}}
|
||||
className={"rounded-full h-5.625 w-10 flex group items-center px-0.8125 transition-all " + (state["update.autoUpdate"] === true ? "bg-blue-600 border-1 border-blue-800/50 justify-end" : "bg-zinc-500/50 border-1 border-zinc-600/50 justify-start")}>
|
||||
<div className={"h-3.75 w-3.75 bg-white rounded-full group-active:(w-5) transition-all"}></div>
|
||||
</div>
|
||||
<div className="text-sm">{state["update.autoUpdate"]?"开":"关"}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<div className="text-base font-bold text-zinc-800">开机自启动</div>
|
||||
<div className="text-sm text-zinc-500">开机后自动启动dot-yasat,放映PPT能更快加载</div>
|
||||
<div className="flex items-center space-x-2 mt-1">
|
||||
<div onClick={() => {
|
||||
dispatch({
|
||||
key: "start.startOnBoot",
|
||||
value: !state["start.startOnBoot"]
|
||||
})
|
||||
}}
|
||||
className={"rounded-full h-5.625 w-10 flex group items-center px-0.8125 transition-all " + (state["start.startOnBoot"] === true ? "bg-blue-600 border-1 border-blue-800/50 justify-end" : "bg-zinc-500/50 border-1 border-zinc-600/50 justify-start")}>
|
||||
<div className={"h-3.75 w-3.75 bg-white rounded-full group-active:(w-5) transition-all"}></div>
|
||||
</div>
|
||||
<div className="text-sm">{state["start.startOnBoot"]?"开":"关"}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2 select-none mb-3 mt-6">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth={1.75}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
className="h-5.25 w-5.25"
|
||||
>
|
||||
<path d="M15 5l4 4M13 7L8.7 2.7a2.41 2.41 0 00-3.4 0L2.7 5.3a2.41 2.41 0 000 3.4L7 13M8 6l2-2M2 22l5.5-1.5L21.17 6.83a2.82 2.82 0 00-4-4L3.5 16.5zM18 16l2-2" />
|
||||
<path d="M17 11l4.3 4.3c.94.94.94 2.46 0 3.4l-2.6 2.6c-.94.94-2.46.94-3.4 0L11 17" />
|
||||
</svg>
|
||||
<div className="text-xl">画布</div>
|
||||
</div>
|
||||
<div className="flex flex-col gap-y-4">
|
||||
<div className="flex flex-col">
|
||||
<div className="text-base font-bold text-zinc-800">显示明显的光标</div>
|
||||
<div className="text-sm text-zinc-500">在使用鼠标移动/绘制/操作时显示明显的对应工具的光标</div>
|
||||
<div className="text-sm text-red-600 font-bold">仅当CEFPython能正确识别到触摸事件时才生效</div>
|
||||
<div className="flex items-center space-x-2 mt-1">
|
||||
<div onClick={() => {
|
||||
dispatch({
|
||||
key: "canvas.displayCursor",
|
||||
value: !state["canvas.displayCursor"]
|
||||
})
|
||||
}}
|
||||
className={"rounded-full h-5.625 w-10 flex group items-center px-0.8125 transition-all " + (state["canvas.displayCursor"] === true ? "bg-blue-600 border-1 border-blue-800/50 justify-end" : "bg-zinc-500/50 border-1 border-zinc-600/50 justify-start")}>
|
||||
<div className={"h-3.75 w-3.75 bg-white rounded-full group-active:(w-5) transition-all"}></div>
|
||||
</div>
|
||||
<div className="text-sm">{state["canvas.displayCursor"]?"开":"关"}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<div className="text-base font-bold text-zinc-800">禁用多点触摸事件</div>
|
||||
<div className="text-sm text-zinc-500">若尝试多点操作时遇到问题直接禁用多点触摸即可</div>
|
||||
<div className="flex items-center space-x-2 mt-1">
|
||||
<div onClick={() => {
|
||||
dispatch({
|
||||
key: "canvas.disableMultiPointTouch",
|
||||
value: !state["canvas.disableMultiPointTouch"]
|
||||
})
|
||||
}}
|
||||
className={"rounded-full h-5.625 w-10 flex group items-center px-0.8125 transition-all " + (state["canvas.disableMultiPointTouch"] === true ? "bg-blue-600 border-1 border-blue-800/50 justify-end" : "bg-zinc-500/50 border-1 border-zinc-600/50 justify-start")}>
|
||||
<div className={"h-3.75 w-3.75 bg-white rounded-full group-active:(w-5) transition-all"}></div>
|
||||
</div>
|
||||
<div className="text-sm">{state["canvas.disableMultiPointTouch"]?"开":"关"}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<div className="text-base font-bold text-zinc-800">橡皮默认大小:{state["eraser.defaultSize"]}</div>
|
||||
<div className="text-sm text-zinc-500">会在重置后恢复到默认大小</div>
|
||||
<div className="flex items-center space-x-2 mt-1">
|
||||
<Slider className="w-full bg-gradient-to-b from-zinc-300 to-zinc-200 h-5 border-1 border-zinc-400/40 rounded-full relative overflow-clip px-2.5"
|
||||
aria-label="slider"
|
||||
minValue={50}
|
||||
maxValue={200}
|
||||
step={1}
|
||||
value={state["eraser.defaultSize"]}
|
||||
onChange={(val)=>dispatch({key:"eraser.defaultSize",value:val})}>
|
||||
<SliderTrack className="w-full h-full">
|
||||
{({state}) => (
|
||||
<>
|
||||
{/*<div className="bg-blue-600 rounded-full absolute top-px bottom-px -left-2.5 ring-1 ring-blue-800 flex justify-end items-center transition-all duration-100 ease-in-out" style={{width: (state.getThumbPercent(0) * 100-1) + "%"}}/>*/}
|
||||
<div className="bg-gradient-to-b from-red-500 to-red-700 absolute top-0 bottom-0 -left-2.5 flex justify-end items-center transition-all duration-50 ease-in-out"
|
||||
style={{width: (state.getThumbPercent(0) * 100) + "%"}} />
|
||||
<SliderThumb className="h-5 w-5 top-50% transition-all duration-50 ease-in-out group">
|
||||
<div className="h-5 w-6 bg-gradient-to-b from-red-500 to-red-700 rounded-r-full -translate-x-1 flex items-center justify-center">
|
||||
<div className="h-3 w-3 bg-red-100 group-active:(scale-120 bg-white shadow-md) transition-all rounded-full ml-1"></div>
|
||||
</div>
|
||||
</SliderThumb>
|
||||
</>
|
||||
)}
|
||||
</SliderTrack>
|
||||
</Slider>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<div className="text-base font-bold text-zinc-800">笔默认大小:{state["pen.defaultSize"]}</div>
|
||||
<div className="text-sm text-zinc-500">会在重置后恢复到默认大小</div>
|
||||
<div className="flex items-center space-x-2 mt-1">
|
||||
<Slider className="w-full bg-gradient-to-b from-zinc-300 to-zinc-200 h-5 border-1 border-zinc-400/40 rounded-full relative overflow-clip px-2.5"
|
||||
aria-label="slider"
|
||||
minValue={1}
|
||||
maxValue={20}
|
||||
step={0.5}
|
||||
value={state["pen.defaultSize"]}
|
||||
onChange={(val)=>dispatch({key:"pen.defaultSize",value:val})}>
|
||||
<SliderTrack className="w-full h-full">
|
||||
{({state}) => (
|
||||
<>
|
||||
{/*<div className="bg-blue-600 rounded-full absolute top-px bottom-px -left-2.5 ring-1 ring-blue-800 flex justify-end items-center transition-all duration-100 ease-in-out" style={{width: (state.getThumbPercent(0) * 100-1) + "%"}}/>*/}
|
||||
<div className="bg-gradient-to-b from-red-500 to-red-700 absolute top-0 bottom-0 -left-2.5 flex justify-end items-center transition-all duration-50 ease-in-out"
|
||||
style={{width: (state.getThumbPercent(0) * 100) + "%"}} />
|
||||
<SliderThumb className="h-5 w-5 top-50% transition-all duration-50 ease-in-out group">
|
||||
<div className="h-5 w-6 bg-gradient-to-b from-red-500 to-red-700 rounded-r-full -translate-x-1 flex items-center justify-center">
|
||||
<div className="h-3 w-3 bg-red-100 group-active:(scale-120 bg-white shadow-md) transition-all rounded-full ml-1"></div>
|
||||
</div>
|
||||
</SliderThumb>
|
||||
</>
|
||||
)}
|
||||
</SliderTrack>
|
||||
</Slider>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<div className="text-base font-bold text-zinc-800">荧光笔默认大小:{state["highlight.defaultSize"]}</div>
|
||||
<div className="text-sm text-zinc-500">会在重置后恢复到默认大小</div>
|
||||
<div className="flex items-center space-x-2 mt-1">
|
||||
<Slider className="w-full bg-gradient-to-b from-zinc-300 to-zinc-200 h-5 border-1 border-zinc-400/40 rounded-full relative overflow-clip px-2.5"
|
||||
aria-label="slider"
|
||||
minValue={10}
|
||||
maxValue={50}
|
||||
step={1}
|
||||
value={state["highlight.defaultSize"]}
|
||||
onChange={(val)=>dispatch({key:"highlight.defaultSize",value:val})}>
|
||||
<SliderTrack className="w-full h-full">
|
||||
{({state}) => (
|
||||
<>
|
||||
{/*<div className="bg-blue-600 rounded-full absolute top-px bottom-px -left-2.5 ring-1 ring-blue-800 flex justify-end items-center transition-all duration-100 ease-in-out" style={{width: (state.getThumbPercent(0) * 100-1) + "%"}}/>*/}
|
||||
<div className="bg-gradient-to-b from-red-500 to-red-700 absolute top-0 bottom-0 -left-2.5 flex justify-end items-center transition-all duration-50 ease-in-out"
|
||||
style={{width: (state.getThumbPercent(0) * 100) + "%"}} />
|
||||
<SliderThumb className="h-5 w-5 top-50% transition-all duration-50 ease-in-out group">
|
||||
<div className="h-5 w-6 bg-gradient-to-b from-red-500 to-red-700 rounded-r-full -translate-x-1 flex items-center justify-center">
|
||||
<div className="h-3 w-3 bg-red-100 group-active:(scale-120 bg-white shadow-md) transition-all rounded-full ml-1"></div>
|
||||
</div>
|
||||
</SliderThumb>
|
||||
</>
|
||||
)}
|
||||
</SliderTrack>
|
||||
</Slider>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<div className="text-base font-bold text-zinc-800">仅使用软件模拟笔锋</div>
|
||||
<div className="text-sm text-zinc-500">若触摸屏不支持压感或返回固定值,请开启此选项</div>
|
||||
<div className="text-sm text-green-600">一体机用户请打开该选项,因为绝大多数一体机都会返回固定的压感数据而导致硬件笔锋无法使用。</div>
|
||||
<div className="flex items-center space-x-2 mt-1">
|
||||
<div onClick={() => {
|
||||
dispatch({
|
||||
key: "ink.emulateStroke",
|
||||
value: !state["ink.emulateStroke"]
|
||||
})
|
||||
}}
|
||||
className={"rounded-full h-5.625 w-10 flex group items-center px-0.8125 transition-all " + (state["ink.emulateStroke"] === true ? "bg-blue-600 border-1 border-blue-800/50 justify-end" : "bg-zinc-500/50 border-1 border-zinc-600/50 justify-start")}>
|
||||
<div className={"h-3.75 w-3.75 bg-white rounded-full group-active:(w-5) transition-all"}></div>
|
||||
</div>
|
||||
<div className="text-sm">{state["ink.emulateStroke"]?"开":"关"}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<div className="text-base font-bold text-zinc-800">尝试使墨迹更平滑</div>
|
||||
<div className="text-sm text-zinc-500">通过精简墨迹行程以及柔滑墨迹边缘来使墨迹更加平滑</div>
|
||||
<div className="text-sm text-red-600 font-bold">该功能是实验性功能,且开启后效果不大,还可能会导致墨迹偏移(精简墨迹行程而造成的墨迹偏移现象)</div>
|
||||
<div className="flex items-center space-x-2 mt-1">
|
||||
<div onClick={() => {
|
||||
dispatch({
|
||||
key: "ink.smoothStroke",
|
||||
value: !state["ink.smoothStroke"]
|
||||
})
|
||||
}}
|
||||
className={"rounded-full h-5.625 w-10 flex group items-center px-0.8125 transition-all " + (state["ink.smoothStroke"] === true ? "bg-blue-600 border-1 border-blue-800/50 justify-end" : "bg-zinc-500/50 border-1 border-zinc-600/50 justify-start")}>
|
||||
<div className={"h-3.75 w-3.75 bg-white rounded-full group-active:(w-5) transition-all"}></div>
|
||||
</div>
|
||||
<div className="text-sm">{state["ink.smoothStroke"]?"开":"关"}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<div className="text-base font-bold text-zinc-800">清屏时清理缓存Buffer</div>
|
||||
<div className="text-sm text-zinc-500">清屏时清理掉缓存Buffer,开启后清屏后将无法使用撤销恢复墨迹,且将清理所有历史记录状态。</div>
|
||||
<div className="flex items-center space-x-2 mt-1">
|
||||
<div onClick={() => {
|
||||
dispatch({
|
||||
key: "canvas.clearBuffer",
|
||||
value: !state["canvas.clearBuffer"]
|
||||
})
|
||||
}}
|
||||
className={"rounded-full h-5.625 w-10 flex group items-center px-0.8125 transition-all " + (state["canvas.clearBuffer"] === true ? "bg-blue-600 border-1 border-blue-800/50 justify-end" : "bg-zinc-500/50 border-1 border-zinc-600/50 justify-start")}>
|
||||
<div className={"h-3.75 w-3.75 bg-white rounded-full group-active:(w-5) transition-all"}></div>
|
||||
</div>
|
||||
<div className="text-sm">{state["canvas.clearBuffer"]?"开":"关"}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2 select-none mb-3 mt-6">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-5.25 w-5.25" viewBox="0 0 24 24" strokeWidth={1.75} stroke="currentColor" fill="none" strokeLinecap="round" strokeLinejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M4 18h9v-12l-5 2v5l-4 2v-8l9 -4l7 2v13l-7 3z" />
|
||||
</svg>
|
||||
<div className="text-xl">PPT</div>
|
||||
</div>
|
||||
<div className="flex flex-col gap-y-4">
|
||||
<div className="flex flex-col">
|
||||
<div className="text-base font-bold text-zinc-800">尝试兼容WPS Office</div>
|
||||
<div className="text-sm text-zinc-500">尝试调用“Kwpp.Application”的COM接口</div>
|
||||
<div className="text-sm text-red-600 font-bold">不建议使用WPS Office,因为其自身的垃圾兼容性和对触摸的垃圾支持,所以不建议使用WPS,日后也不会考虑专门适配WPS等国产垃圾软件</div>
|
||||
<div className="flex items-center space-x-2 mt-1">
|
||||
<div onClick={() => {
|
||||
dispatch({
|
||||
key: "wps.compact",
|
||||
value: !state["wps.compact"]
|
||||
})
|
||||
}}
|
||||
className={"rounded-full h-5.625 w-10 flex group items-center px-0.8125 transition-all " + (state["wps.compact"] === true ? "bg-blue-600 border-1 border-blue-800/50 justify-end" : "bg-zinc-500/50 border-1 border-zinc-600/50 justify-start")}>
|
||||
<div className={"h-3.75 w-3.75 bg-white rounded-full group-active:(w-5) transition-all"}></div>
|
||||
</div>
|
||||
<div className="text-sm">{state["wps.compact"]?"开":"关"}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<div className="text-base font-bold text-zinc-800">启用对WPS的支持</div>
|
||||
<div className="text-sm text-zinc-500">使用Javascript插件支持WPS(未实现)</div>
|
||||
<div className="flex items-center space-x-2 mt-1">
|
||||
<div onClick={() => {
|
||||
dispatch({
|
||||
key: "wps.javascriptPlugin",
|
||||
value: !state["wps.javascriptPlugin"]
|
||||
})
|
||||
}}
|
||||
className={"rounded-full h-5.625 w-10 flex group items-center px-0.8125 transition-all " + (state["wps.javascriptPlugin"] === true ? "bg-blue-600 border-1 border-blue-800/50 justify-end" : "bg-zinc-500/50 border-1 border-zinc-600/50 justify-start")}>
|
||||
<div className={"h-3.75 w-3.75 bg-white rounded-full group-active:(w-5) transition-all"}></div>
|
||||
</div>
|
||||
<div className="text-sm">{state["wps.javascriptPlugin"]?"开":"关"}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<div className="text-base font-bold text-zinc-800">启用对LibreOffice的支持</div>
|
||||
<div className="text-sm text-zinc-500">使用Python插件支持LibreOffice(未实现)</div>
|
||||
<div className="flex items-center space-x-2 mt-1">
|
||||
<div onClick={() => {
|
||||
dispatch({
|
||||
key: "libreoffice.pythonPlugin",
|
||||
value: !state["libreoffice.pythonPlugin"]
|
||||
})
|
||||
}}
|
||||
className={"rounded-full h-5.625 w-10 flex group items-center px-0.8125 transition-all " + (state["libreoffice.pythonPlugin"] === true ? "bg-blue-600 border-1 border-blue-800/50 justify-end" : "bg-zinc-500/50 border-1 border-zinc-600/50 justify-start")}>
|
||||
<div className={"h-3.75 w-3.75 bg-white rounded-full group-active:(w-5) transition-all"}></div>
|
||||
</div>
|
||||
<div className="text-sm">{state["libreoffice.pythonPlugin"]?"开":"关"}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<div className="text-base font-bold text-zinc-800">强制启用内嵌字幕并识别为365</div>
|
||||
<div className="text-sm text-zinc-500">若您使用的是Office 365,而软件没有检测到时,可以强制启用内嵌字幕功能并识别为Office 365</div>
|
||||
<div className="flex items-center space-x-2 mt-1">
|
||||
<div onClick={() => {
|
||||
dispatch({
|
||||
key: "powerpoint.force365",
|
||||
value: !state["powerpoint.force365"]
|
||||
})
|
||||
}}
|
||||
className={"rounded-full h-5.625 w-10 flex group items-center px-0.8125 transition-all " + (state["powerpoint.force365"] === true ? "bg-blue-600 border-1 border-blue-800/50 justify-end" : "bg-zinc-500/50 border-1 border-zinc-600/50 justify-start")}>
|
||||
<div className={"h-3.75 w-3.75 bg-white rounded-full group-active:(w-5) transition-all"}></div>
|
||||
</div>
|
||||
<div className="text-sm">{state["powerpoint.force365"]?"开":"关"}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2 select-none mb-3 mt-6">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth={1.75}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
className="h-5.25 w-5.25"
|
||||
>
|
||||
<circle cx={12} cy={12} r={10} />
|
||||
<path d="M12 16v-4M12 8h.01" />
|
||||
</svg>
|
||||
<div className="text-xl">关于</div>
|
||||
</div>
|
||||
<div className="text-base font-bold">当前版本:0.1.12.0</div>
|
||||
<div className="flex w-full justify-center pointer-events-none">
|
||||
<img src={logo} className="w-80%"/>
|
||||
</div>
|
||||
<div className="rounded-md ring-2 ring-inset mb-2 ring-blue-600 p-2 flex space-x-1 items-center justify-center">
|
||||
<div className="text-sm font-bold text-blue-600 shrink-0">开源协议:</div>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth={2}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
className="h-4 w-4 text-zinc-800"
|
||||
>
|
||||
<path d="M16 16l3-8 3 8c-.87.65-1.92 1-3 1s-2.13-.35-3-1zM2 16l3-8 3 8c-.87.65-1.92 1-3 1s-2.13-.35-3-1zM7 21h10M12 3v18M3 7h2c2 0 5-1 7-2 2 1 5 2 7 2h2" />
|
||||
</svg>
|
||||
<div className="text-sm text-zinc-800">GNU General Public License v3.0</div>
|
||||
</div>
|
||||
<div className="flex items-center mb-1">
|
||||
<div className="font-bold text-blue-600 text-base shrink-0">仓库源:</div>
|
||||
<div className="text-red-600 text-sm underline grow break-all">https://gitea.bliemhax.com/kriastans/dot-yasat</div>
|
||||
</div>
|
||||
<div className="flex items-center mb-1">
|
||||
<div className="font-bold text-blue-600 text-base shrink-0">官网:</div>
|
||||
<div className="text-red-600 text-sm underline grow break-all">https://dot-yasat.bliemhax.com/</div>
|
||||
</div>
|
||||
<div className="flex items-center mb-1">
|
||||
<div className="font-bold text-blue-600 text-base shrink-0">开发者:</div>
|
||||
<div className="text-red-600 text-sm underline grow break-all">https://gitea.bliemhax.com/kriastans</div>
|
||||
</div>
|
||||
<div className="text-sm text-zinc-500">使用和分发本软件前,请您应当且务必知晓相关开源协议。本软件未经开发者同意,不得将其用于非学习/教育用途,违者后果自负。</div>
|
||||
<div className="text-sm font-bold text-zinc-500 mt-1">对新功能的有效意见和合理建议,开发者会适时回复并进行开发。dot-yasat并非商业性质的软件,请勿催促开发者,耐心才能让功能更少BUG、更加稳定。</div>
|
||||
</div>
|
||||
</ReactLenis>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
</>
|
||||
)
|
||||
})
|
@ -3,8 +3,6 @@ import {defineConfig, presetAttributify, presetUno} from 'unocss'
|
||||
import { presetScrollbar } from 'unocss-preset-scrollbar'
|
||||
import transformerVariantGroup from '@unocss/transformer-variant-group'
|
||||
|
||||
|
||||
|
||||
export default defineConfig({
|
||||
presets: [
|
||||
presetUno(),
|
||||
|
Reference in New Issue
Block a user