[codex] add customizable profile avatars (#870)
* add customizable profile avatars * keep profile avatar visible when sidebar collapses * simplify collapsed profile avatar styling * force managed gateway startup in docker * limit gateway autostart to active profile * restore all profile gateway autostart * fix managed gateway runtime detection
This commit is contained in:
@@ -9,7 +9,9 @@ import { copyToClipboard } from "@/utils/clipboard";
|
||||
import MarkdownRenderer from "./MarkdownRenderer.vue";
|
||||
import { parseThinking, countThinkingChars } from "@/utils/thinking-parser";
|
||||
import { useChatStore } from "@/stores/hermes/chat";
|
||||
import { useProfilesStore } from "@/stores/hermes/profiles";
|
||||
import { useSettingsStore } from "@/stores/hermes/settings";
|
||||
import ProfileAvatar from "@/components/hermes/profiles/ProfileAvatar.vue";
|
||||
import {
|
||||
copyTextToClipboard,
|
||||
handleCodeBlockCopyClick,
|
||||
@@ -180,9 +182,12 @@ const toolExpanded = ref(false);
|
||||
const previewUrl = ref<string | null>(null);
|
||||
|
||||
const chatStore = useChatStore();
|
||||
const profilesStore = useProfilesStore();
|
||||
const settingsStore = useSettingsStore();
|
||||
const speech = useGlobalSpeech();
|
||||
const voiceSettings = useVoiceSettings();
|
||||
const assistantProfileName = computed(() => chatStore.activeSession?.profile || profilesStore.activeProfileName || "default");
|
||||
const assistantProfileAvatar = computed(() => profilesStore.profiles.find(profile => profile.name === assistantProfileName.value)?.avatar);
|
||||
|
||||
// Copy entire bubble content
|
||||
const copyableContent = computed(() => {
|
||||
@@ -773,11 +778,12 @@ onBeforeUnmount(() => {
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="msg-body">
|
||||
<img
|
||||
<ProfileAvatar
|
||||
v-if="message.role === 'assistant'"
|
||||
src="/logo.png"
|
||||
alt="Hermes"
|
||||
class="msg-avatar"
|
||||
:name="assistantProfileName"
|
||||
:avatar="assistantProfileAvatar"
|
||||
:size="40"
|
||||
/>
|
||||
<div class="msg-content" :class="message.role">
|
||||
<div
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
import { computed, ref, onUnmounted } from 'vue'
|
||||
import { NPopconfirm, NCheckbox } from 'naive-ui'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import multiavatar from '@multiavatar/multiavatar'
|
||||
import type { Session } from '@/stores/hermes/chat'
|
||||
import { useAppStore } from '@/stores/hermes/app'
|
||||
import { useProfilesStore } from '@/stores/hermes/profiles'
|
||||
import ProfileAvatar from '@/components/hermes/profiles/ProfileAvatar.vue'
|
||||
import { formatTimestampMs } from '@/shared/session-display'
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
@@ -29,13 +30,14 @@ const emit = defineEmits<{
|
||||
|
||||
const { t } = useI18n()
|
||||
const appStore = useAppStore()
|
||||
const profilesStore = useProfilesStore()
|
||||
const sessionModelName = computed(() =>
|
||||
props.session.model
|
||||
? appStore.displayModelName(props.session.model, props.session.provider)
|
||||
: '',
|
||||
)
|
||||
const profileName = computed(() => props.session.profile || 'default')
|
||||
const profileAvatar = computed(() => multiavatar(profileName.value))
|
||||
const profileAvatar = computed(() => profilesStore.profiles.find(profile => profile.name === profileName.value)?.avatar)
|
||||
|
||||
let longPressTimer: ReturnType<typeof setTimeout> | null = null
|
||||
const longPressTriggered = ref(false)
|
||||
@@ -114,7 +116,7 @@ onUnmounted(() => {
|
||||
<span class="session-item-time">{{ formatTimestampMs(session.createdAt) }}</span>
|
||||
</span>
|
||||
<span v-if="props.showProfile" class="session-item-profile">
|
||||
<span class="session-item-profile-avatar" v-html="profileAvatar" />
|
||||
<ProfileAvatar class="session-item-profile-avatar" :name="profileName" :avatar="profileAvatar" :size="16" />
|
||||
<span class="session-item-profile-name">{{ profileName }}</span>
|
||||
</span>
|
||||
</div>
|
||||
@@ -139,18 +141,7 @@ onUnmounted(() => {
|
||||
}
|
||||
|
||||
.session-item-profile-avatar {
|
||||
display: inline-flex;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
flex: 0 0 16px;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.session-item-profile-avatar :deep(svg) {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
display: block;
|
||||
background: var(--bg-secondary);
|
||||
}
|
||||
|
||||
.session-item-profile-name {
|
||||
|
||||
Reference in New Issue
Block a user