feat(avatar): add BOXIM chat takeover
This commit is contained in:
@@ -27,6 +27,7 @@
|
||||
v-for="item in permissionItems"
|
||||
:key="item.key"
|
||||
class="permission-row"
|
||||
:class="{ takeover: item.key === 'takeover' }"
|
||||
type="button"
|
||||
role="switch"
|
||||
:aria-checked="permissionState[item.key]"
|
||||
@@ -51,14 +52,18 @@
|
||||
<rect x="4" y="14" width="6" height="6" rx="1" />
|
||||
<rect x="14" y="14" width="6" height="6" rx="1" />
|
||||
</svg>
|
||||
<svg v-else viewBox="0 0 24 24">
|
||||
<svg v-else-if="item.key === 'interact'" viewBox="0 0 24 24">
|
||||
<path d="M7 10v10H4a2 2 0 0 1-2-2v-6a2 2 0 0 1 2-2h3Zm0 10h9.5a2 2 0 0 0 1.9-1.4l2.3-7A2 2 0 0 0 18.8 9H14l.8-3.2A2.3 2.3 0 0 0 12.6 3L7 10v10Z" />
|
||||
</svg>
|
||||
<svg v-else viewBox="0 0 24 24">
|
||||
<path d="M20 13.5a4.5 4.5 0 0 1-4.5 4.5H9l-5 3 1.4-4.5A6.5 6.5 0 0 1 3 11.4V8.5A4.5 4.5 0 0 1 7.5 4H14" />
|
||||
<path d="M18 3v5m-2.5-2.5h5" />
|
||||
</svg>
|
||||
</span>
|
||||
|
||||
<span class="permission-copy">
|
||||
<strong>{{ item.title }}</strong>
|
||||
<small>{{ item.description }}</small>
|
||||
<small>{{ item.key === 'takeover' ? takeoverDescription : item.description }}</small>
|
||||
</span>
|
||||
|
||||
<span class="permission-switch" :class="{ active: permissionState[item.key] }" aria-hidden="true">
|
||||
@@ -96,12 +101,14 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import { computed, onMounted, reactive, ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import {
|
||||
getAvatarPermissionSettings,
|
||||
getTakeoverStatus,
|
||||
updateAvatarPermissionSettings,
|
||||
type AvatarPermission,
|
||||
type TakeoverStatus,
|
||||
} from '@/api'
|
||||
import { useAvatarStore } from '@/store/avatar'
|
||||
import { pickAvatarId } from '@/utils/avatar-page-data.js'
|
||||
@@ -147,6 +154,12 @@ const permissionItems: Array<{
|
||||
description: '点赞、收藏、评论、回复等操作',
|
||||
tone: 'pink',
|
||||
},
|
||||
{
|
||||
key: 'takeover',
|
||||
title: '分身主动接管聊天回复',
|
||||
description: '收到私聊消息 3 秒后回复,主人发言时暂停',
|
||||
tone: 'cyan',
|
||||
},
|
||||
]
|
||||
|
||||
const permissionState = reactive<PermissionState>({
|
||||
@@ -155,14 +168,21 @@ const permissionState = reactive<PermissionState>({
|
||||
publish: false,
|
||||
browse: false,
|
||||
interact: false,
|
||||
takeover: false,
|
||||
})
|
||||
const activeAvatarId = ref('')
|
||||
const loading = ref(true)
|
||||
const saving = ref(false)
|
||||
const errorMessage = ref('')
|
||||
const toastMessage = ref('')
|
||||
const takeoverStatus = ref<TakeoverStatus | null>(null)
|
||||
let toastTimer: number | undefined
|
||||
|
||||
const takeoverDescription = computed(() => {
|
||||
if (!permissionState.takeover) return '收到私聊消息 3 秒后回复,主人发言时暂停'
|
||||
return takeoverStatus.value?.message || '正在连接 BOXIM'
|
||||
})
|
||||
|
||||
const setPermissions = (permissions: AvatarPermission[]) => {
|
||||
const enabled = new Set(permissions)
|
||||
for (const item of permissionItems) permissionState[item.key] = enabled.has(item.key)
|
||||
@@ -196,6 +216,7 @@ const loadSettings = async () => {
|
||||
try {
|
||||
const settings = await getAvatarPermissionSettings(activeAvatarId.value)
|
||||
setPermissions(settings.permissions || [])
|
||||
await loadTakeoverStatus()
|
||||
} catch (error: any) {
|
||||
errorMessage.value = readableError(error, '授权设置加载失败,请稍后重试')
|
||||
} finally {
|
||||
@@ -203,6 +224,15 @@ const loadSettings = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
const loadTakeoverStatus = async () => {
|
||||
if (!activeAvatarId.value) return
|
||||
try {
|
||||
takeoverStatus.value = await getTakeoverStatus(activeAvatarId.value)
|
||||
} catch {
|
||||
takeoverStatus.value = null
|
||||
}
|
||||
}
|
||||
|
||||
const saveSettings = async () => {
|
||||
if (!activeAvatarId.value || loading.value || saving.value) return
|
||||
saving.value = true
|
||||
@@ -210,6 +240,8 @@ const saveSettings = async () => {
|
||||
try {
|
||||
const settings = await updateAvatarPermissionSettings(activeAvatarId.value, selectedPermissions())
|
||||
setPermissions(settings.permissions || [])
|
||||
await loadTakeoverStatus()
|
||||
if (permissionState.takeover) window.setTimeout(loadTakeoverStatus, 1400)
|
||||
showToast('授权设置已保存')
|
||||
} catch (error: any) {
|
||||
errorMessage.value = readableError(error, '授权设置保存失败,请重试')
|
||||
@@ -363,6 +395,10 @@ svg {
|
||||
background: #fcfcfd;
|
||||
}
|
||||
|
||||
.permission-row.takeover {
|
||||
min-height: 76px;
|
||||
}
|
||||
|
||||
.permission-icon {
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
@@ -400,6 +436,11 @@ svg {
|
||||
background: #fff3f7;
|
||||
}
|
||||
|
||||
.permission-icon.cyan {
|
||||
color: #35a6a2;
|
||||
background: #effaf9;
|
||||
}
|
||||
|
||||
.permission-copy {
|
||||
min-width: 0;
|
||||
}
|
||||
@@ -427,6 +468,15 @@ svg {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.permission-row.takeover .permission-copy small {
|
||||
display: -webkit-box;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: normal;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
}
|
||||
|
||||
.permission-switch {
|
||||
position: relative;
|
||||
width: 43px;
|
||||
|
||||
Reference in New Issue
Block a user