mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-04-18 06:13:52 +02:00
Fix animated emoji in notifications tab
This commit is contained in:
48
src/components/Emoji.vue
Normal file
48
src/components/Emoji.vue
Normal file
@@ -0,0 +1,48 @@
|
||||
<template>
|
||||
<div style="overflow: hidden" :style="{ width: size + 'px', height: size + 'px' }">
|
||||
<div
|
||||
v-if="image.frames"
|
||||
class="avatar"
|
||||
:style="generateEmojiStyle(imageUrl, image.framesOverTime, image.frames, image.loopStyle, size)"></div>
|
||||
<img v-else :src="imageUrl" class="avatar" :style="{ width: size + 'px', height: size + 'px' }" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted, ref, watch } from 'vue';
|
||||
|
||||
import { extractFileId, generateEmojiStyle } from '../shared/utils';
|
||||
import { useGalleryStore } from '../stores';
|
||||
|
||||
const { getCachedEmoji } = useGalleryStore();
|
||||
const { emojiTable } = useGalleryStore();
|
||||
|
||||
const props = defineProps({
|
||||
imageUrl: { type: String, default: '' },
|
||||
size: { type: Number, default: 100 }
|
||||
});
|
||||
|
||||
const image = ref({
|
||||
frames: null,
|
||||
framesOverTime: null,
|
||||
loopStyle: null,
|
||||
versions: []
|
||||
});
|
||||
|
||||
async function update() {
|
||||
const fileId = extractFileId(props.imageUrl);
|
||||
for (const emoji of emojiTable) {
|
||||
if (emoji.id === fileId) {
|
||||
image.value = emoji;
|
||||
return;
|
||||
}
|
||||
}
|
||||
image.value = await getCachedEmoji(fileId);
|
||||
}
|
||||
|
||||
watch(() => props.imageUrl, update);
|
||||
|
||||
onMounted(() => {
|
||||
update();
|
||||
});
|
||||
</script>
|
||||
@@ -150,24 +150,8 @@
|
||||
image.versions[image.versions.length - 1].file.url
|
||||
"
|
||||
class="x-popover-image"
|
||||
style="overflow: hidden; width: 100px; height: 100px; padding: 8px">
|
||||
<div
|
||||
v-if="image.frames"
|
||||
class="avatar"
|
||||
:style="
|
||||
generateEmojiStyle(
|
||||
image.versions[image.versions.length - 1].file.url,
|
||||
image.framesOverTime,
|
||||
image.frames,
|
||||
image.loopStyle,
|
||||
100
|
||||
)
|
||||
"></div>
|
||||
<img
|
||||
v-else
|
||||
:src="image.versions[image.versions.length - 1].file.url"
|
||||
class="avatar"
|
||||
style="width: 100px; height: 100px" />
|
||||
style="padding: 8px">
|
||||
<Emoji :imageUrl="image.versions[image.versions.length - 1].file.url" :size="100"></Emoji>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
@@ -194,7 +178,7 @@
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import { generateEmojiStyle, userImage, userStatusClass } from '../../shared/utils';
|
||||
import { userImage, userStatusClass } from '../../shared/utils';
|
||||
import { miscRequest } from '../../api';
|
||||
import { notificationRequest } from '../../api';
|
||||
import { photonEmojis } from '../../shared/constants/photon.js';
|
||||
@@ -204,6 +188,8 @@
|
||||
import { useNotificationStore } from '../../stores';
|
||||
import { useUserStore } from '../../stores/user.js';
|
||||
|
||||
import Emoji from '../Emoji.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const { sendBoopDialog } = storeToRefs(useUserStore());
|
||||
|
||||
@@ -20,6 +20,8 @@ import { handleImageUploadInput } from '../shared/utils/imageUpload';
|
||||
import { useAdvancedSettingsStore } from './settings/advanced';
|
||||
import { watchState } from '../service/watchState';
|
||||
|
||||
import miscReq from '../api/misc';
|
||||
|
||||
import * as workerTimers from 'worker-timers';
|
||||
|
||||
export const useGalleryStore = defineStore('Gallery', () => {
|
||||
@@ -35,6 +37,8 @@ export const useGalleryStore = defineStore('Gallery', () => {
|
||||
instanceInventoryQueueWorker: null
|
||||
});
|
||||
|
||||
const cachedEmoji = new Map();
|
||||
|
||||
const galleryTable = ref([]);
|
||||
|
||||
const galleryDialogVisible = ref(false);
|
||||
@@ -78,6 +82,7 @@ export const useGalleryStore = defineStore('Gallery', () => {
|
||||
watch(
|
||||
() => watchState.isLoggedIn,
|
||||
(isLoggedIn) => {
|
||||
cachedEmoji.clear();
|
||||
galleryTable.value = [];
|
||||
VRCPlusIconsTable.value = [];
|
||||
stickerTable.value = [];
|
||||
@@ -500,6 +505,23 @@ export const useGalleryStore = defineStore('Gallery', () => {
|
||||
}
|
||||
}
|
||||
|
||||
async function getCachedEmoji(fileId) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let ref = cachedEmoji.get(fileId);
|
||||
if (typeof ref !== 'undefined') {
|
||||
resolve(ref);
|
||||
return;
|
||||
}
|
||||
miscReq
|
||||
.getFile({ fileId })
|
||||
.then((args) => {
|
||||
cachedEmoji.set(fileId, args.json);
|
||||
resolve(args.json);
|
||||
})
|
||||
.catch(reject);
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
state,
|
||||
|
||||
@@ -521,6 +543,7 @@ export const useGalleryStore = defineStore('Gallery', () => {
|
||||
emojiTable,
|
||||
inventoryTable,
|
||||
fullscreenImageDialog,
|
||||
cachedEmoji,
|
||||
|
||||
showGalleryDialog,
|
||||
refreshGalleryTable,
|
||||
@@ -538,6 +561,7 @@ export const useGalleryStore = defineStore('Gallery', () => {
|
||||
handleStickerAdd,
|
||||
handleGalleryImageAdd,
|
||||
handleFilesList,
|
||||
queueCheckInstanceInventory
|
||||
queueCheckInstanceInventory,
|
||||
getCachedEmoji
|
||||
};
|
||||
});
|
||||
|
||||
@@ -126,13 +126,12 @@
|
||||
<el-table-column :label="t('table.notification.photo')" width="100" prop="photo">
|
||||
<template #default="scope">
|
||||
<template v-if="scope.row.type === 'boop'">
|
||||
<img
|
||||
v-if="scope.row.details?.imageUrl && !scope.row.details.imageUrl.startsWith('default_')"
|
||||
<Emoji
|
||||
class="x-link"
|
||||
:src="getSmallThumbnailUrl(scope.row.details.imageUrl)"
|
||||
style="flex: none; height: 50px; border-radius: 4px"
|
||||
@click="showFullscreenImageDialog(scope.row.details.imageUrl)"
|
||||
loading="lazy" />
|
||||
v-if="scope.row.details?.imageUrl && !scope.row.details.imageUrl.startsWith('default_')"
|
||||
:imageUrl="scope.row.details.imageUrl"
|
||||
:size="50"></Emoji>
|
||||
</template>
|
||||
<template v-else-if="scope.row.details && scope.row.details.imageUrl">
|
||||
<img
|
||||
@@ -432,6 +431,7 @@
|
||||
import { friendRequest, notificationRequest, worldRequest } from '../../api';
|
||||
import { database } from '../../service/database';
|
||||
|
||||
import Emoji from '../../components/Emoji.vue';
|
||||
import SendInviteRequestResponseDialog from './dialogs/SendInviteRequestResponseDialog.vue';
|
||||
import SendInviteResponseDialog from './dialogs/SendInviteResponseDialog.vue';
|
||||
import configRepository from '../../service/config';
|
||||
|
||||
@@ -260,25 +260,7 @@
|
||||
getEmojiFileName(image)
|
||||
)
|
||||
">
|
||||
<template v-if="image.frames">
|
||||
<div
|
||||
class="avatar"
|
||||
:style="
|
||||
generateEmojiStyle(
|
||||
image.versions[image.versions.length - 1].file.url,
|
||||
image.framesOverTime,
|
||||
image.frames,
|
||||
image.loopStyle,
|
||||
200
|
||||
)
|
||||
"></div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<img
|
||||
class="avatar"
|
||||
:src="image.versions[image.versions.length - 1].file.url"
|
||||
loading="lazy" />
|
||||
</template>
|
||||
<Emoji :imageUrl="image.versions[image.versions.length - 1].file.url" :size="200"></Emoji>
|
||||
</div>
|
||||
<div style="display: inline-block; margin: 5px">
|
||||
<span v-if="image.loopStyle === 'pingpong'">
|
||||
@@ -553,19 +535,15 @@
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import {
|
||||
extractFileId,
|
||||
formatDateFilter,
|
||||
generateEmojiStyle,
|
||||
getEmojiFileName,
|
||||
getPrintFileName
|
||||
} from '../../../shared/utils';
|
||||
import { inventoryRequest, miscRequest, userRequest, vrcPlusIconRequest, vrcPlusImageRequest } from '../../../api';
|
||||
import { extractFileId, formatDateFilter, getEmojiFileName, getPrintFileName } from '../../../shared/utils';
|
||||
import { useAdvancedSettingsStore, useAuthStore, useGalleryStore, useUserStore } from '../../../stores';
|
||||
import { emojiAnimationStyleList, emojiAnimationStyleUrl } from '../../../shared/constants';
|
||||
import { AppDebug } from '../../../service/appConfig';
|
||||
import { handleImageUploadInput } from '../../../shared/utils/imageUpload';
|
||||
|
||||
import Emoji from '../../../components/Emoji.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const {
|
||||
|
||||
Reference in New Issue
Block a user