diff --git a/components.d.ts b/components.d.ts index 01c604f0..b57b28a7 100644 --- a/components.d.ts +++ b/components.d.ts @@ -12,6 +12,7 @@ declare module '@vue/runtime-core' { '404.page': typeof import('./src/pages/404.page.vue')['default'] About: typeof import('./src/pages/About.vue')['default'] App: typeof import('./src/App.vue')['default'] + AsciiTextDrawer: typeof import('./src/tools/ascii-text-drawer/ascii-text-drawer.vue')['default'] 'Base.layout': typeof import('./src/layouts/base.layout.vue')['default'] Base64FileConverter: typeof import('./src/tools/base64-file-converter/base64-file-converter.vue')['default'] Base64StringConverter: typeof import('./src/tools/base64-string-converter/base64-string-converter.vue')['default'] @@ -89,28 +90,17 @@ declare module '@vue/runtime-core' { HttpStatusCodes: typeof import('./src/tools/http-status-codes/http-status-codes.vue')['default'] IbanValidatorAndParser: typeof import('./src/tools/iban-validator-and-parser/iban-validator-and-parser.vue')['default'] 'IconMdi:brushVariant': typeof import('~icons/mdi/brush-variant')['default'] - 'IconMdi:contentCopy': typeof import('~icons/mdi/content-copy')['default'] 'IconMdi:kettleSteamOutline': typeof import('~icons/mdi/kettle-steam-outline')['default'] - IconMdiArrowDown: typeof import('~icons/mdi/arrow-down')['default'] - IconMdiArrowRightBottom: typeof import('~icons/mdi/arrow-right-bottom')['default'] - IconMdiCamera: typeof import('~icons/mdi/camera')['default'] IconMdiChevronDown: typeof import('~icons/mdi/chevron-down')['default'] IconMdiChevronRight: typeof import('~icons/mdi/chevron-right')['default'] IconMdiClose: typeof import('~icons/mdi/close')['default'] IconMdiContentCopy: typeof import('~icons/mdi/content-copy')['default'] - IconMdiDeleteOutline: typeof import('~icons/mdi/delete-outline')['default'] - IconMdiDownload: typeof import('~icons/mdi/download')['default'] IconMdiEye: typeof import('~icons/mdi/eye')['default'] IconMdiEyeOff: typeof import('~icons/mdi/eye-off')['default'] IconMdiHeart: typeof import('~icons/mdi/heart')['default'] - IconMdiPause: typeof import('~icons/mdi/pause')['default'] - IconMdiPlay: typeof import('~icons/mdi/play')['default'] - IconMdiRecord: typeof import('~icons/mdi/record')['default'] - IconMdiRefresh: typeof import('~icons/mdi/refresh')['default'] IconMdiSearch: typeof import('~icons/mdi/search')['default'] IconMdiTranslate: typeof import('~icons/mdi/translate')['default'] IconMdiTriangleDown: typeof import('~icons/mdi/triangle-down')['default'] - IconMdiVideo: typeof import('~icons/mdi/video')['default'] InputCopyable: typeof import('./src/components/InputCopyable.vue')['default'] IntegerBaseConverter: typeof import('./src/tools/integer-base-converter/integer-base-converter.vue')['default'] Ipv4AddressConverter: typeof import('./src/tools/ipv4-address-converter/ipv4-address-converter.vue')['default'] @@ -137,39 +127,25 @@ declare module '@vue/runtime-core' { MenuLayout: typeof import('./src/components/MenuLayout.vue')['default'] MetaTagGenerator: typeof import('./src/tools/meta-tag-generator/meta-tag-generator.vue')['default'] MimeTypes: typeof import('./src/tools/mime-types/mime-types.vue')['default'] - NAlert: typeof import('naive-ui')['NAlert'] NavbarButtons: typeof import('./src/components/NavbarButtons.vue')['default'] - NCheckbox: typeof import('naive-ui')['NCheckbox'] NCode: typeof import('naive-ui')['NCode'] NCollapseTransition: typeof import('naive-ui')['NCollapseTransition'] - NColorPicker: typeof import('naive-ui')['NColorPicker'] NConfigProvider: typeof import('naive-ui')['NConfigProvider'] - NDatePicker: typeof import('naive-ui')['NDatePicker'] NDivider: typeof import('naive-ui')['NDivider'] - NDynamicInput: typeof import('naive-ui')['NDynamicInput'] NEllipsis: typeof import('naive-ui')['NEllipsis'] - NForm: typeof import('naive-ui')['NForm'] NFormItem: typeof import('naive-ui')['NFormItem'] NGi: typeof import('naive-ui')['NGi'] NGrid: typeof import('naive-ui')['NGrid'] NH1: typeof import('naive-ui')['NH1'] - NH2: typeof import('naive-ui')['NH2'] NH3: typeof import('naive-ui')['NH3'] NIcon: typeof import('naive-ui')['NIcon'] - NImage: typeof import('naive-ui')['NImage'] - NInputGroup: typeof import('naive-ui')['NInputGroup'] - NInputGroupLabel: typeof import('naive-ui')['NInputGroupLabel'] NInputNumber: typeof import('naive-ui')['NInputNumber'] + NLabel: typeof import('naive-ui')['NLabel'] NLayout: typeof import('naive-ui')['NLayout'] NLayoutSider: typeof import('naive-ui')['NLayoutSider'] NMenu: typeof import('naive-ui')['NMenu'] - NProgress: typeof import('naive-ui')['NProgress'] NScrollbar: typeof import('naive-ui')['NScrollbar'] - NSlider: typeof import('naive-ui')['NSlider'] - NStatistic: typeof import('naive-ui')['NStatistic'] - NSwitch: typeof import('naive-ui')['NSwitch'] - NTable: typeof import('naive-ui')['NTable'] - NTag: typeof import('naive-ui')['NTag'] + NSpin: typeof import('naive-ui')['NSpin'] NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default'] OtpCodeGeneratorAndValidator: typeof import('./src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue')['default'] PasswordStrengthAnalyser: typeof import('./src/tools/password-strength-analyser/password-strength-analyser.vue')['default'] diff --git a/locales/en.yml b/locales/en.yml index acac1d9e..37cc59ab 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -76,6 +76,20 @@ ui: copyToClipboard: Copy to clipboard color: invalidHexColor: Invalid hex color +components: + formatTransformer: + inputLabel: Input + inputPlaceholder: Input... + outputLabel: Output + inputCopyable: + copied: Copied! + copyToClipboard: Copy to clipboard + spanCopyable: + copyToClipboard: Copy to clipboard + copied: Copied! + textareaCopyable: + copyToClipboard: Copy to clipboard + copied: Copied! tools: categories: favorite-tools: 'Your favorite tools' diff --git a/locales/zh.yml b/locales/zh.yml index 639af23b..426b6541 100644 --- a/locales/zh.yml +++ b/locales/zh.yml @@ -76,6 +76,20 @@ ui: copyToClipboard: 复制到剪贴板 color: invalidHexColor: 无效的十六进制颜色 +components: + formatTransformer: + inputLabel: 输入 + inputPlaceholder: 输入... + outputLabel: 输出 + inputCopyable: + copied: 已复制! + copyToClipboard: 复制到剪贴板 + spanCopyable: + copyToClipboard: 复制到剪贴板 + copied: 已复制! + textareaCopyable: + copyToClipboard: 复制到剪贴板 + copied: 已复制! tools: categories: favorite-tools: '我的收藏' diff --git a/package.json b/package.json index 65f29dbd..fd6c02e6 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "@tiptap/pm": "2.1.6", "@tiptap/starter-kit": "2.1.6", "@tiptap/vue-3": "2.0.3", + "@types/figlet": "^1.5.8", "@vicons/material": "^0.12.0", "@vicons/tabler": "^0.12.0", "@vueuse/core": "^10.3.0", @@ -57,6 +58,7 @@ "date-fns": "^2.29.3", "dompurify": "^3.0.6", "emojilib": "^3.0.10", + "figlet": "^1.7.0", "figue": "^1.2.0", "fuse.js": "^6.6.2", "highlight.js": "^11.7.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a6f7c32f..bd6c38c9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,6 +23,9 @@ dependencies: '@tiptap/vue-3': specifier: 2.0.3 version: 2.0.3(@tiptap/core@2.1.12)(@tiptap/pm@2.1.6)(vue@3.3.4) + '@types/figlet': + specifier: ^1.5.8 + version: 1.5.8 '@vicons/material': specifier: ^0.12.0 version: 0.12.0 @@ -71,6 +74,9 @@ dependencies: emojilib: specifier: ^3.0.10 version: 3.0.10 + figlet: + specifier: ^1.7.0 + version: 1.7.0 figue: specifier: ^1.2.0 version: 1.2.0 @@ -2902,6 +2908,10 @@ packages: /@types/estree@1.0.0: resolution: {integrity: sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==} + /@types/figlet@1.5.8: + resolution: {integrity: sha512-G22AUvy4Tl95XLE7jmUM8s8mKcoz+Hr+Xm9W90gJsppJq9f9tHvOGkrpn4gRX0q/cLtBdNkWtWCKDg2UDZoZvQ==} + dev: false + /@types/fs-extra@11.0.1: resolution: {integrity: sha512-MxObHvNl4A69ofaTRU8DFqvgzzv8s9yRtaPPm5gud9HDNvpB3GPQFvNuTWAI59B9huVGV5jXYJwbCsmBsOGYWA==} dependencies: @@ -5585,6 +5595,12 @@ packages: web-streams-polyfill: 3.2.1 dev: true + /figlet@1.7.0: + resolution: {integrity: sha512-gO8l3wvqo0V7wEFLXPbkX83b7MVjRrk1oRLfYlZXol8nEpb/ON9pcKLI4qpBv5YtOTfrINtqb7b40iYY2FTWFg==} + engines: {node: '>= 0.4.0'} + hasBin: true + dev: false + /figue@1.2.0: resolution: {integrity: sha512-CXKr12kiNWjKtUK3X+YHeXKepn80s9Rg6pgZXoLQYEybgwaGJ9uGW4DrBrVK30ZWZf1mcvTbXF56AcovG7gLVw==} dependencies: diff --git a/src/components/FormatTransformer.vue b/src/components/FormatTransformer.vue index 677fc25a..7a88fc7b 100644 --- a/src/components/FormatTransformer.vue +++ b/src/components/FormatTransformer.vue @@ -2,6 +2,7 @@ import _ from 'lodash'; import type { UseValidationRule } from '@/composable/validation'; import CInputText from '@/ui/c-input-text/c-input-text.vue'; +import { translate as t } from '@/plugins/i18n.plugin'; const props = withDefaults( defineProps<{ @@ -16,10 +17,10 @@ const props = withDefaults( { transformer: _.identity, inputValidationRules: () => [], - inputLabel: 'Input', + inputLabel: t('components.formatTransformer.inputLabel'), inputDefault: '', - inputPlaceholder: 'Input...', - outputLabel: 'Output', + inputPlaceholder: t('components.formatTransformer.inputPlaceholder'), + outputLabel: t('components.formatTransformer.outputLabel'), outputLanguage: '', }, ); diff --git a/src/components/InputCopyable.vue b/src/components/InputCopyable.vue index a69a039a..1c4f3dfe 100644 --- a/src/components/InputCopyable.vue +++ b/src/components/InputCopyable.vue @@ -1,13 +1,14 @@ diff --git a/src/components/SpanCopyable.vue b/src/components/SpanCopyable.vue index 5643cff9..1c0a3f07 100644 --- a/src/components/SpanCopyable.vue +++ b/src/components/SpanCopyable.vue @@ -1,13 +1,14 @@ diff --git a/src/components/TextareaCopyable.vue b/src/components/TextareaCopyable.vue index 8b0aae61..dab5ca9b 100644 --- a/src/components/TextareaCopyable.vue +++ b/src/components/TextareaCopyable.vue @@ -8,6 +8,7 @@ import xmlHljs from 'highlight.js/lib/languages/xml'; import yamlHljs from 'highlight.js/lib/languages/yaml'; import iniHljs from 'highlight.js/lib/languages/ini'; import { useCopy } from '@/composable/copy'; +import { translate as t } from '@/plugins/i18n.plugin'; const props = withDefaults( defineProps<{ @@ -21,7 +22,7 @@ const props = withDefaults( followHeightOf: null, language: 'txt', copyPlacement: 'top-right', - copyMessage: 'Copy to clipboard', + copyMessage: t('components.textareaCopyable.copyToClipboard'), }, ); hljs.registerLanguage('sql', sqlHljs); @@ -35,7 +36,7 @@ const { value, language, followHeightOf, copyPlacement, copyMessage } = toRefs(p const { height } = followHeightOf.value ? useElementSize(followHeightOf) : { height: ref(null) }; const { copy, isJustCopied } = useCopy({ source: value, createToast: false }); -const tooltipText = computed(() => isJustCopied.value ? 'Copied!' : copyMessage.value); +const tooltipText = computed(() => isJustCopied.value ? t('components.textareaCopyable.copied') : copyMessage.value); diff --git a/src/tools/ascii-text-drawer/ascii-text-drawer.vue b/src/tools/ascii-text-drawer/ascii-text-drawer.vue new file mode 100644 index 00000000..0ea8bda8 --- /dev/null +++ b/src/tools/ascii-text-drawer/ascii-text-drawer.vue @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + {{ t('tools.ascii-text-drawer.loadingFont') }} + + + + {{ t('tools.ascii-text-drawer.errored') }} + + + + + + + diff --git a/src/tools/ascii-text-drawer/index.ts b/src/tools/ascii-text-drawer/index.ts new file mode 100644 index 00000000..0c137d7c --- /dev/null +++ b/src/tools/ascii-text-drawer/index.ts @@ -0,0 +1,13 @@ +import { Artboard } from '@vicons/tabler'; +import { defineTool } from '../tool'; +import { translate as t } from '@/plugins/i18n.plugin'; + +export const tool = defineTool({ + name: t('tools.ascii-text-drawer.title'), + path: '/ascii-text-drawer', + description: t('tools.ascii-text-drawer.description'), + keywords: ['ascii', 'asciiart', 'text', 'drawer'], + component: () => import('./ascii-text-drawer.vue'), + icon: Artboard, + createdAt: new Date('2024-03-03'), +}); diff --git a/src/tools/ascii-text-drawer/locales/en.yml b/src/tools/ascii-text-drawer/locales/en.yml new file mode 100644 index 00000000..0c545145 --- /dev/null +++ b/src/tools/ascii-text-drawer/locales/en.yml @@ -0,0 +1,15 @@ +tools: + ascii-text-drawer: + title: ASCII Art Text Generator + description: Create ASCII art text with many fonts and styles. + + inputLabel: 'Your text:' + inputPlaceholder: Your text to draw + fontLabel: 'Font:' + fontPlaceholder: Select font to use + widthLabel: 'Width:' + widthPlaceholder: Width of the text + loadingFont: Loading font... + outputLabel: 'Ascii Art text:' + + errored: Current settings resulted in error. diff --git a/src/tools/ascii-text-drawer/locales/zh.yml b/src/tools/ascii-text-drawer/locales/zh.yml new file mode 100644 index 00000000..84263f24 --- /dev/null +++ b/src/tools/ascii-text-drawer/locales/zh.yml @@ -0,0 +1,15 @@ +tools: + ascii-text-drawer: + title: ASCII 艺术文本生成器 + description: 使用多种字体和样式创建 ASCII 艺术文本。 + + inputLabel: '您的文本:' + inputPlaceholder: 要绘制的文本 + fontLabel: '字体:' + fontPlaceholder: 选择要使用的字体 + widthLabel: '宽度:' + widthPlaceholder: 文本的宽度 + loadingFont: 正在加载字体... + outputLabel: 'ASCII 艺术文本:' + + errored: 当前设置导致错误。 diff --git a/src/tools/index.ts b/src/tools/index.ts index bc08af84..61873f89 100644 --- a/src/tools/index.ts +++ b/src/tools/index.ts @@ -1,7 +1,11 @@ import { tool as base64FileConverter } from './base64-file-converter'; import { tool as base64StringConverter } from './base64-string-converter'; import { tool as basicAuthGenerator } from './basic-auth-generator'; + +import { tool as asciiTextDrawer } from './ascii-text-drawer'; + import { tool as textToUnicode } from './text-to-unicode'; + import { tool as pdfSignatureChecker } from './pdf-signature-checker'; import { tool as numeronymGenerator } from './numeronym-generator'; import { tool as macAddressGenerator } from './mac-address-generator'; @@ -159,7 +163,15 @@ export const toolsByCategory: ToolCategory[] = [ }, { name: 'Text', - components: [loremIpsumGenerator, textStatistics, emojiPicker, stringObfuscator, textDiff, numeronymGenerator], + components: [ + loremIpsumGenerator, + textStatistics, + emojiPicker, + stringObfuscator, + textDiff, + numeronymGenerator, + asciiTextDrawer, + ], }, { name: 'Data',