From 02478b324252c5253917e85ac51361ebb6e7897f Mon Sep 17 00:00:00 2001 From: NamH Date: Sun, 2 Jun 2024 22:41:27 +0700 Subject: [PATCH] feat: add input actions for setting item (#2978) Signed-off-by: James Co-authored-by: James --- core/src/types/setting/settingComponent.ts | 5 + .../model-extension/resources/settings.json | 4 +- web/.eslintrc.js | 5 + web/helpers/atoms/AppConfig.atom.ts | 2 + web/hooks/{useLogs.tsx => useLogs.ts} | 0 .../Settings/CoreExtensions/ExtensionItem.tsx | 1 - web/screens/Settings/CoreExtensions/index.tsx | 2 - .../SettingDetailTextInputItem/index.tsx | 104 +++++++++++++++--- .../SettingDetailToggleItem/index.tsx | 1 - .../SimpleTextMessage/index.tsx | 1 - 10 files changed, 105 insertions(+), 20 deletions(-) rename web/hooks/{useLogs.tsx => useLogs.ts} (100%) diff --git a/core/src/types/setting/settingComponent.ts b/core/src/types/setting/settingComponent.ts index e2bf667bd..2eae4e16f 100644 --- a/core/src/types/setting/settingComponent.ts +++ b/core/src/types/setting/settingComponent.ts @@ -16,11 +16,16 @@ export type ControllerType = 'slider' | 'checkbox' | 'input' export type InputType = 'password' | 'text' | 'email' | 'number' | 'tel' | 'url' +const InputActions = ['unobscure', 'copy'] as const +export type InputActionsTuple = typeof InputActions +export type InputAction = InputActionsTuple[number] + export type InputComponentProps = { placeholder: string value: string type?: InputType textAlign?: 'left' | 'right' + inputActions?: InputAction[] } export type SliderComponentProps = { diff --git a/extensions/model-extension/resources/settings.json b/extensions/model-extension/resources/settings.json index 5cdeeeba0..d896f1271 100644 --- a/extensions/model-extension/resources/settings.json +++ b/extensions/model-extension/resources/settings.json @@ -6,7 +6,9 @@ "controllerType": "input", "controllerProps": { "value": "", - "placeholder": "hf_**********************************" + "placeholder": "hf_**********************************", + "type": "password", + "inputActions": ["unobscure", "copy"] } } ] diff --git a/web/.eslintrc.js b/web/.eslintrc.js index 79b32be07..0ed19d001 100644 --- a/web/.eslintrc.js +++ b/web/.eslintrc.js @@ -57,6 +57,11 @@ module.exports = { selector: 'typeLike', format: ['PascalCase'], }, + { + selector: 'property', + filter: '^__html$', + format: null, + }, ], '@typescript-eslint/explicit-module-boundary-types': 'off', '@next/next/no-img-element': 'off', diff --git a/web/helpers/atoms/AppConfig.atom.ts b/web/helpers/atoms/AppConfig.atom.ts index 2c678b77d..f4acc7dc2 100644 --- a/web/helpers/atoms/AppConfig.atom.ts +++ b/web/helpers/atoms/AppConfig.atom.ts @@ -21,3 +21,5 @@ export const proxyAtom = atomWithStorage(HTTPS_PROXY_FEATURE, '') export const ignoreSslAtom = atomWithStorage(IGNORE_SSL, false) export const vulkanEnabledAtom = atomWithStorage(VULKAN_ENABLED, false) export const quickAskEnabledAtom = atomWithStorage(QUICK_ASK_ENABLED, false) + +export const hostAtom = atom('http://localhost:1337/') diff --git a/web/hooks/useLogs.tsx b/web/hooks/useLogs.ts similarity index 100% rename from web/hooks/useLogs.tsx rename to web/hooks/useLogs.ts diff --git a/web/screens/Settings/CoreExtensions/ExtensionItem.tsx b/web/screens/Settings/CoreExtensions/ExtensionItem.tsx index b42d51ab0..ec72f5f43 100644 --- a/web/screens/Settings/CoreExtensions/ExtensionItem.tsx +++ b/web/screens/Settings/CoreExtensions/ExtensionItem.tsx @@ -81,7 +81,6 @@ const ExtensionItem: React.FC = ({ item }) => {
Additional Dependencies
diff --git a/web/screens/Settings/CoreExtensions/index.tsx b/web/screens/Settings/CoreExtensions/index.tsx index ae4372a8d..bec267fb4 100644 --- a/web/screens/Settings/CoreExtensions/index.tsx +++ b/web/screens/Settings/CoreExtensions/index.tsx @@ -199,7 +199,6 @@ const ExtensionCatalog = () => {
{
{ - return Renderer.prototype.link + link: (href, title, text) => + Renderer.prototype.link ?.apply(this, [href, title, text]) .replace( ' { - const { value, type, placeholder, textAlign } = + const { value, type, placeholder, textAlign, inputActions } = settingProps.controllerProps as InputComponentProps + const [obscure, setObscure] = useState(type === 'password') const description = marked.parse(settingProps.description ?? '', { async: false, }) + const toggleObscure = useCallback(() => { + setObscure((prev) => !prev) + }, []) + + const copy = useCallback(() => { + navigator.clipboard.writeText(value) + }, [value]) + + const onAction = useCallback( + (action: InputAction) => { + switch (action) { + case 'copy': + copy() + break + case 'unobscure': + toggleObscure() + break + default: + break + } + }, + [toggleObscure, copy] + ) + return (

{settingProps.title}

- { -
- } +
onValueChanged?.(e.target.value)} + suffixIcon={ + + } />
) } +type InputActionProps = { + actions: InputAction[] + onAction: (action: InputAction) => void +} + +const InputExtraActions: React.FC = ({ + actions, + onAction, +}) => { + if (actions.length === 0) return + + return ( +
+ {actions.map((action) => { + switch (action) { + case 'copy': + return ( + onAction(action)} + /> + ) + + case 'unobscure': + return ( + onAction(action)} + /> + ) + + default: + return + } + })} +
+ ) +} + export default SettingDetailTextInputItem diff --git a/web/screens/Settings/SettingDetail/SettingDetailItem/SettingDetailToggleItem/index.tsx b/web/screens/Settings/SettingDetail/SettingDetailItem/SettingDetailToggleItem/index.tsx index f01b79223..0a6f2b890 100644 --- a/web/screens/Settings/SettingDetail/SettingDetailItem/SettingDetailToggleItem/index.tsx +++ b/web/screens/Settings/SettingDetail/SettingDetailItem/SettingDetailToggleItem/index.tsx @@ -38,7 +38,6 @@ const SettingDetailToggleItem: React.FC = ({

{settingProps.title}

{
diff --git a/web/screens/Thread/ThreadCenterPanel/SimpleTextMessage/index.tsx b/web/screens/Thread/ThreadCenterPanel/SimpleTextMessage/index.tsx index d289bf2f6..509610bd5 100644 --- a/web/screens/Thread/ThreadCenterPanel/SimpleTextMessage/index.tsx +++ b/web/screens/Thread/ThreadCenterPanel/SimpleTextMessage/index.tsx @@ -282,7 +282,6 @@ const SimpleTextMessage: React.FC = (props) => { 'message max-width-[100%] flex flex-col gap-y-2 overflow-auto font-medium leading-relaxed', isUser && 'whitespace-pre-wrap break-words' )} - // eslint-disable-next-line @typescript-eslint/naming-convention dangerouslySetInnerHTML={{ __html: parsedText }} /> )}