mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-04-19 14:53:50 +02:00
Boops
This commit is contained in:
@@ -63,6 +63,8 @@
|
|||||||
<VRChatConfigDialog></VRChatConfigDialog>
|
<VRChatConfigDialog></VRChatConfigDialog>
|
||||||
|
|
||||||
<PrimaryPasswordDialog></PrimaryPasswordDialog>
|
<PrimaryPasswordDialog></PrimaryPasswordDialog>
|
||||||
|
|
||||||
|
<SendBoopDialog></SendBoopDialog>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</el-config-provider>
|
</el-config-provider>
|
||||||
@@ -109,6 +111,7 @@
|
|||||||
import NavMenu from './components/NavMenu.vue';
|
import NavMenu from './components/NavMenu.vue';
|
||||||
import PreviousInstancesInfoDialog from './components/dialogs/PreviousInstancesDialog/PreviousInstancesInfoDialog.vue';
|
import PreviousInstancesInfoDialog from './components/dialogs/PreviousInstancesDialog/PreviousInstancesInfoDialog.vue';
|
||||||
import PrimaryPasswordDialog from './views/Settings/dialogs/PrimaryPasswordDialog.vue';
|
import PrimaryPasswordDialog from './views/Settings/dialogs/PrimaryPasswordDialog.vue';
|
||||||
|
import SendBoopDialog from './components/dialogs/SendBoopDialog.vue';
|
||||||
import Sidebar from './views/Sidebar/Sidebar.vue';
|
import Sidebar from './views/Sidebar/Sidebar.vue';
|
||||||
import UserDialog from './components/dialogs/UserDialog/UserDialog.vue';
|
import UserDialog from './components/dialogs/UserDialog/UserDialog.vue';
|
||||||
import VRCXUpdateDialog from './components/dialogs/VRCXUpdateDialog.vue';
|
import VRCXUpdateDialog from './components/dialogs/VRCXUpdateDialog.vue';
|
||||||
|
|||||||
@@ -194,28 +194,29 @@ const miscReq = {
|
|||||||
};
|
};
|
||||||
return args;
|
return args;
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
|
|
||||||
// /**
|
/**
|
||||||
// * @params {{
|
* @params {{
|
||||||
// userId: string,
|
userId: string,
|
||||||
// emojiId: string
|
emojiId: string
|
||||||
// }} params
|
}} params
|
||||||
// * @returns {Promise<{json: any, params}>}
|
* @returns {Promise<{json: any, params}>}
|
||||||
// */
|
*/
|
||||||
// sendBoop(params) {
|
sendBoop(params) {
|
||||||
// return request(`users/${params.userId}/boop`, {
|
return request(`users/${params.userId}/boop`, {
|
||||||
// method: 'POST',
|
method: 'POST',
|
||||||
// params
|
params: {
|
||||||
// }).then((json) => {
|
emojiId: params.emojiId
|
||||||
// const args = {
|
}
|
||||||
// json,
|
}).then((json) => {
|
||||||
// params
|
const args = {
|
||||||
// };
|
json,
|
||||||
// this.$emit('BOOP:SEND', args);
|
params
|
||||||
// return args;
|
};
|
||||||
// });
|
return args;
|
||||||
// }
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default miscReq;
|
export default miscReq;
|
||||||
|
|||||||
@@ -611,6 +611,7 @@
|
|||||||
} from '../../../shared/utils';
|
} from '../../../shared/utils';
|
||||||
import { useAvatarStore, useFavoriteStore, useGalleryStore, useGameStore, useUserStore } from '../../../stores';
|
import { useAvatarStore, useFavoriteStore, useGalleryStore, useGameStore, useUserStore } from '../../../stores';
|
||||||
import { avatarModerationRequest, avatarRequest, favoriteRequest, miscRequest } from '../../../api';
|
import { avatarModerationRequest, avatarRequest, favoriteRequest, miscRequest } from '../../../api';
|
||||||
|
import { AppDebug } from '../../../service/appConfig.js';
|
||||||
import { database } from '../../../service/database';
|
import { database } from '../../../service/database';
|
||||||
import { getNextDialogIndex } from '../../../shared/utils/base/ui';
|
import { getNextDialogIndex } from '../../../shared/utils/base/ui';
|
||||||
import { handleImageUploadInput } from '../../../shared/utils/imageUpload';
|
import { handleImageUploadInput } from '../../../shared/utils/imageUpload';
|
||||||
@@ -727,7 +728,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getImageUrlFromImageId(imageId) {
|
function getImageUrlFromImageId(imageId) {
|
||||||
return `https://api.vrchat.cloud/api/1/file/${imageId}/1/`;
|
return `${AppDebug.endpointDomain}/file/${imageId}/1/`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleDialogOpen() {
|
function handleDialogOpen() {
|
||||||
|
|||||||
@@ -1,277 +1,250 @@
|
|||||||
<!--<template>-->
|
<template>
|
||||||
<!-- <el-dialog-->
|
<el-dialog
|
||||||
<!-- class="x-dialog"-->
|
class="x-dialog"
|
||||||
<!-- :model-value="sendBoopDialog.visible"-->
|
v-model="sendBoopDialog.visible"
|
||||||
<!-- :title="t('dialog.boop_dialog.header')"-->
|
:title="t('dialog.boop_dialog.header')"
|
||||||
<!-- width="450px"-->
|
width="450px"
|
||||||
<!-- @close="closeDialog">-->
|
@close="closeDialog">
|
||||||
<!-- <el-select-->
|
<el-select
|
||||||
<!-- v-model="sendBoopDialog.userId"-->
|
v-if="sendBoopDialog.visible"
|
||||||
<!-- :placeholder="t('dialog.new_instance.instance_creator_placeholder')"-->
|
v-model="sendBoopDialog.userId"
|
||||||
<!-- filterable-->
|
:placeholder="t('dialog.new_instance.instance_creator_placeholder')"
|
||||||
<!-- style="width: 100%">-->
|
filterable
|
||||||
<!-- <el-option-group v-if="vipFriends.length" :label="t('side_panel.favorite')">-->
|
style="width: 100%">
|
||||||
<!-- <el-option-->
|
<el-option-group v-if="vipFriends.length" :label="t('side_panel.favorite')">
|
||||||
<!-- v-for="friend in vipFriends"-->
|
<el-option
|
||||||
<!-- :key="friend.id"-->
|
v-for="friend in vipFriends"
|
||||||
<!-- class="x-friend-item"-->
|
:key="friend.id"
|
||||||
<!-- :label="friend.name"-->
|
:label="friend.name"
|
||||||
<!-- :value="friend.id"-->
|
:value="friend.id"
|
||||||
<!-- style="height: auto">-->
|
style="height: auto"
|
||||||
<!-- <template v-if="friend.ref">-->
|
class="x-friend-item">
|
||||||
<!-- <div class="avatar" :class="userStatusClass(friend.ref)">-->
|
<template v-if="friend.ref">
|
||||||
<!-- <img :src="userImage(friend.ref)" loading="lazy">-->
|
<div class="avatar" :class="userStatusClass(friend.ref)">
|
||||||
<!-- </div>-->
|
<img :src="userImage(friend.ref)" loading="lazy" />
|
||||||
<!-- <div class="detail">-->
|
</div>
|
||||||
<!-- <span-->
|
<div class="detail">
|
||||||
<!-- class="name"-->
|
<span
|
||||||
<!-- :style="{ color: friend.ref.$userColour }"-->
|
class="name"
|
||||||
<!-- v-text="friend.ref.displayName"></span>-->
|
:style="{ color: friend.ref.$userColour }"
|
||||||
<!-- </div>-->
|
v-text="friend.ref.displayName"></span>
|
||||||
<!-- </template>-->
|
</div>
|
||||||
<!-- <span v-else v-text="friend.id"></span>-->
|
</template>
|
||||||
<!-- </el-option>-->
|
<span v-else v-text="friend.id"></span>
|
||||||
<!-- </el-option-group>-->
|
</el-option>
|
||||||
<!-- <el-option-group v-if="onlineFriends.length" :label="t('side_panel.online')">-->
|
</el-option-group>
|
||||||
<!-- <el-option-->
|
<el-option-group v-if="onlineFriends.length" :label="t('side_panel.online')">
|
||||||
<!-- v-for="friend in onlineFriends"-->
|
<el-option
|
||||||
<!-- :key="friend.id"-->
|
v-for="friend in onlineFriends"
|
||||||
<!-- class="x-friend-item"-->
|
:key="friend.id"
|
||||||
<!-- :label="friend.name"-->
|
:label="friend.name"
|
||||||
<!-- :value="friend.id"-->
|
:value="friend.id"
|
||||||
<!-- style="height: auto">-->
|
style="height: auto"
|
||||||
<!-- <template v-if="friend.ref">-->
|
class="x-friend-item">
|
||||||
<!-- <div class="avatar" :class="userStatusClass(friend.ref)">-->
|
<template v-if="friend.ref">
|
||||||
<!-- <img :src="userImage(friend.ref)" loading="lazy">-->
|
<div class="avatar" :class="userStatusClass(friend.ref)">
|
||||||
<!-- </div>-->
|
<img :src="userImage(friend.ref)" loading="lazy" />
|
||||||
<!-- <div class="detail">-->
|
</div>
|
||||||
<!-- <span-->
|
<div class="detail">
|
||||||
<!-- class="name"-->
|
<span
|
||||||
<!-- :style="{ color: friend.ref.$userColour }"-->
|
class="name"
|
||||||
<!-- v-text="friend.ref.displayName"></span>-->
|
:style="{ color: friend.ref.$userColour }"
|
||||||
<!-- </div>-->
|
v-text="friend.ref.displayName"></span>
|
||||||
<!-- </template>-->
|
</div>
|
||||||
<!-- <span v-else v-text="friend.id"></span>-->
|
</template>
|
||||||
<!-- </el-option>-->
|
<span v-else v-text="friend.id"></span>
|
||||||
<!-- </el-option-group>-->
|
</el-option>
|
||||||
<!-- <el-option-group v-if="activeFriends.length" :label="t('side_panel.active')">-->
|
</el-option-group>
|
||||||
<!-- <el-option-->
|
<el-option-group v-if="activeFriends.length" :label="t('side_panel.active')">
|
||||||
<!-- v-for="friend in activeFriends"-->
|
<el-option
|
||||||
<!-- :key="friend.id"-->
|
v-for="friend in activeFriends"
|
||||||
<!-- class="x-friend-item"-->
|
:key="friend.id"
|
||||||
<!-- :label="friend.name"-->
|
:label="friend.name"
|
||||||
<!-- :value="friend.id"-->
|
:value="friend.id"
|
||||||
<!-- style="height: auto">-->
|
style="height: auto"
|
||||||
<!-- <template v-if="friend.ref">-->
|
class="x-friend-item">
|
||||||
<!-- <div class="avatar">-->
|
<template v-if="friend.ref">
|
||||||
<!-- <img :src="userImage(friend.ref)" loading="lazy">-->
|
<div class="avatar">
|
||||||
<!-- </div>-->
|
<img :src="userImage(friend.ref)" loading="lazy" />
|
||||||
<!-- <div class="detail">-->
|
</div>
|
||||||
<!-- <span-->
|
<div class="detail">
|
||||||
<!-- class="name"-->
|
<span
|
||||||
<!-- :style="{ color: friend.ref.$userColour }"-->
|
class="name"
|
||||||
<!-- v-text="friend.ref.displayName"></span>-->
|
:style="{ color: friend.ref.$userColour }"
|
||||||
<!-- </div>-->
|
v-text="friend.ref.displayName"></span>
|
||||||
<!-- </template>-->
|
</div>
|
||||||
<!-- <span v-else v-text="friend.id"></span>-->
|
</template>
|
||||||
<!-- </el-option>-->
|
<span v-else v-text="friend.id"></span>
|
||||||
<!-- </el-option-group>-->
|
</el-option>
|
||||||
<!-- <el-option-group v-if="offlineFriends.length" :label="t('side_panel.offline')">-->
|
</el-option-group>
|
||||||
<!-- <el-option-->
|
<el-option-group v-if="offlineFriends.length" :label="t('side_panel.offline')">
|
||||||
<!-- v-for="friend in offlineFriends"-->
|
<el-option
|
||||||
<!-- :key="friend.id"-->
|
v-for="friend in offlineFriends"
|
||||||
<!-- class="x-friend-item"-->
|
:key="friend.id"
|
||||||
<!-- :label="friend.name"-->
|
:label="friend.name"
|
||||||
<!-- :value="friend.id"-->
|
:value="friend.id"
|
||||||
<!-- style="height: auto">-->
|
style="height: auto"
|
||||||
<!-- <template v-if="friend.ref">-->
|
class="x-friend-item">
|
||||||
<!-- <div class="avatar">-->
|
<template v-if="friend.ref">
|
||||||
<!-- <img :src="userImage(friend.ref)" loading="lazy">-->
|
<div class="avatar">
|
||||||
<!-- </div>-->
|
<img :src="userImage(friend.ref)" loading="lazy" />
|
||||||
<!-- <div class="detail">-->
|
</div>
|
||||||
<!-- <span-->
|
<div class="detail">
|
||||||
<!-- class="name"-->
|
<span
|
||||||
<!-- :style="{ color: friend.ref.$userColour }"-->
|
class="name"
|
||||||
<!-- v-text="friend.ref.displayName"></span>-->
|
:style="{ color: friend.ref.$userColour }"
|
||||||
<!-- </div>-->
|
v-text="friend.ref.displayName"></span>
|
||||||
<!-- </template>-->
|
</div>
|
||||||
<!-- <span v-else v-text="friend.id"></span>-->
|
</template>
|
||||||
<!-- </el-option>-->
|
<span v-else v-text="friend.id"></span>
|
||||||
<!-- </el-option-group>-->
|
</el-option>
|
||||||
<!-- </el-select>-->
|
</el-option-group>
|
||||||
|
</el-select>
|
||||||
|
|
||||||
<!-- <br />-->
|
<br />
|
||||||
<!-- <br />-->
|
<br />
|
||||||
|
|
||||||
<!-- <el-select-->
|
<el-select
|
||||||
<!-- v-model="fileId"-->
|
v-if="sendBoopDialog.visible"
|
||||||
<!-- clearable-->
|
v-model="fileId"
|
||||||
<!-- :placeholder="t('dialog.boop_dialog.select_emoji')"-->
|
clearable
|
||||||
<!-- size="small"-->
|
:placeholder="t('dialog.boop_dialog.select_emoji')"
|
||||||
<!-- style="width: 100%"-->
|
size="small"
|
||||||
<!-- popper-class="max-height-el-select">-->
|
style="width: 100%"
|
||||||
<!-- <el-option-group :label="t('dialog.boop_dialog.my_emojis')">-->
|
popper-class="max-height-el-select">
|
||||||
<!-- <el-option-->
|
<el-option-group :label="t('dialog.boop_dialog.my_emojis')">
|
||||||
<!-- v-for="image in emojiTable"-->
|
<el-option
|
||||||
<!-- v-if="image.versions && image.versions.length > 0"-->
|
v-for="image in emojiTable"
|
||||||
<!-- :key="image.id"-->
|
:key="image.id"
|
||||||
<!-- :value="image.id"-->
|
:value="image.id"
|
||||||
<!-- style="width: 100%; height: 100%">-->
|
style="width: 100%; height: 100%">
|
||||||
<!-- <div-->
|
<div
|
||||||
<!-- v-if="image.versions[image.versions.length - 1].file.url"-->
|
v-if="
|
||||||
<!-- class="vrcplus-icon"-->
|
image.versions &&
|
||||||
<!-- style="overflow: hidden; width: 200px; height: 200px; padding: 10px">-->
|
image.versions.length > 0 &&
|
||||||
<!-- <template v-if="image.frames">-->
|
image.versions[image.versions.length - 1].file.url
|
||||||
<!-- <div-->
|
"
|
||||||
<!-- class="avatar"-->
|
class="vrcplus-icon"
|
||||||
<!-- :style="-->
|
style="overflow: hidden; width: 200px; height: 200px; padding: 10px">
|
||||||
<!-- generateEmojiStyle(-->
|
<template v-if="image.frames">
|
||||||
<!-- image.versions[image.versions.length - 1].file.url,-->
|
<div
|
||||||
<!-- image.framesOverTime,-->
|
class="avatar"
|
||||||
<!-- image.frames,-->
|
:style="
|
||||||
<!-- image.loopStyle-->
|
generateEmojiStyle(
|
||||||
<!-- )-->
|
image.versions[image.versions.length - 1].file.url,
|
||||||
<!-- "></div>-->
|
image.framesOverTime,
|
||||||
<!-- </template>-->
|
image.frames,
|
||||||
<!-- <template v-else>-->
|
image.loopStyle
|
||||||
<!-- <img-->
|
)
|
||||||
<!-- :src="image.versions[image.versions.length - 1].file.url"-->
|
"></div>
|
||||||
<!-- class="avatar"-->
|
</template>
|
||||||
<!-- style="width: 200px; height: 200px" />-->
|
<template v-else>
|
||||||
<!-- </template>-->
|
<img
|
||||||
<!-- </div>-->
|
:src="image.versions[image.versions.length - 1].file.url"
|
||||||
<!-- </el-option>-->
|
class="avatar"
|
||||||
<!-- </el-option-group>-->
|
style="width: 200px; height: 200px" />
|
||||||
<!-- <el-option-group :label="t('dialog.boop_dialog.default_emojis')">-->
|
</template>
|
||||||
<!-- <el-option-->
|
</div>
|
||||||
<!-- v-for="emojiName in photonEmojis"-->
|
</el-option>
|
||||||
<!-- :key="emojiName"-->
|
</el-option-group>
|
||||||
<!-- :value="getEmojiValue(emojiName)"-->
|
<el-option-group :label="t('dialog.boop_dialog.default_emojis')">
|
||||||
<!-- style="width: 100%; height: 100%">-->
|
<el-option
|
||||||
<!-- <span v-text="emojiName"></span>-->
|
v-for="emojiName in photonEmojis"
|
||||||
<!-- </el-option>-->
|
:key="emojiName"
|
||||||
<!-- </el-option-group>-->
|
:value="getEmojiValue(emojiName)"
|
||||||
<!-- </el-select>-->
|
style="width: 100%; height: 100%">
|
||||||
|
<span v-text="emojiName"></span>
|
||||||
|
</el-option>
|
||||||
|
</el-option-group>
|
||||||
|
</el-select>
|
||||||
|
|
||||||
<!-- <template #footer>-->
|
<template #footer>
|
||||||
<!-- <el-button size="small" @click="showGalleryDialog(2)">{{-->
|
<el-button
|
||||||
<!-- t('dialog.boop_dialog.emoji_manager')-->
|
size="small"
|
||||||
<!-- }}</el-button>-->
|
@click="
|
||||||
<!-- <el-button size="small" @click="closeDialog">{{ t('dialog.boop_dialog.cancel') }}</el-button>-->
|
redirectToToolsTab();
|
||||||
<!-- <el-button size="small" :disabled="!sendBoopDialog.userId" @click="sendBoop">{{-->
|
showGalleryDialog();
|
||||||
<!-- t('dialog.boop_dialog.send')-->
|
"
|
||||||
<!-- }}</el-button>-->
|
>{{ t('dialog.boop_dialog.emoji_manager') }}</el-button
|
||||||
<!-- </template>-->
|
>
|
||||||
<!-- </el-dialog>-->
|
<el-button size="small" @click="closeDialog">{{ t('dialog.boop_dialog.cancel') }}</el-button>
|
||||||
<!--</template>-->
|
<el-button size="small" :disabled="!sendBoopDialog.userId" @click="sendBoop">{{
|
||||||
|
t('dialog.boop_dialog.send')
|
||||||
|
}}</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
<!--<script setup>-->
|
<script setup>
|
||||||
<!-- import { inject, ref } from 'vue';-->
|
import { ref, watch } from 'vue';
|
||||||
<!-- import { useI18n } from 'vue-i18n-bridge';-->
|
import { storeToRefs } from 'pinia';
|
||||||
<!-- import { photonEmojis } from '../../composables/shared/constants/photon.js';-->
|
import { useI18n } from 'vue-i18n';
|
||||||
<!-- import { notificationRequest } from '../../api';-->
|
|
||||||
<!-- // import { miscRequest } from '../../api';-->
|
|
||||||
|
|
||||||
<!-- const { t } = useI18n();-->
|
import { generateEmojiStyle, userImage, userStatusClass } from '../../shared/utils';
|
||||||
|
import { miscRequest } from '../../api';
|
||||||
|
import { notificationRequest } from '../../api';
|
||||||
|
import { photonEmojis } from '../../shared/constants/photon.js';
|
||||||
|
import { redirectToToolsTab } from '../../shared/utils/base/ui';
|
||||||
|
import { useFriendStore } from '../../stores';
|
||||||
|
import { useGalleryStore } from '../../stores';
|
||||||
|
import { useNotificationStore } from '../../stores';
|
||||||
|
import { useUserStore } from '../../stores/user.js';
|
||||||
|
|
||||||
<!-- const userStatusClass = inject('userStatusClass');-->
|
const { t } = useI18n();
|
||||||
<!-- const userImage = inject('userImage');-->
|
|
||||||
<!-- const showGalleryDialog = inject('showGalleryDialog');-->
|
|
||||||
|
|
||||||
<!-- const props = defineProps({-->
|
const { sendBoopDialog } = storeToRefs(useUserStore());
|
||||||
<!-- sendBoopDialog: {-->
|
const { notificationTable } = storeToRefs(useNotificationStore());
|
||||||
<!-- type: Object,-->
|
const { showGalleryDialog, refreshEmojiTable } = useGalleryStore();
|
||||||
<!-- required: true-->
|
const { emojiTable } = storeToRefs(useGalleryStore());
|
||||||
<!-- },-->
|
const { vipFriends, onlineFriends, activeFriends, offlineFriends } = useFriendStore();
|
||||||
<!-- emojiTable: {-->
|
|
||||||
<!-- type: Array,-->
|
|
||||||
<!-- required: true-->
|
|
||||||
<!-- },-->
|
|
||||||
<!-- vipFriends: {-->
|
|
||||||
<!-- type: Array,-->
|
|
||||||
<!-- required: true-->
|
|
||||||
<!-- },-->
|
|
||||||
<!-- onlineFriends: {-->
|
|
||||||
<!-- type: Array,-->
|
|
||||||
<!-- required: true-->
|
|
||||||
<!-- },-->
|
|
||||||
<!-- activeFriends: {-->
|
|
||||||
<!-- type: Array,-->
|
|
||||||
<!-- required: true-->
|
|
||||||
<!-- },-->
|
|
||||||
<!-- offlineFriends: {-->
|
|
||||||
<!-- type: Array,-->
|
|
||||||
<!-- required: true-->
|
|
||||||
<!-- },-->
|
|
||||||
<!-- generateEmojiStyle: {-->
|
|
||||||
<!-- type: Function,-->
|
|
||||||
<!-- required: true-->
|
|
||||||
<!-- },-->
|
|
||||||
<!-- notificationTable: {-->
|
|
||||||
<!-- type: Object,-->
|
|
||||||
<!-- required: true-->
|
|
||||||
<!-- }-->
|
|
||||||
<!-- });-->
|
|
||||||
|
|
||||||
<!-- const emit = defineEmits(['update:sendBoopDialog']);-->
|
const fileId = ref('');
|
||||||
|
|
||||||
<!-- const fileId = ref('');-->
|
watch(
|
||||||
|
() => sendBoopDialog.value.visible,
|
||||||
|
(visible) => {
|
||||||
|
if (visible && emojiTable.value.length === 0) {
|
||||||
|
refreshEmojiTable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
<!-- // $app.data.sendBoopDialog = {-->
|
function closeDialog() {
|
||||||
<!-- // visible: false,-->
|
sendBoopDialog.value.visible = false;
|
||||||
<!-- // userId: ''-->
|
}
|
||||||
<!-- // };-->
|
function getEmojiValue(emojiName) {
|
||||||
<!-- // $app.methods.showSendBoopDialog = function (userId) {-->
|
if (!emojiName) {
|
||||||
<!-- // this.$nextTick(() =>-->
|
return '';
|
||||||
<!-- // $app.adjustDialogZ(this.$refs.sendBoopDialog.$el)-->
|
}
|
||||||
<!-- // );-->
|
return `default_${emojiName.replace(/ /g, '_').toLowerCase()}`;
|
||||||
<!-- // const D = this.sendBoopDialog;-->
|
}
|
||||||
<!-- // D.userId = userId;-->
|
|
||||||
<!-- // D.visible = true;-->
|
|
||||||
<!-- // if (this.emojiTable.length === 0 && API.currentUser.$isVRCPlus) {-->
|
|
||||||
<!-- // this.refreshEmojiTable();-->
|
|
||||||
<!-- // }-->
|
|
||||||
<!-- // };-->
|
|
||||||
|
|
||||||
<!-- function closeDialog() {-->
|
function sendBoop() {
|
||||||
<!-- emit('update:sendBoopDialog', {-->
|
const D = sendBoopDialog.value;
|
||||||
<!-- ...props.sendBoopDialog,-->
|
dismissBoop(D.userId);
|
||||||
<!-- visible: false-->
|
const params = {
|
||||||
<!-- });-->
|
userId: D.userId
|
||||||
<!-- }-->
|
};
|
||||||
<!-- function getEmojiValue(emojiName) {-->
|
if (fileId.value) {
|
||||||
<!-- if (!emojiName) {-->
|
params.emojiId = fileId.value;
|
||||||
<!-- return '';-->
|
}
|
||||||
<!-- }-->
|
miscRequest.sendBoop(params);
|
||||||
<!-- return `vrchat_${emojiName.replace(/ /g, '_').toLowerCase()}`;-->
|
D.visible = false;
|
||||||
<!-- }-->
|
}
|
||||||
|
|
||||||
<!-- function sendBoop() {-->
|
function dismissBoop(userId) {
|
||||||
<!-- const D = props.sendBoopDialog;-->
|
// JANK: This is a hack to remove boop notifications when responding
|
||||||
<!-- dismissBoop(D.userId);-->
|
const array = notificationTable.value.data;
|
||||||
<!-- const params = {-->
|
for (let i = array.length - 1; i >= 0; i--) {
|
||||||
<!-- userId: D.userId-->
|
const ref = array[i];
|
||||||
<!-- };-->
|
if (ref.type !== 'boop' || ref.$isExpired || ref.senderUserId !== userId) {
|
||||||
<!-- if (fileId.value) {-->
|
continue;
|
||||||
<!-- params.emojiId = fileId.value;-->
|
}
|
||||||
<!-- }-->
|
notificationRequest.sendNotificationResponse({
|
||||||
<!-- // miscRequest.sendBoop(params);-->
|
notificationId: ref.id,
|
||||||
<!-- D.visible = false;-->
|
responseType: 'delete',
|
||||||
<!-- }-->
|
responseData: ''
|
||||||
|
});
|
||||||
<!-- function dismissBoop(userId) {-->
|
}
|
||||||
<!-- // JANK: This is a hack to remove boop notifications when responding-->
|
}
|
||||||
<!-- const array = props.notificationTable.data;-->
|
</script>
|
||||||
<!-- for (let i = array.length - 1; i >= 0; i--) {-->
|
|
||||||
<!-- const ref = array[i];-->
|
|
||||||
<!-- if (ref.type !== 'boop' || ref.$isExpired || ref.senderUserId !== userId) {-->
|
|
||||||
<!-- continue;-->
|
|
||||||
<!-- }-->
|
|
||||||
<!-- notificationRequest.sendNotificationResponse({-->
|
|
||||||
<!-- notificationId: ref.id,-->
|
|
||||||
<!-- responseType: 'delete',-->
|
|
||||||
<!-- responseData: ''-->
|
|
||||||
<!-- });-->
|
|
||||||
<!-- }-->
|
|
||||||
<!-- }-->
|
|
||||||
<!--</script>-->
|
|
||||||
|
|||||||
@@ -108,6 +108,12 @@
|
|||||||
<el-dropdown-item v-else :icon="Plus" command="Send Friend Request">{{
|
<el-dropdown-item v-else :icon="Plus" command="Send Friend Request">{{
|
||||||
t('dialog.user.actions.send_friend_request')
|
t('dialog.user.actions.send_friend_request')
|
||||||
}}</el-dropdown-item>
|
}}</el-dropdown-item>
|
||||||
|
<el-dropdown-item
|
||||||
|
:disabled="!currentUser.isBoopingEnabled"
|
||||||
|
:icon="Pointer"
|
||||||
|
command="Send Boop"
|
||||||
|
>{{ t('dialog.user.actions.send_boop') }}</el-dropdown-item
|
||||||
|
>
|
||||||
<el-dropdown-item :icon="Message" command="Invite To Group">{{
|
<el-dropdown-item :icon="Message" command="Invite To Group">{{
|
||||||
t('dialog.user.actions.invite_to_group')
|
t('dialog.user.actions.invite_to_group')
|
||||||
}}</el-dropdown-item>
|
}}</el-dropdown-item>
|
||||||
|
|||||||
@@ -423,11 +423,17 @@
|
|||||||
}}</span>
|
}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!--//- .x-friend-item(@click="toggleAllowBooping")-->
|
<div class="x-friend-item" @click="toggleAllowBooping">
|
||||||
<!--//- .detail-->
|
<div class="detail">
|
||||||
<!--//- span.name {{ t('dialog.user.info.booping') }}-->
|
<span class="name">{{ t('dialog.user.info.booping') }}</span>
|
||||||
<!--//- span.extra(v-if="currentUser.isBoopingEnabled" style="color:#67C23A") {{ t('dialog.user.info.avatar_cloning_allow') }}-->
|
<span v-if="currentUser.isBoopingEnabled" class="extra" style="color: #67c23a">{{
|
||||||
<!--//- span.extra(v-else style="color:#F56C6C") {{ t('dialog.user.info.avatar_cloning_deny') }}-->
|
t('dialog.user.info.avatar_cloning_allow')
|
||||||
|
}}</span>
|
||||||
|
<span v-else class="extra" style="color: #f56c6c">{{
|
||||||
|
t('dialog.user.info.avatar_cloning_deny')
|
||||||
|
}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<div class="x-friend-item" style="cursor: default">
|
<div class="x-friend-item" style="cursor: default">
|
||||||
@@ -1302,8 +1308,14 @@
|
|||||||
const { hideUserNotes, hideUserMemos } = storeToRefs(useAppearanceSettingsStore());
|
const { hideUserNotes, hideUserMemos } = storeToRefs(useAppearanceSettingsStore());
|
||||||
const { avatarRemoteDatabase } = storeToRefs(useAdvancedSettingsStore());
|
const { avatarRemoteDatabase } = storeToRefs(useAdvancedSettingsStore());
|
||||||
const { userDialog, languageDialog, currentUser, isLocalUserVrcPlusSupporter } = storeToRefs(useUserStore());
|
const { userDialog, languageDialog, currentUser, isLocalUserVrcPlusSupporter } = storeToRefs(useUserStore());
|
||||||
const { cachedUsers, showUserDialog, sortUserDialogAvatars, refreshUserDialogAvatars, refreshUserDialogTreeData } =
|
const {
|
||||||
useUserStore();
|
cachedUsers,
|
||||||
|
showUserDialog,
|
||||||
|
sortUserDialogAvatars,
|
||||||
|
refreshUserDialogAvatars,
|
||||||
|
refreshUserDialogTreeData,
|
||||||
|
showSendBoopDialog
|
||||||
|
} = useUserStore();
|
||||||
const { favoriteLimits } = storeToRefs(useFavoriteStore());
|
const { favoriteLimits } = storeToRefs(useFavoriteStore());
|
||||||
const { showFavoriteDialog, handleFavoriteWorldList } = useFavoriteStore();
|
const { showFavoriteDialog, handleFavoriteWorldList } = useFavoriteStore();
|
||||||
const { showAvatarDialog, lookupAvatars, showAvatarAuthorDialog } = useAvatarStore();
|
const { showAvatarDialog, lookupAvatars, showAvatarAuthorDialog } = useAvatarStore();
|
||||||
@@ -1749,8 +1761,8 @@
|
|||||||
redirectToToolsTab();
|
redirectToToolsTab();
|
||||||
} else if (command === 'Invite To Group') {
|
} else if (command === 'Invite To Group') {
|
||||||
showInviteGroupDialog('', D.id);
|
showInviteGroupDialog('', D.id);
|
||||||
// } else if (command === 'Send Boop') {
|
} else if (command === 'Send Boop') {
|
||||||
// this.showSendBoopDialog(D.id);
|
showSendBoopDialog(D.id);
|
||||||
} else if (command === 'Group Moderation') {
|
} else if (command === 'Group Moderation') {
|
||||||
showModerateGroupDialog(D.id);
|
showModerateGroupDialog(D.id);
|
||||||
} else if (command === 'Hide Avatar') {
|
} else if (command === 'Hide Avatar') {
|
||||||
@@ -2273,6 +2285,12 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toggleAllowBooping() {
|
||||||
|
userRequest.saveCurrentUser({
|
||||||
|
isBoopingEnabled: !currentUser.value.isBoopingEnabled
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function resetHome() {
|
function resetHome() {
|
||||||
ElMessageBox.confirm('Continue? Reset Home', 'Confirm', {
|
ElMessageBox.confirm('Continue? Reset Home', 'Confirm', {
|
||||||
confirmButtonText: 'Confirm',
|
confirmButtonText: 'Confirm',
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
useSearchStore,
|
useSearchStore,
|
||||||
useWorldStore
|
useWorldStore
|
||||||
} from '../../stores';
|
} from '../../stores';
|
||||||
|
import { AppDebug } from '../../service/appConfig.js';
|
||||||
import { compareUnityVersion } from './avatar';
|
import { compareUnityVersion } from './avatar';
|
||||||
import { escapeTag } from './base/string';
|
import { escapeTag } from './base/string';
|
||||||
import { miscRequest } from '../../api';
|
import { miscRequest } from '../../api';
|
||||||
@@ -213,7 +214,7 @@ function convertFileUrlToImageUrl(url, resolution = 128) {
|
|||||||
if (match) {
|
if (match) {
|
||||||
const fileId = match[1];
|
const fileId = match[1];
|
||||||
const version = match[2];
|
const version = match[2];
|
||||||
return `https://api.vrchat.cloud/api/1/image/file_${fileId}/${version}/${resolution}`;
|
return `${AppDebug.endpointDomain}/image/file_${fileId}/${version}/${resolution}`;
|
||||||
}
|
}
|
||||||
// no match return origin url
|
// no match return origin url
|
||||||
return url;
|
return url;
|
||||||
|
|||||||
@@ -54,4 +54,34 @@ function getEmojiFileName(emoji) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export { getPrintLocalDate, getPrintFileName, getEmojiFileName };
|
/**
|
||||||
|
* @param {string} url
|
||||||
|
* @param {number} fps
|
||||||
|
* @param {number} frameCount
|
||||||
|
* @param {string} loopStyle
|
||||||
|
*/
|
||||||
|
function generateEmojiStyle(url, fps, frameCount, loopStyle) {
|
||||||
|
let framesPerLine = 2;
|
||||||
|
if (frameCount > 4) framesPerLine = 4;
|
||||||
|
if (frameCount > 16) framesPerLine = 8;
|
||||||
|
const animationDurationMs = (1000 / fps) * frameCount;
|
||||||
|
const frameSize = 1024 / framesPerLine;
|
||||||
|
const scale = 100 / (frameSize / 200);
|
||||||
|
const animStyle = loopStyle === 'pingpong' ? 'alternate' : 'none';
|
||||||
|
const style = `
|
||||||
|
transform: scale(${scale / 100});
|
||||||
|
transform-origin: top left;
|
||||||
|
width: ${frameSize}px;
|
||||||
|
height: ${frameSize}px;
|
||||||
|
background: url('${url}') 0 0;
|
||||||
|
animation: ${animationDurationMs}ms steps(1) 0s infinite ${animStyle} running animated-emoji-${frameCount};
|
||||||
|
`;
|
||||||
|
return style;
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
getPrintLocalDate,
|
||||||
|
getPrintFileName,
|
||||||
|
getEmojiFileName,
|
||||||
|
generateEmojiStyle
|
||||||
|
};
|
||||||
|
|||||||
@@ -413,6 +413,15 @@ export const useNotificationStore = defineStore('Notification', () => {
|
|||||||
}
|
}
|
||||||
ref.details = details;
|
ref.details = details;
|
||||||
}
|
}
|
||||||
|
if (ref.type === 'boop') {
|
||||||
|
ref.message = ref.title;
|
||||||
|
if (ref.details?.emojiId.startsWith('default_')) {
|
||||||
|
ref.details.imageUrl = ref.details.emojiId;
|
||||||
|
ref.message += ` ${ref.details.emojiId.replace('default_', '')}`;
|
||||||
|
} else {
|
||||||
|
ref.details.imageUrl = `${AppDebug.endpointDomain}/file/${ref.details.emojiId}/${ref.details.emojiVersion}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1115,7 +1115,7 @@ export const usePhotonStore = defineStore('Photon', () => {
|
|||||||
} else if (type === 1) {
|
} else if (type === 1) {
|
||||||
emojiName = 'Custom';
|
emojiName = 'Custom';
|
||||||
var fileId = data.Parameters[245][1];
|
var fileId = data.Parameters[245][1];
|
||||||
imageUrl = `https://api.vrchat.cloud/api/1/file/${fileId}/1/`;
|
imageUrl = `${AppDebug.endpointDomain}/file/${fileId}/1/`;
|
||||||
}
|
}
|
||||||
addEntryPhotonEvent({
|
addEntryPhotonEvent({
|
||||||
photonId,
|
photonId,
|
||||||
|
|||||||
@@ -269,6 +269,10 @@ export const useUserStore = defineStore('User', () => {
|
|||||||
languageChoice: false,
|
languageChoice: false,
|
||||||
languages: []
|
languages: []
|
||||||
});
|
});
|
||||||
|
const sendBoopDialog = ref({
|
||||||
|
visible: false,
|
||||||
|
userId: ''
|
||||||
|
});
|
||||||
const pastDisplayNameTable = ref({
|
const pastDisplayNameTable = ref({
|
||||||
data: [],
|
data: [],
|
||||||
tableProps: {
|
tableProps: {
|
||||||
@@ -1960,6 +1964,11 @@ export const useUserStore = defineStore('User', () => {
|
|||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function showSendBoopDialog(userId) {
|
||||||
|
sendBoopDialog.value.userId = userId;
|
||||||
|
sendBoopDialog.value.visible = true;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
state,
|
state,
|
||||||
|
|
||||||
@@ -1968,6 +1977,7 @@ export const useUserStore = defineStore('User', () => {
|
|||||||
userDialog,
|
userDialog,
|
||||||
subsetOfLanguages,
|
subsetOfLanguages,
|
||||||
languageDialog,
|
languageDialog,
|
||||||
|
sendBoopDialog,
|
||||||
pastDisplayNameTable,
|
pastDisplayNameTable,
|
||||||
showUserDialogHistory,
|
showUserDialogHistory,
|
||||||
customUserTags,
|
customUserTags,
|
||||||
@@ -1986,7 +1996,7 @@ export const useUserStore = defineStore('User', () => {
|
|||||||
initUserNotes,
|
initUserNotes,
|
||||||
getCurrentUser,
|
getCurrentUser,
|
||||||
handleConfig,
|
handleConfig,
|
||||||
|
showSendBoopDialog,
|
||||||
checkNote
|
checkNote
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -125,7 +125,16 @@
|
|||||||
|
|
||||||
<el-table-column :label="t('table.notification.photo')" width="100" prop="photo">
|
<el-table-column :label="t('table.notification.photo')" width="100" prop="photo">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<template v-if="scope.row.details && scope.row.details.imageUrl">
|
<template v-if="scope.row.type === 'boop'">
|
||||||
|
<img
|
||||||
|
v-if="!scope.row.details.imageUrl.startsWith('default_')"
|
||||||
|
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" />
|
||||||
|
</template>
|
||||||
|
<template v-else-if="scope.row.details && scope.row.details.imageUrl">
|
||||||
<img
|
<img
|
||||||
class="x-link"
|
class="x-link"
|
||||||
:src="getSmallThumbnailUrl(scope.row.details.imageUrl)"
|
:src="getSmallThumbnailUrl(scope.row.details.imageUrl)"
|
||||||
@@ -224,7 +233,14 @@
|
|||||||
<template v-for="response in scope.row.responses" :key="response.text">
|
<template v-for="response in scope.row.responses" :key="response.text">
|
||||||
<el-tooltip placement="top" :content="response.text">
|
<el-tooltip placement="top" :content="response.text">
|
||||||
<el-button
|
<el-button
|
||||||
v-if="response.icon === 'check'"
|
v-if="response.type === 'link'"
|
||||||
|
type="text"
|
||||||
|
:icon="Link"
|
||||||
|
size="small"
|
||||||
|
:class="['button-pd-0', 'ml-5']"
|
||||||
|
@click="openNotificationLink(response.data)" />
|
||||||
|
<el-button
|
||||||
|
v-else-if="response.icon === 'check'"
|
||||||
type="text"
|
type="text"
|
||||||
:icon="Check"
|
:icon="Check"
|
||||||
size="small"
|
size="small"
|
||||||
@@ -259,13 +275,13 @@
|
|||||||
@click="
|
@click="
|
||||||
sendNotificationResponse(scope.row.id, scope.row.responses, response.type)
|
sendNotificationResponse(scope.row.id, scope.row.responses, response.type)
|
||||||
" />
|
" />
|
||||||
<!--//el-button(-->
|
<el-button
|
||||||
<!--// v-else-if='response.icon === "reply" && scope.row.type === "boop"'-->
|
v-else-if="response.icon === 'reply' && scope.row.type === 'boop'"
|
||||||
<!--// type='text'-->
|
type="text"
|
||||||
<!--// icon='el-icon-chat-line-square'-->
|
:icon="ChatLineSquare"
|
||||||
<!--// size='mini'-->
|
size="small"
|
||||||
<!--// style='margin-left: 5px'-->
|
:class="['button-pd-0', 'ml-5']"
|
||||||
<!--// @click='showSendBoopDialog(scope.row.senderUserId)')-->
|
@click="showSendBoopDialog(scope.row.senderUserId)" />
|
||||||
<el-button
|
<el-button
|
||||||
v-else-if="response.icon === 'reply'"
|
v-else-if="response.icon === 'reply'"
|
||||||
type="text"
|
type="text"
|
||||||
@@ -384,6 +400,7 @@
|
|||||||
Close,
|
Close,
|
||||||
CollectionTag,
|
CollectionTag,
|
||||||
Delete,
|
Delete,
|
||||||
|
Link,
|
||||||
Refresh
|
Refresh
|
||||||
} from '@element-plus/icons-vue';
|
} from '@element-plus/icons-vue';
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||||
@@ -419,7 +436,7 @@
|
|||||||
import SendInviteResponseDialog from './dialogs/SendInviteResponseDialog.vue';
|
import SendInviteResponseDialog from './dialogs/SendInviteResponseDialog.vue';
|
||||||
import configRepository from '../../service/config';
|
import configRepository from '../../service/config';
|
||||||
|
|
||||||
const { showUserDialog } = useUserStore();
|
const { showUserDialog, showSendBoopDialog } = useUserStore();
|
||||||
const { showWorldDialog } = useWorldStore();
|
const { showWorldDialog } = useWorldStore();
|
||||||
const { showGroupDialog } = useGroupStore();
|
const { showGroupDialog } = useGroupStore();
|
||||||
const { lastLocation, lastLocationDestination } = storeToRefs(useLocationStore());
|
const { lastLocation, lastLocationDestination } = storeToRefs(useLocationStore());
|
||||||
|
|||||||
@@ -550,8 +550,14 @@
|
|||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
|
import {
|
||||||
|
extractFileId,
|
||||||
|
formatDateFilter,
|
||||||
|
generateEmojiStyle,
|
||||||
|
getEmojiFileName,
|
||||||
|
getPrintFileName
|
||||||
|
} from '../../../shared/utils';
|
||||||
import { inventoryRequest, miscRequest, userRequest, vrcPlusIconRequest, vrcPlusImageRequest } from '../../../api';
|
import { inventoryRequest, miscRequest, userRequest, vrcPlusIconRequest, vrcPlusImageRequest } from '../../../api';
|
||||||
import { extractFileId, formatDateFilter, getEmojiFileName, getPrintFileName } from '../../../shared/utils';
|
|
||||||
import { useAdvancedSettingsStore, useAuthStore, useGalleryStore, useUserStore } from '../../../stores';
|
import { useAdvancedSettingsStore, useAuthStore, useGalleryStore, useUserStore } from '../../../stores';
|
||||||
import { emojiAnimationStyleList, emojiAnimationStyleUrl } from '../../../shared/constants';
|
import { emojiAnimationStyleList, emojiAnimationStyleUrl } from '../../../shared/constants';
|
||||||
import { AppDebug } from '../../../service/appConfig';
|
import { AppDebug } from '../../../service/appConfig';
|
||||||
@@ -905,25 +911,6 @@
|
|||||||
document.getElementById('EmojiUploadButton').click();
|
document.getElementById('EmojiUploadButton').click();
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateEmojiStyle(url, fps, frameCount, loopStyle) {
|
|
||||||
let framesPerLine = 2;
|
|
||||||
if (frameCount > 4) framesPerLine = 4;
|
|
||||||
if (frameCount > 16) framesPerLine = 8;
|
|
||||||
const animationDurationMs = (1000 / fps) * frameCount;
|
|
||||||
const frameSize = 1024 / framesPerLine;
|
|
||||||
const scale = 100 / (frameSize / 200);
|
|
||||||
const animStyle = loopStyle === 'pingpong' ? 'alternate' : 'none';
|
|
||||||
const style = `
|
|
||||||
transform: scale(${scale / 100});
|
|
||||||
transform-origin: top left;
|
|
||||||
width: ${frameSize}px;
|
|
||||||
height: ${frameSize}px;
|
|
||||||
background: url('${url}') 0 0;
|
|
||||||
animation: ${animationDurationMs}ms steps(1) 0s infinite ${animStyle} running animated-emoji-${frameCount};
|
|
||||||
`;
|
|
||||||
return style;
|
|
||||||
}
|
|
||||||
|
|
||||||
function deleteEmoji(fileId) {
|
function deleteEmoji(fileId) {
|
||||||
miscRequest.deleteFile(fileId).then((args) => {
|
miscRequest.deleteFile(fileId).then((args) => {
|
||||||
const array = emojiTable.value;
|
const array = emojiTable.value;
|
||||||
|
|||||||
Reference in New Issue
Block a user