diff --git a/.dumi/theme/builtins/IconSearch/IconPicSearcher.tsx b/.dumi/theme/builtins/IconSearch/IconPicSearcher.tsx deleted file mode 100644 index 853387cf3c..0000000000 --- a/.dumi/theme/builtins/IconSearch/IconPicSearcher.tsx +++ /dev/null @@ -1,239 +0,0 @@ -import React, { useCallback, useEffect, useState } from 'react'; -import { Upload, Tooltip, Popover, Modal, Progress, message, Spin, Result } from 'antd'; -import CopyToClipboard from 'react-copy-to-clipboard'; -import { useIntl } from 'dumi'; -import * as AntdIcons from '@ant-design/icons'; - -const allIcons: { [key: string]: any } = AntdIcons; - -const { Dragger } = Upload; -interface AntdIconClassifier { - load: Function; - predict: Function; -} -declare global { - interface Window { - antdIconClassifier: AntdIconClassifier; - } -} - -interface PicSearcherState { - loading: boolean; - modalOpen: boolean; - popoverVisible: boolean; - icons: iconObject[]; - fileList: any[]; - error: boolean; - modelLoaded: boolean; -} - -interface iconObject { - type: string; - score: number; -} - -const PicSearcher: React.FC = () => { - const intl = useIntl(); - const [state, setState] = useState({ - loading: false, - modalOpen: false, - popoverVisible: false, - icons: [], - fileList: [], - error: false, - modelLoaded: false, - }); - const predict = (imgEl: HTMLImageElement) => { - try { - let icons: any[] = window.antdIconClassifier.predict(imgEl); - if (gtag && icons.length) { - gtag('event', 'icon', { - event_category: 'search-by-image', - event_label: icons[0].className, - }); - } - icons = icons.map((i) => ({ score: i.score, type: i.className.replace(/\s/g, '-') })); - setState((prev) => ({ ...prev, loading: false, error: false, icons })); - } catch { - setState((prev) => ({ ...prev, loading: false, error: true })); - } - }; - // eslint-disable-next-line class-methods-use-this - const toImage = (url: string): Promise => - new Promise((resolve) => { - const img = new Image(); - img.setAttribute('crossOrigin', 'anonymous'); - img.src = url; - img.onload = () => { - resolve(img); - }; - }); - - const uploadFile = useCallback((file: File) => { - setState((prev) => ({ ...prev, loading: true })); - const reader = new FileReader(); - reader.onload = () => { - toImage(reader.result as string).then(predict); - setState((prev) => ({ - ...prev, - fileList: [{ uid: 1, name: file.name, status: 'done', url: reader.result }], - })); - }; - reader.readAsDataURL(file); - }, []); - - const onPaste = useCallback((event: ClipboardEvent) => { - const items = event.clipboardData && event.clipboardData.items; - let file = null; - if (items && items.length) { - for (let i = 0; i < items.length; i++) { - if (items[i].type.includes('image')) { - file = items[i].getAsFile(); - break; - } - } - } - if (file) { - uploadFile(file); - } - }, []); - const toggleModal = useCallback(() => { - setState((prev) => ({ - ...prev, - modalOpen: !prev.modalOpen, - popoverVisible: false, - fileList: [], - icons: [], - })); - if (!localStorage.getItem('disableIconTip')) { - localStorage.setItem('disableIconTip', 'true'); - } - }, []); - // eslint-disable-next-line class-methods-use-this - const onCopied = useCallback((text: string) => { - message.success( - - {text} copied 🎉 - , - ); - }, []); - useEffect(() => { - const script = document.createElement('script'); - script.onload = async () => { - await window.antdIconClassifier.load(); - setState((prev) => ({ ...prev, modelLoaded: true })); - document.addEventListener('paste', onPaste); - }; - script.src = 'https://cdn.jsdelivr.net/gh/lewis617/antd-icon-classifier@0.0/dist/main.js'; - document.head.appendChild(script); - setState((prev) => ({ ...prev, popoverVisible: !localStorage.getItem('disableIconTip') })); - return () => { - document.removeEventListener('paste', onPaste); - }; - }, []); - - return ( -
- - - - - {state.modelLoaded || ( - -
- - )} - {state.modelLoaded && ( - uploadFile(o.file as File)} - fileList={state.fileList} - showUploadList={{ showPreviewIcon: false, showRemoveIcon: false }} - > -

- -

-

- {intl.formatMessage({ id: 'app.docs.components.icon.pic-searcher.upload-text' })} -

-

- {intl.formatMessage({ id: 'app.docs.components.icon.pic-searcher.upload-hint' })} -

-
- )} - -
- {state.icons.length > 0 && ( -
- {intl.formatMessage({ id: 'app.docs.components.icon.pic-searcher.result-tip' })} -
- )} - - {state.icons.length > 0 && ( - - - - - - - )} - - {state.icons.map((icon) => { - const { type } = icon; - const iconName = `${type - .split('-') - .map((str) => `${str[0].toUpperCase()}${str.slice(1)}`) - .join('')}Outlined`; - return ( - - - - - ); - })} - -
- {intl.formatMessage({ id: 'app.docs.components.icon.pic-searcher.th-icon' })} - - {intl.formatMessage({ id: 'app.docs.components.icon.pic-searcher.th-score' })} -
- `} onCopy={onCopied}> - - {React.createElement(allIcons[iconName])} - - - - -
- {state.error && ( - - )} -
-
- -
- ); -}; - -export default PicSearcher; diff --git a/.dumi/theme/builtins/IconSearch/index.tsx b/.dumi/theme/builtins/IconSearch/index.tsx index 3337b5b158..c58c6e055e 100644 --- a/.dumi/theme/builtins/IconSearch/index.tsx +++ b/.dumi/theme/builtins/IconSearch/index.tsx @@ -5,7 +5,6 @@ import type { RadioChangeEvent } from 'antd/es/radio/interface'; import { useIntl } from 'dumi'; import debounce from 'lodash/debounce'; import Category from './Category'; -import IconPicSearcher from './IconPicSearcher'; import { FilledIcon, OutlinedIcon, TwoToneIcon } from './themeIcons'; import type { CategoriesKeys } from './fields'; import { categories } from './fields'; @@ -109,7 +108,6 @@ const IconSearch: React.FC = () => { onChange={(e) => handleSearchIcon(e.currentTarget.value)} size="large" autoFocus - suffix={} />
{renderCategories} diff --git a/.dumi/theme/locales/en-US.json b/.dumi/theme/locales/en-US.json index d8a620b43c..bd1fa14132 100644 --- a/.dumi/theme/locales/en-US.json +++ b/.dumi/theme/locales/en-US.json @@ -123,16 +123,6 @@ "app.docs.components.icon.category.data": "Data Icons", "app.docs.components.icon.category.other": "Application Icons", "app.docs.components.icon.category.logo": "Brand and Logos", - "app.docs.components.icon.pic-searcher.intro": "AI Search by image is online, you are welcome to use it! 🎉", - "app.docs.components.icon.pic-searcher.title": "Search by image", - "app.docs.components.icon.pic-searcher.upload-text": "Click, drag, or paste file to this area to upload", - "app.docs.components.icon.pic-searcher.upload-hint": "We will find the best matching icon based on the image provided", - "app.docs.components.icon.pic-searcher.server-error": "Predict service is temporarily unavailable", - "app.docs.components.icon.pic-searcher.matching": "Matching...", - "app.docs.components.icon.pic-searcher.modelloading": "Model is loading...", - "app.docs.components.icon.pic-searcher.result-tip": "Matched the following icons for you:", - "app.docs.components.icon.pic-searcher.th-icon": "Icon", - "app.docs.components.icon.pic-searcher.th-score": "Probability", "app.docs.resource.design": "Design", "app.docs.resource.develop": "Develop", "app.components.overview.search": "Search in components", diff --git a/.dumi/theme/locales/zh-CN.json b/.dumi/theme/locales/zh-CN.json index b25d1426af..efd572abca 100644 --- a/.dumi/theme/locales/zh-CN.json +++ b/.dumi/theme/locales/zh-CN.json @@ -122,16 +122,6 @@ "app.docs.components.icon.category.data": "数据类图标", "app.docs.components.icon.category.other": "网站通用图标", "app.docs.components.icon.category.logo": "品牌和标识", - "app.docs.components.icon.pic-searcher.intro": "AI 截图搜索上线了,快来体验吧!🎉", - "app.docs.components.icon.pic-searcher.title": "上传图片搜索图标", - "app.docs.components.icon.pic-searcher.upload-text": "点击/拖拽/粘贴上传图片", - "app.docs.components.icon.pic-searcher.upload-hint": "我们会通过上传的图片进行匹配,得到最相似的图标", - "app.docs.components.icon.pic-searcher.server-error": "识别服务暂不可用", - "app.docs.components.icon.pic-searcher.matching": "匹配中...", - "app.docs.components.icon.pic-searcher.modelloading": "神经网络模型加载中...", - "app.docs.components.icon.pic-searcher.result-tip": "为您匹配到以下图标:", - "app.docs.components.icon.pic-searcher.th-icon": "图标", - "app.docs.components.icon.pic-searcher.th-score": "匹配度", "app.docs.resource.design": "设计", "app.docs.resource.develop": "开发", "app.components.overview.search": "搜索组件",