From 33363f0d6aadacf1e8270e854a006c973a5f54fe Mon Sep 17 00:00:00 2001 From: Phantom <59059173+EurFelux@users.noreply.github.com> Date: Mon, 1 Sep 2025 13:01:11 +0800 Subject: [PATCH] fix(ProviderSettings): click padding won't trigger onClick (#9740) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(ProviderSettings): 修复添加提供商弹窗菜单项样式问题 调整菜单项样式以移除默认内边距,并统一使用 MenuItem 组件封装 修复点击边缘无法触发回调的问题,通过添加 overlayClassName 控制 * refactor(ProviderSettings): 优化添加供应商弹窗的菜单项交互逻辑 移除不必要的ant.scss样式和overlayClassName属性 使用useRef和ItemType优化菜单项点击处理 --- .../ProviderSettings/AddProviderPopup.tsx | 126 +++++++++--------- 1 file changed, 60 insertions(+), 66 deletions(-) diff --git a/src/renderer/src/pages/settings/ProviderSettings/AddProviderPopup.tsx b/src/renderer/src/pages/settings/ProviderSettings/AddProviderPopup.tsx index 57620bd379..586271e902 100644 --- a/src/renderer/src/pages/settings/ProviderSettings/AddProviderPopup.tsx +++ b/src/renderer/src/pages/settings/ProviderSettings/AddProviderPopup.tsx @@ -7,7 +7,8 @@ import ImageStorage from '@renderer/services/ImageStorage' import { Provider, ProviderType } from '@renderer/types' import { compressImage, generateColorFromChar, getForegroundColor } from '@renderer/utils' import { Divider, Dropdown, Form, Input, Modal, Popover, Select, Upload } from 'antd' -import React, { useEffect, useState } from 'react' +import { ItemType } from 'antd/es/menu/interface' +import React, { useEffect, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' import styled from 'styled-components' @@ -26,6 +27,7 @@ const PopupContainer: React.FC = ({ provider, resolve }) => { const [logoPickerOpen, setLogoPickerOpen] = useState(false) const [dropdownOpen, setDropdownOpen] = useState(false) const { t } = useTranslation() + const uploadRef = useRef(null) useEffect(() => { if (provider?.id) { @@ -107,80 +109,67 @@ const PopupContainer: React.FC = ({ provider, resolve }) => { { key: 'upload', label: ( -
- {}} - accept="image/png, image/jpeg, image/gif" - itemRender={() => null} - maxCount={1} - onChange={async ({ file }) => { - try { - const _file = file.originFileObj as File - let logoData: string | Blob + {}} + accept="image/png, image/jpeg, image/gif" + itemRender={() => null} + maxCount={1} + onChange={async ({ file }) => { + try { + const _file = file.originFileObj as File + let logoData: string | Blob - if (_file.type === 'image/gif') { - logoData = _file - } else { - logoData = await compressImage(_file) - } - - if (provider?.id) { - if (logoData instanceof Blob && !(logoData instanceof File)) { - const fileFromBlob = new File([logoData], 'logo.png', { type: logoData.type }) - await ImageStorage.set(`provider-${provider.id}`, fileFromBlob) - } else { - await ImageStorage.set(`provider-${provider.id}`, logoData) - } - const savedLogo = await ImageStorage.get(`provider-${provider.id}`) - setLogo(savedLogo) - } else { - // 临时保存在内存中,等创建 provider 后会在调用方保存 - const tempUrl = await new Promise((resolve) => { - const reader = new FileReader() - reader.onload = () => resolve(reader.result as string) - reader.readAsDataURL(logoData) - }) - setLogo(tempUrl) - } - - setDropdownOpen(false) - } catch (error: any) { - window.message.error(error.message) + if (_file.type === 'image/gif') { + logoData = _file + } else { + logoData = await compressImage(_file) } - }}> - {t('settings.general.image_upload')} - -
- ) + + if (provider?.id) { + if (logoData instanceof Blob && !(logoData instanceof File)) { + const fileFromBlob = new File([logoData], 'logo.png', { type: logoData.type }) + await ImageStorage.set(`provider-${provider.id}`, fileFromBlob) + } else { + await ImageStorage.set(`provider-${provider.id}`, logoData) + } + const savedLogo = await ImageStorage.get(`provider-${provider.id}`) + setLogo(savedLogo) + } else { + // 临时保存在内存中,等创建 provider 后会在调用方保存 + const tempUrl = await new Promise((resolve) => { + const reader = new FileReader() + reader.onload = () => resolve(reader.result as string) + reader.readAsDataURL(logoData) + }) + setLogo(tempUrl) + } + + setDropdownOpen(false) + } catch (error: any) { + window.message.error(error.message) + } + }}> + {t('settings.general.image_upload')} + + ), + onClick: () => { + uploadRef.current?.click() + } }, { key: 'builtin', - label: ( -
{ - e.stopPropagation() - setDropdownOpen(false) - setLogoPickerOpen(true) - }}> - {t('settings.general.avatar.builtin')} -
- ) + label: {t('settings.general.avatar.builtin')}, + onClick: () => { + setDropdownOpen(false) + setLogoPickerOpen(true) + } }, { key: 'reset', - label: ( -
{ - e.stopPropagation() - handleReset() - }}> - {t('settings.general.avatar.reset')} -
- ) + label: {t('settings.general.avatar.reset')}, + onClick: handleReset } - ] + ] satisfies ItemType[] // for logo const backgroundColor = generateColorFromChar(name) @@ -302,6 +291,11 @@ const ProviderInitialsLogo = styled.div` } ` +const MenuItem = styled.div` + width: 100%; + text-align: center; +` + export default class AddProviderPopup { static topviewId = 0 static hide() {