refactor(web): icons

This commit is contained in:
Acbox
2026-02-10 17:16:02 +08:00
parent 14e895d0ce
commit ae65a61ac0
13 changed files with 133 additions and 129 deletions
+6 -3
View File
@@ -9,8 +9,6 @@
"start": "vite preview" "start": "vite preview"
}, },
"dependencies": { "dependencies": {
"@jamescoyle/vue-icon": "^0.1.2",
"@mdi/js": "^7.4.47",
"@memoh/shared": "workspace:*", "@memoh/shared": "workspace:*",
"@memoh/ui": "workspace:*", "@memoh/ui": "workspace:*",
"@pinia/colada": "^0.21.1", "@pinia/colada": "^0.21.1",
@@ -36,7 +34,12 @@
"vue-i18n": "^11.2.8", "vue-i18n": "^11.2.8",
"vue-router": "^4.6.4", "vue-router": "^4.6.4",
"vue-sonner": "^2.0.9", "vue-sonner": "^2.0.9",
"zod": "^4.3.5" "zod": "^4.3.5",
"@fortawesome/fontawesome-svg-core": "^7.0.0",
"@fortawesome/free-brands-svg-icons": "^7.0.0",
"@fortawesome/free-regular-svg-icons": "^7.0.0",
"@fortawesome/free-solid-svg-icons": "^7.0.0",
"@fortawesome/vue-fontawesome": "^3.1.1"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^24.10.1", "@types/node": "^24.10.1",
+14 -15
View File
@@ -4,12 +4,16 @@
<SidebarHeader> <SidebarHeader>
<SidebarMenu> <SidebarMenu>
<SidebarMenuItem> <SidebarMenuItem>
<img <div class="flex flex-row items-center w-full gap-2 px-3 py-2">
src="../../../public/logo.png" <img
width="80" src="/logo.png"
class="m-auto" class="size-10"
alt="logo.png" alt="logo.png"
> >
<span class="text-xl font-bold text-gray-500 dark:text-gray-400">
Memoh
</span>
</div>
</SidebarMenuItem> </SidebarMenuItem>
</SidebarMenu> </SidebarMenu>
</SidebarHeader> </SidebarHeader>
@@ -36,10 +40,7 @@
}" }"
@click="router.push({ name: sidebarItem.name })" @click="router.push({ name: sidebarItem.name })"
> >
<svg-icon <FontAwesomeIcon :icon="sidebarItem.icon" />
type="mdi"
:path="sidebarItem.icon"
/>
<span>{{ sidebarItem.title }}</span> <span>{{ sidebarItem.title }}</span>
</Toggle> </Toggle>
</SidebarMenuButton> </SidebarMenuButton>
@@ -65,8 +66,6 @@ import {
Toggle Toggle
} from '@memoh/ui' } from '@memoh/ui'
import { computed } from 'vue' import { computed } from 'vue'
import SvgIcon from '@jamescoyle/vue-icon'
import { mdiRobot, mdiChatOutline, mdiCogBox } from '@mdi/js'
import { useRouter,useRoute } from 'vue-router' import { useRouter,useRoute } from 'vue-router'
import { useUserStore } from '@/store/user' import { useUserStore } from '@/store/user'
import i18n from '@/i18n' import i18n from '@/i18n'
@@ -85,7 +84,7 @@ const sidebarInfo = computed(() => [
{ {
title: t('slidebar.chat'), title: t('slidebar.chat'),
name: 'chat', name: 'chat',
icon: mdiChatOutline icon: ['far', 'comments']
}, },
// { // {
// title: t('slidebar.home'), // title: t('slidebar.home'),
@@ -95,11 +94,11 @@ const sidebarInfo = computed(() => [
{ {
title: t('slidebar.model_setting'), title: t('slidebar.model_setting'),
name: 'models', name: 'models',
icon: mdiRobot icon: ['fas', 'robot']
}, { }, {
title: t('slidebar.setting'), title: t('slidebar.setting'),
name: 'settings', name: 'settings',
icon: mdiCogBox icon: ['fas', 'gear']
}, },
// { // {
// title: 'MCP', // title: 'MCP',
@@ -6,9 +6,8 @@
class="w-full shadow-none! text-muted-foreground mb-4" class="w-full shadow-none! text-muted-foreground mb-4"
variant="outline" variant="outline"
> >
<svg-icon <FontAwesomeIcon
type="mdi" :icon="['fas', 'plus']"
:path="mdiPlus"
class="mr-1" class="mr-1"
/> 添加 /> 添加
</Button> </Button>
@@ -127,8 +126,6 @@
</section> </section>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { mdiPlus } from '@mdi/js'
import SvgIcon from '@jamescoyle/vue-icon'
import { import {
Button, Button,
Dialog, Dialog,
@@ -1,10 +1,7 @@
<template> <template>
<div class="flex gap-4 items-start"> <div class="flex gap-4 items-start">
<div class="p-2 rounded-full bg-[#F9F9F9] dark:bg-[#666]"> <div class="p-2 rounded-full bg-[#F9F9F9] dark:bg-[#666]">
<svg-icon <FontAwesomeIcon :icon="['fas', 'robot']" />
type="mdi"
:path="mdiRobotOutline"
/>
</div> </div>
<section class="w-[90%]"> <section class="w-[90%]">
<sup class="font-semibold"> <sup class="font-semibold">
@@ -23,8 +20,6 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import SvgIcon from '@jamescoyle/vue-icon'
import { mdiRobotOutline } from '@mdi/js'
import type { robot } from '@memoh/shared' import type { robot } from '@memoh/shared'
import MarkdownRender, { enableKatex, enableMermaid } from 'markstream-vue' import MarkdownRender, { enableKatex, enableMermaid } from 'markstream-vue'
import LoadingDots from '@/components/loading-dots/index.vue' import LoadingDots from '@/components/loading-dots/index.vue'
@@ -1,63 +1,15 @@
<template> <template>
<svg <FontAwesomeIcon
xmlns="http://www.w3.org/2000/svg" :icon="['fas', 'spinner']"
:width="size" spin
:height="size" :style="{ fontSize: `${size}px` }"
viewBox="0 0 24 24" />
>
<circle
cx="4"
cy="12"
r="3"
fill="currentColor"
>
<animate
id="dot1"
fill="freeze"
attributeName="opacity"
begin="0;dot3.end-0.25s"
dur="0.75s"
values="1;0.2"
/>
</circle>
<circle
cx="12"
cy="12"
r="3"
fill="currentColor"
opacity="0.4"
>
<animate
fill="freeze"
attributeName="opacity"
begin="dot1.begin+0.15s"
dur="0.75s"
values="1;0.2"
/>
</circle>
<circle
cx="20"
cy="12"
r="3"
fill="currentColor"
opacity="0.3"
>
<animate
id="dot3"
fill="freeze"
attributeName="opacity"
begin="dot1.begin+0.3s"
dur="0.75s"
values="1;0.2"
/>
</circle>
</svg>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
withDefaults(defineProps<{ withDefaults(defineProps<{
size?: number size?: number
}>(), { }>(), {
size: 24, size: 16,
}) })
</script> </script>
+31 -1
View File
@@ -9,9 +9,39 @@ import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
import 'markstream-vue/index.css' import 'markstream-vue/index.css'
import 'katex/dist/katex.min.css' import 'katex/dist/katex.min.css'
// Font Awesome
import { library } from '@fortawesome/fontawesome-svg-core'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
import {
faGear,
faPaperPlane,
faRobot,
faMagnifyingGlass,
faPlus,
faSpinner,
} from '@fortawesome/free-solid-svg-icons'
import {
faRectangleList,
faTrashCan,
faComments,
} from '@fortawesome/free-regular-svg-icons'
library.add(
faGear,
faPaperPlane,
faRobot,
faMagnifyingGlass,
faPlus,
faSpinner,
faRectangleList,
faTrashCan,
faComments,
)
createApp(App) createApp(App)
.component('FontAwesomeIcon', FontAwesomeIcon)
.use(createPinia().use(piniaPluginPersistedstate)) .use(createPinia().use(piniaPluginPersistedstate))
.use(PiniaColada) .use(PiniaColada)
.use(router) .use(router)
.use(i18n) .use(i18n)
.mount('#app') .mount('#app')
+1 -6
View File
@@ -32,10 +32,7 @@
> >
<template v-if="!loading"> <template v-if="!loading">
{{ $t('chat.send') }} {{ $t('chat.send') }}
<svg-icon <FontAwesomeIcon :icon="['fas', 'paper-plane']" />
type="mdi"
:path="mdiSendOutline"
/>
</template> </template>
<LoadingDots v-else /> <LoadingDots v-else />
</Button> </Button>
@@ -50,8 +47,6 @@ import {
Textarea, Textarea,
Button, Button,
} from '@memoh/ui' } from '@memoh/ui'
import SvgIcon from '@jamescoyle/vue-icon'
import { mdiSendOutline } from '@mdi/js'
import ChatList from '@/components/chat-list/index.vue' import ChatList from '@/components/chat-list/index.vue'
import LoadingDots from '@/components/loading-dots/index.vue' import LoadingDots from '@/components/loading-dots/index.vue'
import { provide, ref } from 'vue' import { provide, ref } from 'vue'
@@ -42,10 +42,7 @@
class="cursor-pointer" class="cursor-pointer"
@click="$emit('edit', model)" @click="$emit('edit', model)"
> >
<svg-icon <FontAwesomeIcon :icon="['fas', 'gear']" />
type="mdi"
:path="mdiCog"
/>
</Button> </Button>
<ConfirmPopover <ConfirmPopover
@@ -55,10 +52,7 @@
> >
<template #trigger> <template #trigger>
<Button variant="outline"> <Button variant="outline">
<svg-icon <FontAwesomeIcon :icon="['far', 'trash-can']" />
type="mdi"
:path="mdiTrashCanOutline"
/>
</Button> </Button>
</template> </template>
</ConfirmPopover> </ConfirmPopover>
@@ -83,8 +77,6 @@ import {
SelectItem, SelectItem,
} from '@memoh/ui' } from '@memoh/ui'
import ConfirmPopover from '@/components/confirm-popover/index.vue' import ConfirmPopover from '@/components/confirm-popover/index.vue'
import SvgIcon from '@jamescoyle/vue-icon'
import { mdiCog, mdiTrashCanOutline } from '@mdi/js'
import { type ModelInfo } from '@memoh/shared' import { type ModelInfo } from '@memoh/shared'
defineProps<{ defineProps<{
@@ -31,10 +31,7 @@
> >
<EmptyHeader> <EmptyHeader>
<EmptyMedia variant="icon"> <EmptyMedia variant="icon">
<svg-icon <FontAwesomeIcon :icon="['far', 'rectangle-list']" />
type="mdi"
:path="mdiListBoxOutline"
/>
</EmptyMedia> </EmptyMedia>
</EmptyHeader> </EmptyHeader>
<EmptyTitle>还没有添加模型</EmptyTitle> <EmptyTitle>还没有添加模型</EmptyTitle>
@@ -55,8 +52,6 @@ import {
} from '@memoh/ui' } from '@memoh/ui'
import CreateModel from '@/components/create-model/index.vue' import CreateModel from '@/components/create-model/index.vue'
import ModelItem from './model-item.vue' import ModelItem from './model-item.vue'
import SvgIcon from '@jamescoyle/vue-icon'
import { mdiListBoxOutline } from '@mdi/js'
import { type ModelInfo } from '@memoh/shared' import { type ModelInfo } from '@memoh/shared'
defineProps<{ defineProps<{
@@ -70,10 +70,7 @@
> >
<template #trigger> <template #trigger>
<Button variant="outline"> <Button variant="outline">
<svg-icon <FontAwesomeIcon :icon="['far', 'trash-can']" />
type="mdi"
:path="mdiTrashCanOutline"
/>
</Button> </Button>
</template> </template>
</ConfirmPopover> </ConfirmPopover>
@@ -99,8 +96,6 @@ import {
Spinner, Spinner,
} from '@memoh/ui' } from '@memoh/ui'
import ConfirmPopover from '@/components/confirm-popover/index.vue' import ConfirmPopover from '@/components/confirm-popover/index.vue'
import SvgIcon from '@jamescoyle/vue-icon'
import { mdiTrashCanOutline } from '@mdi/js'
import { computed, toValue, watch } from 'vue' import { computed, toValue, watch } from 'vue'
import { toTypedSchema } from '@vee-validate/zod' import { toTypedSchema } from '@vee-validate/zod'
import z from 'zod' import z from 'zod'
+2 -12
View File
@@ -28,9 +28,6 @@ import {
EmptyMedia, EmptyMedia,
EmptyTitle, EmptyTitle,
} from '@memoh/ui' } from '@memoh/ui'
import { mdiMagnify,mdiListBoxOutline } from '@mdi/js'
// import DataTable from '@/components/DataTable/index.vue'
import SvgIcon from '@jamescoyle/vue-icon'
import request from '@/utils/request' import request from '@/utils/request'
import { type ProviderInfo } from '@memoh/shared' import { type ProviderInfo } from '@memoh/shared'
import AddProvider from '@/components/add-provider/index.vue' import AddProvider from '@/components/add-provider/index.vue'
@@ -118,11 +115,7 @@ const openStatus = reactive({
searchProviderTxt.value = searchProviderTxt.temp_value searchProviderTxt.value = searchProviderTxt.temp_value
}" }"
> >
<svg-icon <FontAwesomeIcon :icon="['fas', 'magnifying-glass']" />
type="mdi"
:path="mdiMagnify"
class="translate-icon"
/>
</InputGroupAddon> </InputGroupAddon>
</InputGroup> </InputGroup>
</SidebarHeader> </SidebarHeader>
@@ -184,10 +177,7 @@ const openStatus = reactive({
> >
<EmptyHeader> <EmptyHeader>
<EmptyMedia variant="icon"> <EmptyMedia variant="icon">
<svg-icon <FontAwesomeIcon :icon="['far', 'rectangle-list']" />
type="mdi"
:path="mdiListBoxOutline"
/>
</EmptyMedia> </EmptyMedia>
</EmptyHeader> </EmptyHeader>
<EmptyTitle>No Provider</EmptyTitle> <EmptyTitle>No Provider</EmptyTitle>
+2 -5
View File
@@ -1,9 +1,8 @@
<template> <template>
<div class="max-w-187 m-auto"> <div class="max-w-187 m-auto">
<h6 class="mt-6 mb-2 flex items-center"> <h6 class="mt-6 mb-2 flex items-center">
<svg-icon <FontAwesomeIcon
type="mdi" :icon="['fas', 'gear']"
:path="mdiCog"
class="mr-2" class="mr-2"
/> />
显示设置 显示设置
@@ -103,8 +102,6 @@ import {
PopoverContent, PopoverContent,
PopoverTrigger, PopoverTrigger,
} from '@memoh/ui' } from '@memoh/ui'
import SvgIcon from '@jamescoyle/vue-icon'
import { mdiCog } from '@mdi/js'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { storeToRefs } from 'pinia' import { storeToRefs } from 'pinia'
import { useUserStore } from '../../store/user' import { useUserStore } from '../../store/user'
+64
View File
@@ -236,6 +236,21 @@ importers:
packages/web: packages/web:
dependencies: dependencies:
'@fortawesome/fontawesome-svg-core':
specifier: ^7.0.0
version: 7.1.0
'@fortawesome/free-brands-svg-icons':
specifier: ^7.0.0
version: 7.1.0
'@fortawesome/free-regular-svg-icons':
specifier: ^7.0.0
version: 7.1.0
'@fortawesome/free-solid-svg-icons':
specifier: ^7.0.0
version: 7.1.0
'@fortawesome/vue-fontawesome':
specifier: ^3.1.1
version: 3.1.3(@fortawesome/fontawesome-svg-core@7.1.0)(vue@3.5.26(typescript@5.9.3))
'@jamescoyle/vue-icon': '@jamescoyle/vue-icon':
specifier: ^0.1.2 specifier: ^0.1.2
version: 0.1.2 version: 0.1.2
@@ -1364,6 +1379,32 @@ packages:
'@floating-ui/vue@1.1.9': '@floating-ui/vue@1.1.9':
resolution: {integrity: sha512-BfNqNW6KA83Nexspgb9DZuz578R7HT8MZw1CfK9I6Ah4QReNWEJsXWHN+SdmOVLNGmTPDi+fDT535Df5PzMLbQ==} resolution: {integrity: sha512-BfNqNW6KA83Nexspgb9DZuz578R7HT8MZw1CfK9I6Ah4QReNWEJsXWHN+SdmOVLNGmTPDi+fDT535Df5PzMLbQ==}
'@fortawesome/fontawesome-common-types@7.1.0':
resolution: {integrity: sha512-l/BQM7fYntsCI//du+6sEnHOP6a74UixFyOYUyz2DLMXKx+6DEhfR3F2NYGE45XH1JJuIamacb4IZs9S0ZOWLA==}
engines: {node: '>=6'}
'@fortawesome/fontawesome-svg-core@7.1.0':
resolution: {integrity: sha512-fNxRUk1KhjSbnbuBxlWSnBLKLBNun52ZBTcs22H/xEEzM6Ap81ZFTQ4bZBxVQGQgVY0xugKGoRcCbaKjLQ3XZA==}
engines: {node: '>=6'}
'@fortawesome/free-brands-svg-icons@7.1.0':
resolution: {integrity: sha512-9byUd9bgNfthsZAjBl6GxOu1VPHgBuRUP9juI7ZoM98h8xNPTCTagfwUFyYscdZq4Hr7gD1azMfM9s5tIWKZZA==}
engines: {node: '>=6'}
'@fortawesome/free-regular-svg-icons@7.1.0':
resolution: {integrity: sha512-0e2fdEyB4AR+e6kU4yxwA/MonnYcw/CsMEP9lH82ORFi9svA6/RhDyhxIv5mlJaldmaHLLYVTb+3iEr+PDSZuQ==}
engines: {node: '>=6'}
'@fortawesome/free-solid-svg-icons@7.1.0':
resolution: {integrity: sha512-Udu3K7SzAo9N013qt7qmm22/wo2hADdheXtBfxFTecp+ogsc0caQNRKEb7pkvvagUGOpG9wJC1ViH6WXs8oXIA==}
engines: {node: '>=6'}
'@fortawesome/vue-fontawesome@3.1.3':
resolution: {integrity: sha512-OHHUTLPEzdwP8kcYIzhioUdUOjZ4zzmi+midwa4bqscza4OJCOvTKJEHkXNz8PgZ23kWci1HkKVX0bm8f9t9gQ==}
peerDependencies:
'@fortawesome/fontawesome-svg-core': ~1 || ~6 || ~7
vue: '>= 3.0.0 < 4'
'@hono/node-server@1.19.9': '@hono/node-server@1.19.9':
resolution: {integrity: sha512-vHL6w3ecZsky+8P5MD+eFfaGTyCeOHUIFYMGpQGbrBTSmNNoxv0if69rEZ5giu36weC5saFuznL411gRX7bJDw==} resolution: {integrity: sha512-vHL6w3ecZsky+8P5MD+eFfaGTyCeOHUIFYMGpQGbrBTSmNNoxv0if69rEZ5giu36weC5saFuznL411gRX7bJDw==}
engines: {node: '>=18.14.1'} engines: {node: '>=18.14.1'}
@@ -5702,6 +5743,29 @@ snapshots:
- '@vue/composition-api' - '@vue/composition-api'
- vue - vue
'@fortawesome/fontawesome-common-types@7.1.0': {}
'@fortawesome/fontawesome-svg-core@7.1.0':
dependencies:
'@fortawesome/fontawesome-common-types': 7.1.0
'@fortawesome/free-brands-svg-icons@7.1.0':
dependencies:
'@fortawesome/fontawesome-common-types': 7.1.0
'@fortawesome/free-regular-svg-icons@7.1.0':
dependencies:
'@fortawesome/fontawesome-common-types': 7.1.0
'@fortawesome/free-solid-svg-icons@7.1.0':
dependencies:
'@fortawesome/fontawesome-common-types': 7.1.0
'@fortawesome/vue-fontawesome@3.1.3(@fortawesome/fontawesome-svg-core@7.1.0)(vue@3.5.26(typescript@5.9.3))':
dependencies:
'@fortawesome/fontawesome-svg-core': 7.1.0
vue: 3.5.26(typescript@5.9.3)
'@hono/node-server@1.19.9(hono@4.11.4)': '@hono/node-server@1.19.9(hono@4.11.4)':
dependencies: dependencies:
hono: 4.11.4 hono: 4.11.4