eslint fix

This commit is contained in:
pa
2026-03-10 22:42:22 +09:00
parent 699bf620e5
commit 4877010006
124 changed files with 980 additions and 1121 deletions
-2
View File
@@ -66,7 +66,6 @@ const avatarReq = {
* @returns {Promise<{json: any, params}>} * @returns {Promise<{json: any, params}>}
*/ */
selectAvatar(params) { selectAvatar(params) {
return request(`avatars/${params.avatarId}/select`, { return request(`avatars/${params.avatarId}/select`, {
method: 'PUT', method: 'PUT',
params params
@@ -98,7 +97,6 @@ const avatarReq = {
* @returns { Promise<{json: any, params}> } * @returns { Promise<{json: any, params}> }
*/ */
selectFallbackAvatar(params) { selectFallbackAvatar(params) {
return request(`avatars/${params.avatarId}/selectfallback`, { return request(`avatars/${params.avatarId}/selectfallback`, {
method: 'PUT', method: 'PUT',
params params
+2 -2
View File
@@ -14,7 +14,7 @@ const avatarModerationReq = {
/** /**
* @param {{ avatarModerationType: string, targetAvatarId: string }} params * @param {{ avatarModerationType: string, targetAvatarId: string }} params
* @return { Promise<{json: any, params}> } * @returns { Promise<{json: any, params}> }
*/ */
sendAvatarModeration(params) { sendAvatarModeration(params) {
return request('auth/user/avatarmoderations', { return request('auth/user/avatarmoderations', {
@@ -31,7 +31,7 @@ const avatarModerationReq = {
/** /**
* @param {{ avatarModerationType: string, targetAvatarId: string }} params * @param {{ avatarModerationType: string, targetAvatarId: string }} params
* @return { Promise<{json: any, params}> } * @returns { Promise<{json: any, params}> }
*/ */
deleteAvatarModeration(params) { deleteAvatarModeration(params) {
return request( return request(
-1
View File
@@ -23,7 +23,6 @@ const friendReq = {
* @type {import('../types/api/friend').GetFriends} * @type {import('../types/api/friend').GetFriends}
*/ */
getFriends(params) { getFriends(params) {
return request('auth/user/friends', { return request('auth/user/friends', {
method: 'GET', method: 'GET',
params params
+8 -7
View File
@@ -2,7 +2,8 @@ import { request } from '../services/request';
import { useGalleryStore } from '../stores'; import { useGalleryStore } from '../stores';
const notificationReq = { const notificationReq = {
/** @typedef {{ /**
* @typedef {{
* n: number, * n: number,
* offset: number, * offset: number,
* sent: boolean, * sent: boolean,
@@ -89,7 +90,7 @@ const notificationReq = {
* rsvp?: boolean, * rsvp?: boolean,
* }} params * }} params
* @param receiverUserId * @param receiverUserId
* @return { Promise<{json: any, params}> } * @returns { Promise<{json: any, params}> }
*/ */
sendInvite(params, receiverUserId) { sendInvite(params, receiverUserId) {
return request(`invite/${receiverUserId}`, { return request(`invite/${receiverUserId}`, {
@@ -180,7 +181,7 @@ const notificationReq = {
/** /**
* @param {{ notificationId: string }} params * @param {{ notificationId: string }} params
* @return { Promise<{json: any, params}> } * @returns { Promise<{json: any, params}> }
*/ */
acceptFriendRequestNotification(params) { acceptFriendRequestNotification(params) {
return request( return request(
@@ -199,7 +200,7 @@ const notificationReq = {
/** /**
* @param {{ notificationId: string }} params * @param {{ notificationId: string }} params
* @return { Promise<{json: any, params}> } * @returns { Promise<{json: any, params}> }
*/ */
hideNotification(params) { hideNotification(params) {
return request( return request(
@@ -218,7 +219,7 @@ const notificationReq = {
/** /**
* @param {{ notificationId: string }} params * @param {{ notificationId: string }} params
* @return { Promise<{json: any, params}> } * @returns { Promise<{json: any, params}> }
*/ */
seeNotification(params) { seeNotification(params) {
return request(`auth/user/notifications/${params.notificationId}/see`, { return request(`auth/user/notifications/${params.notificationId}/see`, {
@@ -234,7 +235,7 @@ const notificationReq = {
/** /**
* @param {{ notificationId: string }} params * @param {{ notificationId: string }} params
* @return { Promise<{json: any, params}> } * @returns { Promise<{json: any, params}> }
*/ */
seeNotificationV2(params) { seeNotificationV2(params) {
return request(`notifications/${params.notificationId}/see`, { return request(`notifications/${params.notificationId}/see`, {
@@ -254,7 +255,7 @@ const notificationReq = {
* responseType: string, * responseType: string,
* responseData: string * responseData: string
* }} params * }} params
* @return { Promise<{json: any, params}> } * @returns { Promise<{json: any, params}> }
*/ */
sendNotificationResponse(params) { sendNotificationResponse(params) {
return request(`notifications/${params.notificationId}/respond`, { return request(`notifications/${params.notificationId}/respond`, {
+2 -2
View File
@@ -14,7 +14,7 @@ const playerModerationReq = {
/** /**
* @param {{ moderated: string, type: string }} params * @param {{ moderated: string, type: string }} params
* @return { Promise<{json: any, params}> } * @returns { Promise<{json: any, params}> }
*/ */
// old-way: POST auth/user/blocks {blocked:userId} // old-way: POST auth/user/blocks {blocked:userId}
sendPlayerModeration(params) { sendPlayerModeration(params) {
@@ -32,7 +32,7 @@ const playerModerationReq = {
/** /**
* @param {{ moderated: string, type: string }} params * @param {{ moderated: string, type: string }} params
* @return { Promise<{json: any, params}> } * @returns { Promise<{json: any, params}> }
*/ */
// old-way: PUT auth/user/unblocks {blocked:userId} // old-way: PUT auth/user/unblocks {blocked:userId}
deletePlayerModeration(params) { deletePlayerModeration(params) {
-4
View File
@@ -17,7 +17,6 @@ const userReq = {
* @type {import('../types/api/user').GetUser} * @type {import('../types/api/user').GetUser}
*/ */
getUser(params) { getUser(params) {
return request(`users/${params.userId}`, { return request(`users/${params.userId}`, {
method: 'GET' method: 'GET'
}).then((json) => { }).then((json) => {
@@ -57,7 +56,6 @@ const userReq = {
* @returns {Promise<{json: any, params: {tags: string[]}}>} * @returns {Promise<{json: any, params: {tags: string[]}}>}
*/ */
addUserTags(params) { addUserTags(params) {
return request(`users/${getCurrentUserId()}/addTags`, { return request(`users/${getCurrentUserId()}/addTags`, {
method: 'POST', method: 'POST',
params params
@@ -76,7 +74,6 @@ const userReq = {
* @returns {Promise<{json: any, params: {tags: string[]}}>} * @returns {Promise<{json: any, params: {tags: string[]}}>}
*/ */
removeUserTags(params) { removeUserTags(params) {
return request(`users/${getCurrentUserId()}/removeTags`, { return request(`users/${getCurrentUserId()}/removeTags`, {
method: 'POST', method: 'POST',
params params
@@ -114,7 +111,6 @@ const userReq = {
* @type {import('../types/api/user').GetCurrentUser} * @type {import('../types/api/user').GetCurrentUser}
*/ */
saveCurrentUser(params) { saveCurrentUser(params) {
return request(`users/${getCurrentUserId()}`, { return request(`users/${getCurrentUserId()}`, {
method: 'PUT', method: 'PUT',
params params
-1
View File
@@ -44,4 +44,3 @@
watch([() => props.userid, () => props.location, () => props.forceUpdateKey], parse, { immediate: true }); watch([() => props.userid, () => props.location, () => props.forceUpdateKey], parse, { immediate: true });
</script> </script>
-2
View File
@@ -355,8 +355,6 @@
} }
}; };
const closeInstance = (location) => { const closeInstance = (location) => {
modalStore modalStore
.confirm({ .confirm({
@@ -426,7 +426,7 @@
import GroupDialogPhotosTab from './GroupDialogPhotosTab.vue'; import GroupDialogPhotosTab from './GroupDialogPhotosTab.vue';
import GroupDialogPostsTab from './GroupDialogPostsTab.vue'; import GroupDialogPostsTab from './GroupDialogPostsTab.vue';
import GroupPostEditDialog from './GroupPostEditDialog.vue'; import GroupPostEditDialog from './GroupPostEditDialog.vue';
import { showUserDialog } from '../../../coordinators/userCoordinator'; import { showUserDialog } from '../../../coordinators/userCoordinator';
const { t } = useI18n(); const { t } = useI18n();
const groupDialogTabs = computed(() => [ const groupDialogTabs = computed(() => [
@@ -439,13 +439,9 @@ import { showUserDialog } from '../../../coordinators/userCoordinator';
const modalStore = useModalStore(); const modalStore = useModalStore();
const { currentUser } = storeToRefs(useUserStore()); const { currentUser } = storeToRefs(useUserStore());
const { groupDialog, inviteGroupDialog } = storeToRefs(useGroupStore()); const { groupDialog, inviteGroupDialog } = storeToRefs(useGroupStore());
const { const { updateGroupPostSearch, showGroupMemberModerationDialog } = useGroupStore();
updateGroupPostSearch,
showGroupMemberModerationDialog
} = useGroupStore();
const { showFullscreenImageDialog } = useGalleryStore(); const { showFullscreenImageDialog } = useGalleryStore();
@@ -216,12 +216,11 @@
import { applyGroupMember, handleGroupMember } from '../../../coordinators/groupCoordinator'; import { applyGroupMember, handleGroupMember } from '../../../coordinators/groupCoordinator';
import { groupDialogSortingOptions } from '../../../shared/constants'; import { groupDialogSortingOptions } from '../../../shared/constants';
import { useGroupMembers } from './useGroupMembers'; import { useGroupMembers } from './useGroupMembers';
import { showUserDialog } from '../../../coordinators/userCoordinator'; import { showUserDialog } from '../../../coordinators/userCoordinator';
const { userImage } = useUserDisplay(); const { userImage } = useUserDisplay();
const { t } = useI18n(); const { t } = useI18n();
const { currentUser } = storeToRefs(useUserStore()); const { currentUser } = storeToRefs(useUserStore());
const { groupDialog } = storeToRefs(useGroupStore()); const { groupDialog } = storeToRefs(useGroupStore());
@@ -122,7 +122,11 @@
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useAppearanceSettingsStore, useGalleryStore, useGroupStore, useUserStore } from '../../../stores'; import { useAppearanceSettingsStore, useGalleryStore, useGroupStore, useUserStore } from '../../../stores';
import { applyGroupMember, handleGroupMember, handleGroupMemberProps } from '../../../coordinators/groupCoordinator'; import {
applyGroupMember,
handleGroupMember,
handleGroupMemberProps
} from '../../../coordinators/groupCoordinator';
import { hasGroupPermission } from '../../../shared/utils'; import { hasGroupPermission } from '../../../shared/utils';
import { useUserDisplay } from '../../../composables/useUserDisplay'; import { useUserDisplay } from '../../../composables/useUserDisplay';
import { groupDialogFilterOptions, groupDialogSortingOptions } from '../../../shared/constants'; import { groupDialogFilterOptions, groupDialogSortingOptions } from '../../../shared/constants';
@@ -140,7 +144,7 @@
import GroupModerationInvitesTab from './GroupModerationInvitesTab.vue'; import GroupModerationInvitesTab from './GroupModerationInvitesTab.vue';
import GroupModerationLogsTab from './GroupModerationLogsTab.vue'; import GroupModerationLogsTab from './GroupModerationLogsTab.vue';
import GroupModerationMembersTab from './GroupModerationMembersTab.vue'; import GroupModerationMembersTab from './GroupModerationMembersTab.vue';
import { showUserDialog } from '../../../coordinators/userCoordinator'; import { showUserDialog } from '../../../coordinators/userCoordinator';
// ── Stores ─────────────────────────────────────────────────── // ── Stores ───────────────────────────────────────────────────
const { userImage, userImageFull } = useUserDisplay(); const { userImage, userImageFull } = useUserDisplay();
@@ -40,9 +40,7 @@
</template> </template>
<AlertTriangle style="margin-left: 3px; display: inline-block" /> <AlertTriangle style="margin-left: 3px; display: inline-block" />
</TooltipWrapper> </TooltipWrapper>
<span <span v-text="user.user?.displayName || user.userId" style="font-weight: bold; margin-left: 6px"></span>
v-text="user.user?.displayName || user.userId"
style="font-weight: bold; margin-left: 6px"></span>
<button <button
type="button" type="button"
style=" style="
@@ -79,10 +77,7 @@
<SelectValue :placeholder="t('dialog.group_member_moderation.choose_roles_placeholder')" /> <SelectValue :placeholder="t('dialog.group_member_moderation.choose_roles_placeholder')" />
</SelectTrigger> </SelectTrigger>
<SelectContent> <SelectContent>
<SelectItem <SelectItem v-for="role in groupRef.roles" :key="role.id" :value="role.id">
v-for="role in groupRef.roles"
:key="role.id"
:value="role.id">
{{ role.name }} {{ role.name }}
</SelectItem> </SelectItem>
</SelectContent> </SelectContent>
@@ -96,9 +91,7 @@
variant="outline" variant="outline"
:disabled=" :disabled="
Boolean( Boolean(
!selectedRoles.length || !selectedRoles.length || progressCurrent || !hasGroupPermission(groupRef, 'group-roles-assign')
progressCurrent ||
!hasGroupPermission(groupRef, 'group-roles-assign')
) )
" "
@click="$emit('add-roles')" @click="$emit('add-roles')"
@@ -108,9 +101,7 @@
variant="secondary" variant="secondary"
:disabled=" :disabled="
Boolean( Boolean(
!selectedRoles.length || !selectedRoles.length || progressCurrent || !hasGroupPermission(groupRef, 'group-roles-assign')
progressCurrent ||
!hasGroupPermission(groupRef, 'group-roles-assign')
) )
" "
@click="$emit('remove-roles')" @click="$emit('remove-roles')"
@@ -118,45 +109,25 @@
> >
<Button <Button
variant="outline" variant="outline"
:disabled=" :disabled="Boolean(progressCurrent || !hasGroupPermission(groupRef, 'group-members-manage'))"
Boolean(
progressCurrent ||
!hasGroupPermission(groupRef, 'group-members-manage')
)
"
@click="$emit('save-note')" @click="$emit('save-note')"
>{{ t('dialog.group_member_moderation.save_note') }}</Button >{{ t('dialog.group_member_moderation.save_note') }}</Button
> >
<Button <Button
variant="outline" variant="outline"
:disabled=" :disabled="Boolean(progressCurrent || !hasGroupPermission(groupRef, 'group-members-remove'))"
Boolean(
progressCurrent ||
!hasGroupPermission(groupRef, 'group-members-remove')
)
"
@click="$emit('kick')" @click="$emit('kick')"
>{{ t('dialog.group_member_moderation.kick') }}</Button >{{ t('dialog.group_member_moderation.kick') }}</Button
> >
<Button <Button
variant="outline" variant="outline"
:disabled=" :disabled="Boolean(progressCurrent || !hasGroupPermission(groupRef, 'group-bans-manage'))"
Boolean(
progressCurrent ||
!hasGroupPermission(groupRef, 'group-bans-manage')
)
"
@click="$emit('ban')" @click="$emit('ban')"
>{{ t('dialog.group_member_moderation.ban') }}</Button >{{ t('dialog.group_member_moderation.ban') }}</Button
> >
<Button <Button
variant="outline" variant="outline"
:disabled=" :disabled="Boolean(progressCurrent || !hasGroupPermission(groupRef, 'group-bans-manage'))"
Boolean(
progressCurrent ||
!hasGroupPermission(groupRef, 'group-bans-manage')
)
"
@click="$emit('unban')" @click="$emit('unban')"
>{{ t('dialog.group_member_moderation.unban') }}</Button >{{ t('dialog.group_member_moderation.unban') }}</Button
> >
@@ -130,7 +130,7 @@ const MOCK_POSTS = [
]; ];
/** /**
* @param {Object} overrides * @param {object} overrides
*/ */
function mountComponent(overrides = {}) { function mountComponent(overrides = {}) {
const pinia = createTestingPinia({ const pinia = createTestingPinia({
@@ -3,7 +3,6 @@ import { computed } from 'vue';
/** /**
* Composable for filtering group calendar events into past and upcoming, * Composable for filtering group calendar events into past and upcoming,
* and updating follow state on individual events. * and updating follow state on individual events.
*
* @param {import('vue').Ref} groupDialog - reactive ref to the group dialog state * @param {import('vue').Ref} groupDialog - reactive ref to the group dialog state
* @returns {{ * @returns {{
* pastCalenderEvents: import('vue').ComputedRef<Array>, * pastCalenderEvents: import('vue').ComputedRef<Array>,
@@ -35,7 +34,7 @@ export function useGroupCalendarEvents(groupDialog) {
}); });
/** /**
* @param {Object} event * @param {object} event
*/ */
function updateFollowingCalendarData(event) { function updateFollowingCalendarData(event) {
const calendar = groupDialog.value.calendar; const calendar = groupDialog.value.calendar;
@@ -43,8 +43,7 @@
import { createColumns } from './previousInstancesInfoColumns.jsx'; import { createColumns } from './previousInstancesInfoColumns.jsx';
import { database } from '../../../services/database'; import { database } from '../../../services/database';
import { useVrcxVueTable } from '../../../lib/table/useVrcxVueTable'; import { useVrcxVueTable } from '../../../lib/table/useVrcxVueTable';
import { lookupUser } from '../../../coordinators/userCoordinator'; import { lookupUser } from '../../../coordinators/userCoordinator';
const { previousInstancesInfoDialog, previousInstancesInfoState } = storeToRefs(useInstanceStore()); const { previousInstancesInfoDialog, previousInstancesInfoState } = storeToRefs(useInstanceStore());
const { gameLogIsFriend, gameLogIsFavorite } = useGameLogStore(); const { gameLogIsFriend, gameLogIsFavorite } = useGameLogStore();
@@ -142,9 +142,9 @@
const { userDialog, languageDialog, currentUser, isLocalUserVrcPlusSupporter } = storeToRefs(useUserStore()); const { userDialog, languageDialog, currentUser, isLocalUserVrcPlusSupporter } = storeToRefs(useUserStore());
const { cachedUsers, showSendBoopDialog } = useUserStore(); const { cachedUsers, showSendBoopDialog } = useUserStore();
const { showFavoriteDialog } = useFavoriteStore(); const { showFavoriteDialog } = useFavoriteStore();
import { showAvatarDialog, showAvatarAuthorDialog } from '../../../coordinators/avatarCoordinator'; import { showAvatarDialog, showAvatarAuthorDialog } from '../../../coordinators/avatarCoordinator';
import { showUserDialog, refreshUserDialogAvatars } from '../../../coordinators/userCoordinator'; import { showUserDialog, refreshUserDialogAvatars } from '../../../coordinators/userCoordinator';
import { getFriendRequest, handleFriendDelete } from '../../../coordinators/friendRelationshipCoordinator'; import { getFriendRequest, handleFriendDelete } from '../../../coordinators/friendRelationshipCoordinator';
const { showModerateGroupDialog } = useGroupStore(); const { showModerateGroupDialog } = useGroupStore();
const { inviteGroupDialog } = storeToRefs(useGroupStore()); const { inviteGroupDialog } = storeToRefs(useGroupStore());
@@ -85,7 +85,6 @@
const { userDialog, currentUser } = storeToRefs(useUserStore()); const { userDialog, currentUser } = storeToRefs(useUserStore());
const { favoriteLimits } = storeToRefs(useFavoriteStore()); const { favoriteLimits } = storeToRefs(useFavoriteStore());
const favoriteWorldsTab = ref('0'); const favoriteWorldsTab = ref('0');
const userDialogFavoriteWorldsRequestId = ref(0); const userDialogFavoriteWorldsRequestId = ref(0);
@@ -73,7 +73,7 @@
import { useUserStore } from '../../../stores'; import { useUserStore } from '../../../stores';
import { userDialogMutualFriendSortingOptions } from '../../../shared/constants'; import { userDialogMutualFriendSortingOptions } from '../../../shared/constants';
import { userRequest } from '../../../api'; import { userRequest } from '../../../api';
import { showUserDialog } from '../../../coordinators/userCoordinator'; import { showUserDialog } from '../../../coordinators/userCoordinator';
const { t } = useI18n(); const { t } = useI18n();
@@ -134,8 +134,6 @@
const emit = defineEmits(['update:isSetWorldTagsDialogVisible']); const emit = defineEmits(['update:isSetWorldTagsDialogVisible']);
const { t } = useI18n(); const { t } = useI18n();
const setWorldTagsDialog = ref({ const setWorldTagsDialog = ref({
@@ -9,12 +9,12 @@ import { database } from '../../../services/database';
/** /**
* Composable for WorldDialogInfoTab computed properties and actions. * Composable for WorldDialogInfoTab computed properties and actions.
*
* @param {import('vue').Ref} worldDialog - reactive ref to the world dialog state * @param {import('vue').Ref} worldDialog - reactive ref to the world dialog state
* @param {Object} deps - external dependencies * @param {object} deps - external dependencies
* @param {Function} deps.t - i18n translation function * @param {Function} deps.t - i18n translation function
* @param {Function} deps.toast - toast notification function * @param {Function} deps.toast - toast notification function
* @returns {Object} info composable API * @param deps.sdkUnityVersion
* @returns {object} info composable API
*/ */
export function useWorldDialogInfo(worldDialog, { t, toast, sdkUnityVersion }) { export function useWorldDialogInfo(worldDialog, { t, toast, sdkUnityVersion }) {
const memo = computed({ const memo = computed({
@@ -71,7 +71,12 @@ export function useWorldDialogInfo(worldDialog, { t, toast, sdkUnityVersion }) {
const platforms = []; const platforms = [];
if (ref.unityPackages) { if (ref.unityPackages) {
for (const unityPackage of ref.unityPackages) { for (const unityPackage of ref.unityPackages) {
if (!compareUnityVersion(unityPackage.unitySortNumber, sdkUnityVersion)) { if (
!compareUnityVersion(
unityPackage.unitySortNumber,
sdkUnityVersion
)
) {
continue; continue;
} }
let platform = 'PC'; let platform = 'PC';
@@ -1,12 +1,12 @@
<script setup> <script setup>
import { cn } from '@/lib/utils'; import { cn } from '@/lib/utils';
import { buttonGroupVariants } from '.'; import { buttonGroupVariants } from '.';
const props = defineProps({ const props = defineProps({
class: { type: null, required: false }, class: { type: null, required: false },
orientation: { type: null, required: false } orientation: { type: null, required: false }
}); });
</script> </script>
<template> <template>
@@ -1,16 +1,16 @@
<script setup> <script setup>
import { Separator } from '@/components/ui/separator'; import { Separator } from '@/components/ui/separator';
import { cn } from '@/lib/utils'; import { cn } from '@/lib/utils';
import { reactiveOmit } from '@vueuse/core'; import { reactiveOmit } from '@vueuse/core';
const props = defineProps({ const props = defineProps({
orientation: { type: String, required: false, default: 'vertical' }, orientation: { type: String, required: false, default: 'vertical' },
decorative: { type: Boolean, required: false }, decorative: { type: Boolean, required: false },
asChild: { type: Boolean, required: false }, asChild: { type: Boolean, required: false },
as: { type: null, required: false }, as: { type: null, required: false },
class: { type: null, required: false } class: { type: null, required: false }
}); });
const delegatedProps = reactiveOmit(props, 'class'); const delegatedProps = reactiveOmit(props, 'class');
</script> </script>
<template> <template>
@@ -1,13 +1,13 @@
<script setup> <script setup>
import { Primitive } from 'reka-ui'; import { Primitive } from 'reka-ui';
import { cn } from '@/lib/utils'; import { cn } from '@/lib/utils';
const props = defineProps({ const props = defineProps({
class: { type: null, required: false }, class: { type: null, required: false },
orientation: { type: null, required: false }, orientation: { type: null, required: false },
asChild: { type: Boolean, required: false }, asChild: { type: Boolean, required: false },
as: { type: null, required: false, default: 'div' } as: { type: null, required: false, default: 'div' }
}); });
</script> </script>
<template> <template>
+7 -7
View File
@@ -1,7 +1,7 @@
export { default as Card } from "./Card.vue"; export { default as Card } from './Card.vue';
export { default as CardAction } from "./CardAction.vue"; export { default as CardAction } from './CardAction.vue';
export { default as CardContent } from "./CardContent.vue"; export { default as CardContent } from './CardContent.vue';
export { default as CardDescription } from "./CardDescription.vue"; export { default as CardDescription } from './CardDescription.vue';
export { default as CardFooter } from "./CardFooter.vue"; export { default as CardFooter } from './CardFooter.vue';
export { default as CardHeader } from "./CardHeader.vue"; export { default as CardHeader } from './CardHeader.vue';
export { default as CardTitle } from "./CardTitle.vue"; export { default as CardTitle } from './CardTitle.vue';
+3 -3
View File
@@ -1,3 +1,3 @@
export { default as Collapsible } from "./Collapsible.vue"; export { default as Collapsible } from './Collapsible.vue';
export { default as CollapsibleContent } from "./CollapsibleContent.vue"; export { default as CollapsibleContent } from './CollapsibleContent.vue';
export { default as CollapsibleTrigger } from "./CollapsibleTrigger.vue"; export { default as CollapsibleTrigger } from './CollapsibleTrigger.vue';
@@ -1,14 +1,14 @@
<script setup> <script setup>
import { ContextMenuRoot, useForwardPropsEmits } from "reka-ui"; import { ContextMenuRoot, useForwardPropsEmits } from 'reka-ui';
const props = defineProps({ const props = defineProps({
pressOpenDelay: { type: Number, required: false }, pressOpenDelay: { type: Number, required: false },
dir: { type: String, required: false }, dir: { type: String, required: false },
modal: { type: Boolean, required: false }, modal: { type: Boolean, required: false }
}); });
const emits = defineEmits(["update:open"]); const emits = defineEmits(['update:open']);
const forwarded = useForwardPropsEmits(props, emits); const forwarded = useForwardPropsEmits(props, emits);
</script> </script>
<template> <template>
@@ -1,26 +1,22 @@
<script setup> <script setup>
import { reactiveOmit } from "@vueuse/core"; import { reactiveOmit } from '@vueuse/core';
import { Check } from "lucide-vue-next"; import { Check } from 'lucide-vue-next';
import { import { ContextMenuCheckboxItem, ContextMenuItemIndicator, useForwardPropsEmits } from 'reka-ui';
ContextMenuCheckboxItem, import { cn } from '@/lib/utils';
ContextMenuItemIndicator,
useForwardPropsEmits,
} from "reka-ui";
import { cn } from "@/lib/utils";
const props = defineProps({ const props = defineProps({
modelValue: { type: [Boolean, String], required: false }, modelValue: { type: [Boolean, String], required: false },
disabled: { type: Boolean, required: false }, disabled: { type: Boolean, required: false },
textValue: { type: String, required: false }, textValue: { type: String, required: false },
asChild: { type: Boolean, required: false }, asChild: { type: Boolean, required: false },
as: { type: null, required: false }, as: { type: null, required: false },
class: { type: null, required: false }, class: { type: null, required: false }
}); });
const emits = defineEmits(["select", "update:modelValue"]); const emits = defineEmits(['select', 'update:modelValue']);
const delegatedProps = reactiveOmit(props, "class"); const delegatedProps = reactiveOmit(props, 'class');
const forwarded = useForwardPropsEmits(delegatedProps, emits); const forwarded = useForwardPropsEmits(delegatedProps, emits);
</script> </script>
<template> <template>
@@ -30,13 +26,10 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits);
:class=" :class="
cn( cn(
'focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=\'size-\'])]:size-4', 'focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=\'size-\'])]:size-4',
props.class, props.class
) )
" ">
> <span class="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
<span
class="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center"
>
<ContextMenuItemIndicator> <ContextMenuItemIndicator>
<slot name="indicator-icon"> <slot name="indicator-icon">
<Check class="size-4" /> <Check class="size-4" />
@@ -1,17 +1,13 @@
<script setup> <script setup>
import { reactiveOmit } from "@vueuse/core"; import { reactiveOmit } from '@vueuse/core';
import { import { ContextMenuContent, ContextMenuPortal, useForwardPropsEmits } from 'reka-ui';
ContextMenuContent, import { cn } from '@/lib/utils';
ContextMenuPortal,
useForwardPropsEmits,
} from "reka-ui";
import { cn } from "@/lib/utils";
defineOptions({ defineOptions({
inheritAttrs: false, inheritAttrs: false
}); });
const props = defineProps({ const props = defineProps({
forceMount: { type: Boolean, required: false }, forceMount: { type: Boolean, required: false },
loop: { type: Boolean, required: false }, loop: { type: Boolean, required: false },
sideFlip: { type: Boolean, required: false }, sideFlip: { type: Boolean, required: false },
@@ -29,19 +25,19 @@ const props = defineProps({
reference: { type: null, required: false }, reference: { type: null, required: false },
asChild: { type: Boolean, required: false }, asChild: { type: Boolean, required: false },
as: { type: null, required: false }, as: { type: null, required: false },
class: { type: null, required: false }, class: { type: null, required: false }
}); });
const emits = defineEmits([ const emits = defineEmits([
"escapeKeyDown", 'escapeKeyDown',
"pointerDownOutside", 'pointerDownOutside',
"focusOutside", 'focusOutside',
"interactOutside", 'interactOutside',
"closeAutoFocus", 'closeAutoFocus'
]); ]);
const delegatedProps = reactiveOmit(props, "class"); const delegatedProps = reactiveOmit(props, 'class');
const forwarded = useForwardPropsEmits(delegatedProps, emits); const forwarded = useForwardPropsEmits(delegatedProps, emits);
</script> </script>
<template> <template>
@@ -52,10 +48,9 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits);
:class=" :class="
cn( cn(
'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--reka-context-menu-content-available-height) min-w-[8rem] overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md', 'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--reka-context-menu-content-available-height) min-w-[8rem] overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md',
props.class, props.class
) )
" ">
>
<slot /> <slot />
</ContextMenuContent> </ContextMenuContent>
</ContextMenuPortal> </ContextMenuPortal>
@@ -1,10 +1,10 @@
<script setup> <script setup>
import { ContextMenuGroup } from "reka-ui"; import { ContextMenuGroup } from 'reka-ui';
const props = defineProps({ const props = defineProps({
asChild: { type: Boolean, required: false }, asChild: { type: Boolean, required: false },
as: { type: null, required: false }, as: { type: null, required: false }
}); });
</script> </script>
<template> <template>
@@ -1,22 +1,22 @@
<script setup> <script setup>
import { reactiveOmit } from "@vueuse/core"; import { reactiveOmit } from '@vueuse/core';
import { ContextMenuItem, useForwardPropsEmits } from "reka-ui"; import { ContextMenuItem, useForwardPropsEmits } from 'reka-ui';
import { cn } from "@/lib/utils"; import { cn } from '@/lib/utils';
const props = defineProps({ const props = defineProps({
disabled: { type: Boolean, required: false }, disabled: { type: Boolean, required: false },
textValue: { type: String, required: false }, textValue: { type: String, required: false },
asChild: { type: Boolean, required: false }, asChild: { type: Boolean, required: false },
as: { type: null, required: false }, as: { type: null, required: false },
class: { type: null, required: false }, class: { type: null, required: false },
inset: { type: Boolean, required: false }, inset: { type: Boolean, required: false },
variant: { type: String, required: false, default: "default" }, variant: { type: String, required: false, default: 'default' }
}); });
const emits = defineEmits(["select"]); const emits = defineEmits(['select']);
const delegatedProps = reactiveOmit(props, "class"); const delegatedProps = reactiveOmit(props, 'class');
const forwarded = useForwardPropsEmits(delegatedProps, emits); const forwarded = useForwardPropsEmits(delegatedProps, emits);
</script> </script>
<template> <template>
@@ -28,10 +28,9 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits);
:class=" :class="
cn( cn(
'focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive-foreground data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/40 data-[variant=destructive]:focus:text-destructive-foreground data-[variant=destructive]:*:[svg]:!text-destructive-foreground [&_svg:not([class*=\'text-\'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=\'size-\'])]:size-4', 'focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive-foreground data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/40 data-[variant=destructive]:focus:text-destructive-foreground data-[variant=destructive]:*:[svg]:!text-destructive-foreground [&_svg:not([class*=\'text-\'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=\'size-\'])]:size-4',
props.class, props.class
) )
" ">
>
<slot /> <slot />
</ContextMenuItem> </ContextMenuItem>
</template> </template>
@@ -1,16 +1,16 @@
<script setup> <script setup>
import { reactiveOmit } from "@vueuse/core"; import { reactiveOmit } from '@vueuse/core';
import { ContextMenuLabel } from "reka-ui"; import { ContextMenuLabel } from 'reka-ui';
import { cn } from "@/lib/utils"; import { cn } from '@/lib/utils';
const props = defineProps({ const props = defineProps({
asChild: { type: Boolean, required: false }, asChild: { type: Boolean, required: false },
as: { type: null, required: false }, as: { type: null, required: false },
class: { type: null, required: false }, class: { type: null, required: false },
inset: { type: Boolean, required: false }, inset: { type: Boolean, required: false }
}); });
const delegatedProps = reactiveOmit(props, "class"); const delegatedProps = reactiveOmit(props, 'class');
</script> </script>
<template> <template>
@@ -18,13 +18,7 @@ const delegatedProps = reactiveOmit(props, "class");
data-slot="context-menu-label" data-slot="context-menu-label"
:data-inset="inset ? '' : undefined" :data-inset="inset ? '' : undefined"
v-bind="delegatedProps" v-bind="delegatedProps"
:class=" :class="cn('text-foreground px-2 py-1.5 text-sm font-medium data-[inset]:pl-8', props.class)">
cn(
'text-foreground px-2 py-1.5 text-sm font-medium data-[inset]:pl-8',
props.class,
)
"
>
<slot /> <slot />
</ContextMenuLabel> </ContextMenuLabel>
</template> </template>
@@ -1,12 +1,12 @@
<script setup> <script setup>
import { ContextMenuPortal } from "reka-ui"; import { ContextMenuPortal } from 'reka-ui';
const props = defineProps({ const props = defineProps({
to: { type: null, required: false }, to: { type: null, required: false },
disabled: { type: Boolean, required: false }, disabled: { type: Boolean, required: false },
defer: { type: Boolean, required: false }, defer: { type: Boolean, required: false },
forceMount: { type: Boolean, required: false }, forceMount: { type: Boolean, required: false }
}); });
</script> </script>
<template> <template>
@@ -1,21 +1,18 @@
<script setup> <script setup>
import { ContextMenuRadioGroup, useForwardPropsEmits } from "reka-ui"; import { ContextMenuRadioGroup, useForwardPropsEmits } from 'reka-ui';
const props = defineProps({ const props = defineProps({
modelValue: { type: null, required: false }, modelValue: { type: null, required: false },
asChild: { type: Boolean, required: false }, asChild: { type: Boolean, required: false },
as: { type: null, required: false }, as: { type: null, required: false }
}); });
const emits = defineEmits(["update:modelValue"]); const emits = defineEmits(['update:modelValue']);
const forwarded = useForwardPropsEmits(props, emits); const forwarded = useForwardPropsEmits(props, emits);
</script> </script>
<template> <template>
<ContextMenuRadioGroup <ContextMenuRadioGroup data-slot="context-menu-radio-group" v-bind="forwarded">
data-slot="context-menu-radio-group"
v-bind="forwarded"
>
<slot /> <slot />
</ContextMenuRadioGroup> </ContextMenuRadioGroup>
</template> </template>
@@ -1,26 +1,22 @@
<script setup> <script setup>
import { reactiveOmit } from "@vueuse/core"; import { reactiveOmit } from '@vueuse/core';
import { Circle } from "lucide-vue-next"; import { Circle } from 'lucide-vue-next';
import { import { ContextMenuItemIndicator, ContextMenuRadioItem, useForwardPropsEmits } from 'reka-ui';
ContextMenuItemIndicator, import { cn } from '@/lib/utils';
ContextMenuRadioItem,
useForwardPropsEmits,
} from "reka-ui";
import { cn } from "@/lib/utils";
const props = defineProps({ const props = defineProps({
value: { type: null, required: true }, value: { type: null, required: true },
disabled: { type: Boolean, required: false }, disabled: { type: Boolean, required: false },
textValue: { type: String, required: false }, textValue: { type: String, required: false },
asChild: { type: Boolean, required: false }, asChild: { type: Boolean, required: false },
as: { type: null, required: false }, as: { type: null, required: false },
class: { type: null, required: false }, class: { type: null, required: false }
}); });
const emits = defineEmits(["select"]); const emits = defineEmits(['select']);
const delegatedProps = reactiveOmit(props, "class"); const delegatedProps = reactiveOmit(props, 'class');
const forwarded = useForwardPropsEmits(delegatedProps, emits); const forwarded = useForwardPropsEmits(delegatedProps, emits);
</script> </script>
<template> <template>
@@ -30,13 +26,10 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits);
:class=" :class="
cn( cn(
'focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=\'size-\'])]:size-4', 'focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=\'size-\'])]:size-4',
props.class, props.class
) )
" ">
> <span class="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
<span
class="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center"
>
<ContextMenuItemIndicator> <ContextMenuItemIndicator>
<slot name="indicator-icon"> <slot name="indicator-icon">
<Circle class="size-2 fill-current" /> <Circle class="size-2 fill-current" />
@@ -1,21 +1,20 @@
<script setup> <script setup>
import { reactiveOmit } from "@vueuse/core"; import { reactiveOmit } from '@vueuse/core';
import { ContextMenuSeparator } from "reka-ui"; import { ContextMenuSeparator } from 'reka-ui';
import { cn } from "@/lib/utils"; import { cn } from '@/lib/utils';
const props = defineProps({ const props = defineProps({
asChild: { type: Boolean, required: false }, asChild: { type: Boolean, required: false },
as: { type: null, required: false }, as: { type: null, required: false },
class: { type: null, required: false }, class: { type: null, required: false }
}); });
const delegatedProps = reactiveOmit(props, "class"); const delegatedProps = reactiveOmit(props, 'class');
</script> </script>
<template> <template>
<ContextMenuSeparator <ContextMenuSeparator
data-slot="context-menu-separator" data-slot="context-menu-separator"
v-bind="delegatedProps" v-bind="delegatedProps"
:class="cn('bg-border -mx-1 my-1 h-px', props.class)" :class="cn('bg-border -mx-1 my-1 h-px', props.class)" />
/>
</template> </template>
@@ -1,18 +1,15 @@
<script setup> <script setup>
import { cn } from "@/lib/utils"; import { cn } from '@/lib/utils';
const props = defineProps({ const props = defineProps({
class: { type: null, required: false }, class: { type: null, required: false }
}); });
</script> </script>
<template> <template>
<span <span
data-slot="context-menu-shortcut" data-slot="context-menu-shortcut"
:class=" :class="cn('text-muted-foreground ml-auto text-xs tracking-widest', props.class)">
cn('text-muted-foreground ml-auto text-xs tracking-widest', props.class)
"
>
<slot /> <slot />
</span> </span>
</template> </template>
@@ -1,13 +1,13 @@
<script setup> <script setup>
import { ContextMenuSub, useForwardPropsEmits } from "reka-ui"; import { ContextMenuSub, useForwardPropsEmits } from 'reka-ui';
const props = defineProps({ const props = defineProps({
defaultOpen: { type: Boolean, required: false }, defaultOpen: { type: Boolean, required: false },
open: { type: Boolean, required: false }, open: { type: Boolean, required: false }
}); });
const emits = defineEmits(["update:open"]); const emits = defineEmits(['update:open']);
const forwarded = useForwardPropsEmits(props, emits); const forwarded = useForwardPropsEmits(props, emits);
</script> </script>
<template> <template>
@@ -1,9 +1,9 @@
<script setup> <script setup>
import { reactiveOmit } from "@vueuse/core"; import { reactiveOmit } from '@vueuse/core';
import { ContextMenuSubContent, useForwardPropsEmits } from "reka-ui"; import { ContextMenuSubContent, useForwardPropsEmits } from 'reka-ui';
import { cn } from "@/lib/utils"; import { cn } from '@/lib/utils';
const props = defineProps({ const props = defineProps({
forceMount: { type: Boolean, required: false }, forceMount: { type: Boolean, required: false },
loop: { type: Boolean, required: false }, loop: { type: Boolean, required: false },
sideOffset: { type: Number, required: false }, sideOffset: { type: Number, required: false },
@@ -24,21 +24,21 @@ const props = defineProps({
reference: { type: null, required: false }, reference: { type: null, required: false },
asChild: { type: Boolean, required: false }, asChild: { type: Boolean, required: false },
as: { type: null, required: false }, as: { type: null, required: false },
class: { type: null, required: false }, class: { type: null, required: false }
}); });
const emits = defineEmits([ const emits = defineEmits([
"escapeKeyDown", 'escapeKeyDown',
"pointerDownOutside", 'pointerDownOutside',
"focusOutside", 'focusOutside',
"interactOutside", 'interactOutside',
"entryFocus", 'entryFocus',
"openAutoFocus", 'openAutoFocus',
"closeAutoFocus", 'closeAutoFocus'
]); ]);
const delegatedProps = reactiveOmit(props, "class"); const delegatedProps = reactiveOmit(props, 'class');
const forwarded = useForwardPropsEmits(delegatedProps, emits); const forwarded = useForwardPropsEmits(delegatedProps, emits);
</script> </script>
<template> <template>
@@ -48,10 +48,9 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits);
:class=" :class="
cn( cn(
'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--reka-context-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg', 'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--reka-context-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg',
props.class, props.class
) )
" ">
>
<slot /> <slot />
</ContextMenuSubContent> </ContextMenuSubContent>
</template> </template>
@@ -1,21 +1,21 @@
<script setup> <script setup>
import { reactiveOmit } from "@vueuse/core"; import { reactiveOmit } from '@vueuse/core';
import { ChevronRight } from "lucide-vue-next"; import { ChevronRight } from 'lucide-vue-next';
import { ContextMenuSubTrigger, useForwardProps } from "reka-ui"; import { ContextMenuSubTrigger, useForwardProps } from 'reka-ui';
import { cn } from "@/lib/utils"; import { cn } from '@/lib/utils';
const props = defineProps({ const props = defineProps({
disabled: { type: Boolean, required: false }, disabled: { type: Boolean, required: false },
textValue: { type: String, required: false }, textValue: { type: String, required: false },
asChild: { type: Boolean, required: false }, asChild: { type: Boolean, required: false },
as: { type: null, required: false }, as: { type: null, required: false },
class: { type: null, required: false }, class: { type: null, required: false },
inset: { type: Boolean, required: false }, inset: { type: Boolean, required: false }
}); });
const delegatedProps = reactiveOmit(props, "class"); const delegatedProps = reactiveOmit(props, 'class');
const forwardedProps = useForwardProps(delegatedProps); const forwardedProps = useForwardProps(delegatedProps);
</script> </script>
<template> <template>
@@ -26,10 +26,9 @@ const forwardedProps = useForwardProps(delegatedProps);
:class=" :class="
cn( cn(
'focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=\'size-\'])]:size-4', 'focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=\'size-\'])]:size-4',
props.class, props.class
) )
" ">
>
<slot /> <slot />
<ChevronRight class="ml-auto" /> <ChevronRight class="ml-auto" />
</ContextMenuSubTrigger> </ContextMenuSubTrigger>
@@ -1,13 +1,13 @@
<script setup> <script setup>
import { ContextMenuTrigger, useForwardProps } from "reka-ui"; import { ContextMenuTrigger, useForwardProps } from 'reka-ui';
const props = defineProps({ const props = defineProps({
disabled: { type: Boolean, required: false }, disabled: { type: Boolean, required: false },
asChild: { type: Boolean, required: false }, asChild: { type: Boolean, required: false },
as: { type: null, required: false }, as: { type: null, required: false }
}); });
const forwardedProps = useForwardProps(props); const forwardedProps = useForwardProps(props);
</script> </script>
<template> <template>
+14 -14
View File
@@ -1,14 +1,14 @@
export { default as ContextMenu } from "./ContextMenu.vue"; export { default as ContextMenu } from './ContextMenu.vue';
export { default as ContextMenuCheckboxItem } from "./ContextMenuCheckboxItem.vue"; export { default as ContextMenuCheckboxItem } from './ContextMenuCheckboxItem.vue';
export { default as ContextMenuContent } from "./ContextMenuContent.vue"; export { default as ContextMenuContent } from './ContextMenuContent.vue';
export { default as ContextMenuGroup } from "./ContextMenuGroup.vue"; export { default as ContextMenuGroup } from './ContextMenuGroup.vue';
export { default as ContextMenuItem } from "./ContextMenuItem.vue"; export { default as ContextMenuItem } from './ContextMenuItem.vue';
export { default as ContextMenuLabel } from "./ContextMenuLabel.vue"; export { default as ContextMenuLabel } from './ContextMenuLabel.vue';
export { default as ContextMenuRadioGroup } from "./ContextMenuRadioGroup.vue"; export { default as ContextMenuRadioGroup } from './ContextMenuRadioGroup.vue';
export { default as ContextMenuRadioItem } from "./ContextMenuRadioItem.vue"; export { default as ContextMenuRadioItem } from './ContextMenuRadioItem.vue';
export { default as ContextMenuSeparator } from "./ContextMenuSeparator.vue"; export { default as ContextMenuSeparator } from './ContextMenuSeparator.vue';
export { default as ContextMenuShortcut } from "./ContextMenuShortcut.vue"; export { default as ContextMenuShortcut } from './ContextMenuShortcut.vue';
export { default as ContextMenuSub } from "./ContextMenuSub.vue"; export { default as ContextMenuSub } from './ContextMenuSub.vue';
export { default as ContextMenuSubContent } from "./ContextMenuSubContent.vue"; export { default as ContextMenuSubContent } from './ContextMenuSubContent.vue';
export { default as ContextMenuSubTrigger } from "./ContextMenuSubTrigger.vue"; export { default as ContextMenuSubTrigger } from './ContextMenuSubTrigger.vue';
export { default as ContextMenuTrigger } from "./ContextMenuTrigger.vue"; export { default as ContextMenuTrigger } from './ContextMenuTrigger.vue';
+1 -1
View File
@@ -1 +1 @@
export { default as Input } from "./Input.vue"; export { default as Input } from './Input.vue';
+8 -13
View File
@@ -1,24 +1,19 @@
<script setup> <script setup>
import { Primitive } from "reka-ui"; import { Primitive } from 'reka-ui';
import { cn } from "@/lib/utils"; import { cn } from '@/lib/utils';
import { itemVariants } from "."; import { itemVariants } from '.';
const props = defineProps({ const props = defineProps({
asChild: { type: Boolean, required: false }, asChild: { type: Boolean, required: false },
as: { type: null, required: false, default: "div" }, as: { type: null, required: false, default: 'div' },
class: { type: null, required: false }, class: { type: null, required: false },
variant: { type: null, required: false }, variant: { type: null, required: false },
size: { type: null, required: false }, size: { type: null, required: false }
}); });
</script> </script>
<template> <template>
<Primitive <Primitive data-slot="item" :as="as" :as-child="asChild" :class="cn(itemVariants({ variant, size }), props.class)">
data-slot="item"
:as="as"
:as-child="asChild"
:class="cn(itemVariants({ variant, size }), props.class)"
>
<slot /> <slot />
</Primitive> </Primitive>
</template> </template>
+5 -8
View File
@@ -1,16 +1,13 @@
<script setup> <script setup>
import { cn } from "@/lib/utils"; import { cn } from '@/lib/utils';
const props = defineProps({ const props = defineProps({
class: { type: null, required: false }, class: { type: null, required: false }
}); });
</script> </script>
<template> <template>
<div <div data-slot="item-actions" :class="cn('flex items-center gap-2', props.class)">
data-slot="item-actions"
:class="cn('flex items-center gap-2', props.class)"
>
<slot /> <slot />
</div> </div>
</template> </template>
+5 -11
View File
@@ -1,21 +1,15 @@
<script setup> <script setup>
import { cn } from "@/lib/utils"; import { cn } from '@/lib/utils';
const props = defineProps({ const props = defineProps({
class: { type: null, required: false }, class: { type: null, required: false }
}); });
</script> </script>
<template> <template>
<div <div
data-slot="item-content" data-slot="item-content"
:class=" :class="cn('flex flex-1 flex-col gap-1 [&+[data-slot=item-content]]:flex-none', props.class)">
cn(
'flex flex-1 flex-col gap-1 [&+[data-slot=item-content]]:flex-none',
props.class,
)
"
>
<slot /> <slot />
</div> </div>
</template> </template>
+6 -7
View File
@@ -1,9 +1,9 @@
<script setup> <script setup>
import { cn } from "@/lib/utils"; import { cn } from '@/lib/utils';
const props = defineProps({ const props = defineProps({
class: { type: null, required: false }, class: { type: null, required: false }
}); });
</script> </script>
<template> <template>
@@ -13,10 +13,9 @@ const props = defineProps({
cn( cn(
'text-muted-foreground line-clamp-2 text-sm leading-normal font-normal text-balance', 'text-muted-foreground line-clamp-2 text-sm leading-normal font-normal text-balance',
'[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4', '[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4',
props.class, props.class
) )
" ">
>
<slot /> <slot />
</p> </p>
</template> </template>
+5 -10
View File
@@ -1,18 +1,13 @@
<script setup> <script setup>
import { cn } from "@/lib/utils"; import { cn } from '@/lib/utils';
const props = defineProps({ const props = defineProps({
class: { type: null, required: false }, class: { type: null, required: false }
}); });
</script> </script>
<template> <template>
<div <div data-slot="item-footer" :class="cn('flex basis-full items-center justify-between gap-2', props.class)">
data-slot="item-footer"
:class="
cn('flex basis-full items-center justify-between gap-2', props.class)
"
>
<slot /> <slot />
</div> </div>
</template> </template>
+5 -9
View File
@@ -1,17 +1,13 @@
<script setup> <script setup>
import { cn } from "@/lib/utils"; import { cn } from '@/lib/utils';
const props = defineProps({ const props = defineProps({
class: { type: null, required: false }, class: { type: null, required: false }
}); });
</script> </script>
<template> <template>
<div <div role="list" data-slot="item-group" :class="cn('group/item-group flex flex-col', props.class)">
role="list"
data-slot="item-group"
:class="cn('group/item-group flex flex-col', props.class)"
>
<slot /> <slot />
</div> </div>
</template> </template>
+5 -10
View File
@@ -1,18 +1,13 @@
<script setup> <script setup>
import { cn } from "@/lib/utils"; import { cn } from '@/lib/utils';
const props = defineProps({ const props = defineProps({
class: { type: null, required: false }, class: { type: null, required: false }
}); });
</script> </script>
<template> <template>
<div <div data-slot="item-header" :class="cn('flex basis-full items-center justify-between gap-2', props.class)">
data-slot="item-header"
:class="
cn('flex basis-full items-center justify-between gap-2', props.class)
"
>
<slot /> <slot />
</div> </div>
</template> </template>
+6 -10
View File
@@ -1,19 +1,15 @@
<script setup> <script setup>
import { cn } from "@/lib/utils"; import { cn } from '@/lib/utils';
import { itemMediaVariants } from "."; import { itemMediaVariants } from '.';
const props = defineProps({ const props = defineProps({
class: { type: null, required: false }, class: { type: null, required: false },
variant: { type: null, required: false }, variant: { type: null, required: false }
}); });
</script> </script>
<template> <template>
<div <div data-slot="item-media" :data-variant="props.variant" :class="cn(itemMediaVariants({ variant }), props.class)">
data-slot="item-media"
:data-variant="props.variant"
:class="cn(itemMediaVariants({ variant }), props.class)"
>
<slot /> <slot />
</div> </div>
</template> </template>
+6 -10
View File
@@ -1,20 +1,16 @@
<script setup> <script setup>
import { cn } from "@/lib/utils"; import { cn } from '@/lib/utils';
import { Separator } from '@/components/ui/separator'; import { Separator } from '@/components/ui/separator';
const props = defineProps({ const props = defineProps({
orientation: { type: String, required: false }, orientation: { type: String, required: false },
decorative: { type: Boolean, required: false }, decorative: { type: Boolean, required: false },
asChild: { type: Boolean, required: false }, asChild: { type: Boolean, required: false },
as: { type: null, required: false }, as: { type: null, required: false },
class: { type: null, required: false }, class: { type: null, required: false }
}); });
</script> </script>
<template> <template>
<Separator <Separator data-slot="item-separator" orientation="horizontal" :class="cn('my-0', props.class)" />
data-slot="item-separator"
orientation="horizontal"
:class="cn('my-0', props.class)"
/>
</template> </template>
+5 -11
View File
@@ -1,21 +1,15 @@
<script setup> <script setup>
import { cn } from "@/lib/utils"; import { cn } from '@/lib/utils';
const props = defineProps({ const props = defineProps({
class: { type: null, required: false }, class: { type: null, required: false }
}); });
</script> </script>
<template> <template>
<div <div
data-slot="item-title" data-slot="item-title"
:class=" :class="cn('flex w-fit items-center gap-2 text-sm leading-snug font-medium', props.class)">
cn(
'flex w-fit items-center gap-2 text-sm leading-snug font-medium',
props.class,
)
"
>
<slot /> <slot />
</div> </div>
</template> </template>
+29 -30
View File
@@ -1,50 +1,49 @@
import { cva } from "class-variance-authority"; import { cva } from 'class-variance-authority';
export { default as Item } from "./Item.vue"; export { default as Item } from './Item.vue';
export { default as ItemActions } from "./ItemActions.vue"; export { default as ItemActions } from './ItemActions.vue';
export { default as ItemContent } from "./ItemContent.vue"; export { default as ItemContent } from './ItemContent.vue';
export { default as ItemDescription } from "./ItemDescription.vue"; export { default as ItemDescription } from './ItemDescription.vue';
export { default as ItemFooter } from "./ItemFooter.vue"; export { default as ItemFooter } from './ItemFooter.vue';
export { default as ItemGroup } from "./ItemGroup.vue"; export { default as ItemGroup } from './ItemGroup.vue';
export { default as ItemHeader } from "./ItemHeader.vue"; export { default as ItemHeader } from './ItemHeader.vue';
export { default as ItemMedia } from "./ItemMedia.vue"; export { default as ItemMedia } from './ItemMedia.vue';
export { default as ItemSeparator } from "./ItemSeparator.vue"; export { default as ItemSeparator } from './ItemSeparator.vue';
export { default as ItemTitle } from "./ItemTitle.vue"; export { default as ItemTitle } from './ItemTitle.vue';
export const itemVariants = cva( export const itemVariants = cva(
"group/item flex items-center border border-transparent text-sm rounded-md transition-colors [a]:hover:bg-accent/50 [a]:transition-colors duration-100 flex-wrap outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]", 'group/item flex items-center border border-transparent text-sm rounded-md transition-colors [a]:hover:bg-accent/50 [a]:transition-colors duration-100 flex-wrap outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]',
{ {
variants: { variants: {
variant: { variant: {
default: "bg-transparent", default: 'bg-transparent',
outline: "border-border", outline: 'border-border',
muted: "bg-muted/50", muted: 'bg-muted/50'
}, },
size: { size: {
default: "p-4 gap-4 ", default: 'p-4 gap-4 ',
sm: "py-3 px-4 gap-2.5", sm: 'py-3 px-4 gap-2.5'
}, }
}, },
defaultVariants: { defaultVariants: {
variant: "default", variant: 'default',
size: "default", size: 'default'
}, }
}, }
); );
export const itemMediaVariants = cva( export const itemMediaVariants = cva(
"flex shrink-0 items-center justify-center gap-2 group-has-[[data-slot=item-description]]/item:self-start [&_svg]:pointer-events-none group-has-[[data-slot=item-description]]/item:translate-y-0.5", 'flex shrink-0 items-center justify-center gap-2 group-has-[[data-slot=item-description]]/item:self-start [&_svg]:pointer-events-none group-has-[[data-slot=item-description]]/item:translate-y-0.5',
{ {
variants: { variants: {
variant: { variant: {
default: "bg-transparent", default: 'bg-transparent',
icon: "size-8 border rounded-sm bg-muted [&_svg:not([class*='size-'])]:size-4", icon: "size-8 border rounded-sm bg-muted [&_svg:not([class*='size-'])]:size-4",
image: image: 'size-10 rounded-sm overflow-hidden [&_img]:size-full [&_img]:object-cover'
"size-10 rounded-sm overflow-hidden [&_img]:size-full [&_img]:object-cover", }
},
}, },
defaultVariants: { defaultVariants: {
variant: "default", variant: 'default'
}, }
}, }
); );
+13 -19
View File
@@ -1,17 +1,17 @@
<script setup> <script setup>
import { reactiveOmit } from "@vueuse/core"; import { reactiveOmit } from '@vueuse/core';
import { ScrollAreaScrollbar, ScrollAreaThumb } from "reka-ui"; import { ScrollAreaScrollbar, ScrollAreaThumb } from 'reka-ui';
import { cn } from "@/lib/utils"; import { cn } from '@/lib/utils';
const props = defineProps({ const props = defineProps({
orientation: { type: String, required: false, default: "vertical" }, orientation: { type: String, required: false, default: 'vertical' },
forceMount: { type: Boolean, required: false }, forceMount: { type: Boolean, required: false },
asChild: { type: Boolean, required: false }, asChild: { type: Boolean, required: false },
as: { type: null, required: false }, as: { type: null, required: false },
class: { type: null, required: false }, class: { type: null, required: false }
}); });
const delegatedProps = reactiveOmit(props, "class"); const delegatedProps = reactiveOmit(props, 'class');
</script> </script>
<template> <template>
@@ -21,17 +21,11 @@ const delegatedProps = reactiveOmit(props, "class");
:class=" :class="
cn( cn(
'flex touch-none p-px transition-colors select-none', 'flex touch-none p-px transition-colors select-none',
orientation === 'vertical' && orientation === 'vertical' && 'h-full w-2.5 border-l border-l-transparent',
'h-full w-2.5 border-l border-l-transparent', orientation === 'horizontal' && 'h-2.5 flex-col border-t border-t-transparent',
orientation === 'horizontal' && props.class
'h-2.5 flex-col border-t border-t-transparent',
props.class,
) )
" ">
> <ScrollAreaThumb data-slot="scroll-area-thumb" class="bg-border relative flex-1 rounded-full" />
<ScrollAreaThumb
data-slot="scroll-area-thumb"
class="bg-border relative flex-1 rounded-full"
/>
</ScrollAreaScrollbar> </ScrollAreaScrollbar>
</template> </template>
+2 -2
View File
@@ -1,2 +1,2 @@
export { default as ScrollArea } from "./ScrollArea.vue"; export { default as ScrollArea } from './ScrollArea.vue';
export { default as ScrollBar } from "./ScrollBar.vue"; export { default as ScrollBar } from './ScrollBar.vue';
+4 -4
View File
@@ -1,10 +1,10 @@
<script setup> <script setup>
import { SelectGroup } from "reka-ui"; import { SelectGroup } from 'reka-ui';
const props = defineProps({ const props = defineProps({
asChild: { type: Boolean, required: false }, asChild: { type: Boolean, required: false },
as: { type: null, required: false }, as: { type: null, required: false }
}); });
</script> </script>
<template> <template>
+11 -17
View File
@@ -1,26 +1,21 @@
<script setup> <script setup>
import { reactiveOmit } from "@vueuse/core"; import { reactiveOmit } from '@vueuse/core';
import { Check } from "lucide-vue-next"; import { Check } from 'lucide-vue-next';
import { import { SelectItem, SelectItemIndicator, SelectItemText, useForwardProps } from 'reka-ui';
SelectItem, import { cn } from '@/lib/utils';
SelectItemIndicator,
SelectItemText,
useForwardProps,
} from "reka-ui";
import { cn } from "@/lib/utils";
const props = defineProps({ const props = defineProps({
value: { type: null, required: true }, value: { type: null, required: true },
disabled: { type: Boolean, required: false }, disabled: { type: Boolean, required: false },
textValue: { type: String, required: false }, textValue: { type: String, required: false },
asChild: { type: Boolean, required: false }, asChild: { type: Boolean, required: false },
as: { type: null, required: false }, as: { type: null, required: false },
class: { type: null, required: false }, class: { type: null, required: false }
}); });
const delegatedProps = reactiveOmit(props, "class"); const delegatedProps = reactiveOmit(props, 'class');
const forwardedProps = useForwardProps(delegatedProps); const forwardedProps = useForwardProps(delegatedProps);
</script> </script>
<template> <template>
@@ -30,10 +25,9 @@ const forwardedProps = useForwardProps(delegatedProps);
:class=" :class="
cn( cn(
'focus:bg-accent focus:text-accent-foreground [&_svg:not([class*=\'text-\'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=\'size-\'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2', 'focus:bg-accent focus:text-accent-foreground [&_svg:not([class*=\'text-\'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=\'size-\'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2',
props.class, props.class
) )
" ">
>
<span class="absolute right-2 flex size-3.5 items-center justify-center"> <span class="absolute right-2 flex size-3.5 items-center justify-center">
<SelectItemIndicator> <SelectItemIndicator>
<slot name="indicator-icon"> <slot name="indicator-icon">
+4 -4
View File
@@ -1,10 +1,10 @@
<script setup> <script setup>
import { SelectItemText } from "reka-ui"; import { SelectItemText } from 'reka-ui';
const props = defineProps({ const props = defineProps({
asChild: { type: Boolean, required: false }, asChild: { type: Boolean, required: false },
as: { type: null, required: false }, as: { type: null, required: false }
}); });
</script> </script>
<template> <template>
+6 -9
View File
@@ -1,20 +1,17 @@
<script setup> <script setup>
import { SelectLabel } from "reka-ui"; import { SelectLabel } from 'reka-ui';
import { cn } from "@/lib/utils"; import { cn } from '@/lib/utils';
const props = defineProps({ const props = defineProps({
for: { type: String, required: false }, for: { type: String, required: false },
asChild: { type: Boolean, required: false }, asChild: { type: Boolean, required: false },
as: { type: null, required: false }, as: { type: null, required: false },
class: { type: null, required: false }, class: { type: null, required: false }
}); });
</script> </script>
<template> <template>
<SelectLabel <SelectLabel data-slot="select-label" :class="cn('text-muted-foreground px-2 py-1.5 text-xs', props.class)">
data-slot="select-label"
:class="cn('text-muted-foreground px-2 py-1.5 text-xs', props.class)"
>
<slot /> <slot />
</SelectLabel> </SelectLabel>
</template> </template>
@@ -1,28 +1,25 @@
<script setup> <script setup>
import { reactiveOmit } from "@vueuse/core"; import { reactiveOmit } from '@vueuse/core';
import { ChevronDown } from "lucide-vue-next"; import { ChevronDown } from 'lucide-vue-next';
import { SelectScrollDownButton, useForwardProps } from "reka-ui"; import { SelectScrollDownButton, useForwardProps } from 'reka-ui';
import { cn } from "@/lib/utils"; import { cn } from '@/lib/utils';
const props = defineProps({ const props = defineProps({
asChild: { type: Boolean, required: false }, asChild: { type: Boolean, required: false },
as: { type: null, required: false }, as: { type: null, required: false },
class: { type: null, required: false }, class: { type: null, required: false }
}); });
const delegatedProps = reactiveOmit(props, "class"); const delegatedProps = reactiveOmit(props, 'class');
const forwardedProps = useForwardProps(delegatedProps); const forwardedProps = useForwardProps(delegatedProps);
</script> </script>
<template> <template>
<SelectScrollDownButton <SelectScrollDownButton
data-slot="select-scroll-down-button" data-slot="select-scroll-down-button"
v-bind="forwardedProps" v-bind="forwardedProps"
:class=" :class="cn('flex cursor-default items-center justify-center py-1', props.class)">
cn('flex cursor-default items-center justify-center py-1', props.class)
"
>
<slot> <slot>
<ChevronDown class="size-4" /> <ChevronDown class="size-4" />
</slot> </slot>
@@ -1,28 +1,25 @@
<script setup> <script setup>
import { reactiveOmit } from "@vueuse/core"; import { reactiveOmit } from '@vueuse/core';
import { ChevronUp } from "lucide-vue-next"; import { ChevronUp } from 'lucide-vue-next';
import { SelectScrollUpButton, useForwardProps } from "reka-ui"; import { SelectScrollUpButton, useForwardProps } from 'reka-ui';
import { cn } from "@/lib/utils"; import { cn } from '@/lib/utils';
const props = defineProps({ const props = defineProps({
asChild: { type: Boolean, required: false }, asChild: { type: Boolean, required: false },
as: { type: null, required: false }, as: { type: null, required: false },
class: { type: null, required: false }, class: { type: null, required: false }
}); });
const delegatedProps = reactiveOmit(props, "class"); const delegatedProps = reactiveOmit(props, 'class');
const forwardedProps = useForwardProps(delegatedProps); const forwardedProps = useForwardProps(delegatedProps);
</script> </script>
<template> <template>
<SelectScrollUpButton <SelectScrollUpButton
data-slot="select-scroll-up-button" data-slot="select-scroll-up-button"
v-bind="forwardedProps" v-bind="forwardedProps"
:class=" :class="cn('flex cursor-default items-center justify-center py-1', props.class)">
cn('flex cursor-default items-center justify-center py-1', props.class)
"
>
<slot> <slot>
<ChevronUp class="size-4" /> <ChevronUp class="size-4" />
</slot> </slot>
+8 -9
View File
@@ -1,21 +1,20 @@
<script setup> <script setup>
import { reactiveOmit } from "@vueuse/core"; import { reactiveOmit } from '@vueuse/core';
import { SelectSeparator } from "reka-ui"; import { SelectSeparator } from 'reka-ui';
import { cn } from "@/lib/utils"; import { cn } from '@/lib/utils';
const props = defineProps({ const props = defineProps({
asChild: { type: Boolean, required: false }, asChild: { type: Boolean, required: false },
as: { type: null, required: false }, as: { type: null, required: false },
class: { type: null, required: false }, class: { type: null, required: false }
}); });
const delegatedProps = reactiveOmit(props, "class"); const delegatedProps = reactiveOmit(props, 'class');
</script> </script>
<template> <template>
<SelectSeparator <SelectSeparator
data-slot="select-separator" data-slot="select-separator"
v-bind="delegatedProps" v-bind="delegatedProps"
:class="cn('bg-border pointer-events-none -mx-1 my-1 h-px', props.class)" :class="cn('bg-border pointer-events-none -mx-1 my-1 h-px', props.class)" />
/>
</template> </template>
+8 -8
View File
@@ -1,20 +1,20 @@
<script setup> <script setup>
import { SelectIcon, SelectTrigger, useForwardProps } from 'reka-ui'; import { SelectIcon, SelectTrigger, useForwardProps } from 'reka-ui';
import { ChevronDown } from 'lucide-vue-next'; import { ChevronDown } from 'lucide-vue-next';
import { cn } from '@/lib/utils'; import { cn } from '@/lib/utils';
import { reactiveOmit } from '@vueuse/core'; import { reactiveOmit } from '@vueuse/core';
const props = defineProps({ const props = defineProps({
disabled: { type: Boolean, required: false }, disabled: { type: Boolean, required: false },
reference: { type: null, required: false }, reference: { type: null, required: false },
asChild: { type: Boolean, required: false }, asChild: { type: Boolean, required: false },
as: { type: null, required: false }, as: { type: null, required: false },
class: { type: null, required: false }, class: { type: null, required: false },
size: { type: String, required: false, default: 'default' } size: { type: String, required: false, default: 'default' }
}); });
const delegatedProps = reactiveOmit(props, 'class', 'size'); const delegatedProps = reactiveOmit(props, 'class', 'size');
const forwardedProps = useForwardProps(delegatedProps); const forwardedProps = useForwardProps(delegatedProps);
</script> </script>
<template> <template>
+4 -4
View File
@@ -1,11 +1,11 @@
<script setup> <script setup>
import { SelectValue } from "reka-ui"; import { SelectValue } from 'reka-ui';
const props = defineProps({ const props = defineProps({
placeholder: { type: String, required: false }, placeholder: { type: String, required: false },
asChild: { type: Boolean, required: false }, asChild: { type: Boolean, required: false },
as: { type: null, required: false }, as: { type: null, required: false }
}); });
</script> </script>
<template> <template>
+11 -11
View File
@@ -1,11 +1,11 @@
export { default as Select } from "./Select.vue"; export { default as Select } from './Select.vue';
export { default as SelectContent } from "./SelectContent.vue"; export { default as SelectContent } from './SelectContent.vue';
export { default as SelectGroup } from "./SelectGroup.vue"; export { default as SelectGroup } from './SelectGroup.vue';
export { default as SelectItem } from "./SelectItem.vue"; export { default as SelectItem } from './SelectItem.vue';
export { default as SelectItemText } from "./SelectItemText.vue"; export { default as SelectItemText } from './SelectItemText.vue';
export { default as SelectLabel } from "./SelectLabel.vue"; export { default as SelectLabel } from './SelectLabel.vue';
export { default as SelectScrollDownButton } from "./SelectScrollDownButton.vue"; export { default as SelectScrollDownButton } from './SelectScrollDownButton.vue';
export { default as SelectScrollUpButton } from "./SelectScrollUpButton.vue"; export { default as SelectScrollUpButton } from './SelectScrollUpButton.vue';
export { default as SelectSeparator } from "./SelectSeparator.vue"; export { default as SelectSeparator } from './SelectSeparator.vue';
export { default as SelectTrigger } from "./SelectTrigger.vue"; export { default as SelectTrigger } from './SelectTrigger.vue';
export { default as SelectValue } from "./SelectValue.vue"; export { default as SelectValue } from './SelectValue.vue';
+6 -6
View File
@@ -1,17 +1,17 @@
<script setup> <script setup>
import { Separator } from 'reka-ui'; import { Separator } from 'reka-ui';
import { cn } from '@/lib/utils'; import { cn } from '@/lib/utils';
import { reactiveOmit } from '@vueuse/core'; import { reactiveOmit } from '@vueuse/core';
const props = defineProps({ const props = defineProps({
orientation: { type: String, required: false, default: 'horizontal' }, orientation: { type: String, required: false, default: 'horizontal' },
decorative: { type: Boolean, required: false, default: true }, decorative: { type: Boolean, required: false, default: true },
asChild: { type: Boolean, required: false }, asChild: { type: Boolean, required: false },
as: { type: null, required: false }, as: { type: null, required: false },
class: { type: null, required: false } class: { type: null, required: false }
}); });
const delegatedProps = reactiveOmit(props, 'class'); const delegatedProps = reactiveOmit(props, 'class');
</script> </script>
<template> <template>
+1 -1
View File
@@ -1 +1 @@
export { default as Spinner } from "./Spinner.vue"; export { default as Spinner } from './Spinner.vue';
+5 -5
View File
@@ -1,7 +1,7 @@
<script setup> <script setup>
import { TooltipRoot, useForwardPropsEmits } from 'reka-ui'; import { TooltipRoot, useForwardPropsEmits } from 'reka-ui';
const props = defineProps({ const props = defineProps({
defaultOpen: { type: Boolean, required: false }, defaultOpen: { type: Boolean, required: false },
open: { type: Boolean, required: false }, open: { type: Boolean, required: false },
delayDuration: { type: Number, required: false }, delayDuration: { type: Number, required: false },
@@ -9,10 +9,10 @@ const props = defineProps({
disableClosingTrigger: { type: Boolean, required: false }, disableClosingTrigger: { type: Boolean, required: false },
disabled: { type: Boolean, required: false }, disabled: { type: Boolean, required: false },
ignoreNonKeyboardFocus: { type: Boolean, required: false } ignoreNonKeyboardFocus: { type: Boolean, required: false }
}); });
const emits = defineEmits(['update:open']); const emits = defineEmits(['update:open']);
const forwarded = useForwardPropsEmits(props, emits); const forwarded = useForwardPropsEmits(props, emits);
</script> </script>
<template> <template>
+3 -3
View File
@@ -1,11 +1,11 @@
<script setup> <script setup>
import { TooltipTrigger } from 'reka-ui'; import { TooltipTrigger } from 'reka-ui';
const props = defineProps({ const props = defineProps({
reference: { type: null, required: false }, reference: { type: null, required: false },
asChild: { type: Boolean, required: false }, asChild: { type: Boolean, required: false },
as: { type: null, required: false } as: { type: null, required: false }
}); });
</script> </script>
<template> <template>
+1 -2
View File
@@ -4,8 +4,7 @@ import { computed } from 'vue';
* A composable that provides key-based selection for an options map. * A composable that provides key-based selection for an options map.
* Extracts the repeated pattern of finding the current option's key from an * Extracts the repeated pattern of finding the current option's key from an
* options object and selecting a new option by key. * options object and selecting a new option by key.
* * @param {object} optionsMap - A static object mapping string keys to option objects
* @param {Object} optionsMap - A static object mapping string keys to option objects
* (each option should have at least `value` and `name` properties). * (each option should have at least `value` and `name` properties).
* @param {() => any} getCurrentValue - A getter function that returns the currently * @param {() => any} getCurrentValue - A getter function that returns the currently
* selected option value (e.g., `() => userDialog.value.worldSorting`). * selected option value (e.g., `() => userDialog.value.worldSorting`).
+1 -3
View File
@@ -65,9 +65,7 @@ export async function runHandleAutoLoginFlow({
if (AppDebug.errorNoty) { if (AppDebug.errorNoty) {
toast.dismiss(AppDebug.errorNoty); toast.dismiss(AppDebug.errorNoty);
} }
AppDebug.errorNoty = toast.error( AppDebug.errorNoty = toast.error(t('message.auth.auto_login_failed'));
t('message.auth.auto_login_failed')
);
console.error('Failed to login automatically.', err); console.error('Failed to login automatically.', err);
} finally { } finally {
authStore.setAttemptingAutoLogin(false); authStore.setAttemptingAutoLogin(false);
+4 -14
View File
@@ -129,11 +129,7 @@ export function showAvatarDialog(avatarId, options = {}) {
.then((args) => { .then((args) => {
const ref = applyAvatar(args.json); const ref = applyAvatar(args.json);
D.ref = ref; D.ref = ref;
uiStore.setDialogCrumbLabel( uiStore.setDialogCrumbLabel('avatar', D.id, D.ref?.name || D.id);
'avatar',
D.id,
D.ref?.name || D.id
);
avatarStore.getAvatarGallery(avatarId); avatarStore.getAvatarGallery(avatarId);
avatarStore.updateVRChatAvatarCache(); avatarStore.updateVRChatAvatarCache();
if (/quest/.test(ref.tags)) { if (/quest/.test(ref.tags)) {
@@ -333,8 +329,7 @@ export async function lookupAvatars(type, search) {
const length = const length =
avatarProviderStore.avatarRemoteDatabaseProviderList.length; avatarProviderStore.avatarRemoteDatabaseProviderList.length;
for (let i = 0; i < length; ++i) { for (let i = 0; i < length; ++i) {
const url = const url = avatarProviderStore.avatarRemoteDatabaseProviderList[i];
avatarProviderStore.avatarRemoteDatabaseProviderList[i];
const avatarArray = await lookupAvatarsByAuthor(url, search); const avatarArray = await lookupAvatarsByAuthor(url, search);
avatarArray.forEach((avatar) => { avatarArray.forEach((avatar) => {
if (!avatars.has(avatar.id)) { if (!avatars.has(avatar.id)) {
@@ -362,10 +357,7 @@ export async function lookupAvatarByImageFileId(authorId, fileId) {
} }
for (const providerUrl of avatarProviderStore.avatarRemoteDatabaseProviderList) { for (const providerUrl of avatarProviderStore.avatarRemoteDatabaseProviderList) {
const avatarArray = await lookupAvatarsByAuthor( const avatarArray = await lookupAvatarsByAuthor(providerUrl, authorId);
providerUrl,
authorId
);
for (const avatar of avatarArray) { for (const avatar of avatarArray) {
if (extractFileId(avatar.imageUrl) === fileId) { if (extractFileId(avatar.imageUrl) === fileId) {
return avatar.id; return avatar.id;
@@ -595,9 +587,7 @@ export async function showAvatarAuthorDialog(
} }
if (!avatarId) { if (!avatarId) {
if (ownerUserId === refUserId) { if (ownerUserId === refUserId) {
toast.warning( toast.warning(t('message.avatar_lookup.private_or_not_found'));
t('message.avatar_lookup.private_or_not_found')
);
} else { } else {
toast.warning(t('message.avatar_lookup.not_found')); toast.warning(t('message.avatar_lookup.not_found'));
showUserDialog(avatarInfo.ownerId); showUserDialog(avatarInfo.ownerId);
+58 -31
View File
@@ -326,8 +326,7 @@ export async function applyFavorite(type, objectId) {
} }
} else { } else {
// try fetch from local world favorites // try fetch from local world favorites
const world = const world = await database.getCachedWorldById(objectId);
await database.getCachedWorldById(objectId);
if (world) { if (world) {
ctx.ref = world; ctx.ref = world;
ctx.name = world.name; ctx.name = world.name;
@@ -356,8 +355,7 @@ export async function applyFavorite(type, objectId) {
} }
} else { } else {
// try fetch from local avatar history // try fetch from local avatar history
const avatar = const avatar = await database.getCachedAvatarById(objectId);
await database.getCachedAvatarById(objectId);
if (avatar) { if (avatar) {
ctx.ref = avatar; ctx.ref = avatar;
ctx.name = avatar.name; ctx.name = avatar.name;
@@ -392,12 +390,15 @@ export function refreshFavorites() {
return; return;
} }
favoriteStore.isFavoriteLoading = true; favoriteStore.isFavoriteLoading = true;
queryRequest.fetch('favoriteLimits').then((args) => { queryRequest
.fetch('favoriteLimits')
.then((args) => {
favoriteStore.favoriteLimits = { favoriteStore.favoriteLimits = {
...favoriteStore.favoriteLimits, ...favoriteStore.favoriteLimits,
...args.json ...args.json
}; };
}).catch((err) => { })
.catch((err) => {
console.error(err); console.error(err);
}); });
let newFavoriteSortOrder = []; let newFavoriteSortOrder = [];
@@ -516,7 +517,11 @@ export function sortLocalAvatarFavorites() {
const favoriteStore = useFavoriteStore(); const favoriteStore = useFavoriteStore();
const appearanceSettingsStore = useAppearanceSettingsStore(); const appearanceSettingsStore = useAppearanceSettingsStore();
if (!appearanceSettingsStore.sortFavorites) { if (!appearanceSettingsStore.sortFavorites) {
for (let i = 0; i < favoriteStore.localAvatarFavoriteGroups.length; ++i) { for (
let i = 0;
i < favoriteStore.localAvatarFavoriteGroups.length;
++i
) {
const group = favoriteStore.localAvatarFavoriteGroups[i]; const group = favoriteStore.localAvatarFavoriteGroups[i];
if (favoriteStore.localAvatarFavorites[group]) { if (favoriteStore.localAvatarFavorites[group]) {
favoriteStore.localAvatarFavorites[group].sort(compareByName); favoriteStore.localAvatarFavorites[group].sort(compareByName);
@@ -532,7 +537,11 @@ export function sortLocalWorldFavorites() {
const favoriteStore = useFavoriteStore(); const favoriteStore = useFavoriteStore();
const appearanceSettingsStore = useAppearanceSettingsStore(); const appearanceSettingsStore = useAppearanceSettingsStore();
if (!appearanceSettingsStore.sortFavorites) { if (!appearanceSettingsStore.sortFavorites) {
for (let i = 0; i < favoriteStore.localWorldFavoriteGroups.length; ++i) { for (
let i = 0;
i < favoriteStore.localWorldFavoriteGroups.length;
++i
) {
const group = favoriteStore.localWorldFavoriteGroups[i]; const group = favoriteStore.localWorldFavoriteGroups[i];
if (favoriteStore.localWorldFavorites[group]) { if (favoriteStore.localWorldFavorites[group]) {
favoriteStore.localWorldFavorites[group].sort(compareByName); favoriteStore.localWorldFavorites[group].sort(compareByName);
@@ -604,10 +613,17 @@ export function removeLocalWorldFavorite(worldId, group) {
let worldInFavorites = false; let worldInFavorites = false;
for (i = 0; i < favoriteStore.localWorldFavoriteGroups.length; ++i) { for (i = 0; i < favoriteStore.localWorldFavoriteGroups.length; ++i) {
const groupName = favoriteStore.localWorldFavoriteGroups[i]; const groupName = favoriteStore.localWorldFavoriteGroups[i];
if (!favoriteStore.localWorldFavorites[groupName] || group === groupName) { if (
!favoriteStore.localWorldFavorites[groupName] ||
group === groupName
) {
continue; continue;
} }
for (let j = 0; j < favoriteStore.localWorldFavorites[groupName].length; ++j) { for (
let j = 0;
j < favoriteStore.localWorldFavorites[groupName].length;
++j
) {
const id = favoriteStore.localWorldFavorites[groupName][j].id; const id = favoriteStore.localWorldFavorites[groupName][j].id;
if (id === worldId) { if (id === worldId) {
worldInFavorites = true; worldInFavorites = true;
@@ -704,7 +720,8 @@ export function renameLocalWorldFavoriteGroup(newName, group) {
); );
return; return;
} }
favoriteStore.localWorldFavorites[newName] = favoriteStore.localWorldFavorites[group]; favoriteStore.localWorldFavorites[newName] =
favoriteStore.localWorldFavorites[group];
delete favoriteStore.localWorldFavorites[group]; delete favoriteStore.localWorldFavorites[group];
database.renameWorldFavoriteGroup(newName, group); database.renameWorldFavoriteGroup(newName, group);
@@ -794,10 +811,17 @@ export function removeLocalAvatarFavorite(avatarId, group) {
let avatarInFavorites = false; let avatarInFavorites = false;
for (i = 0; i < favoriteStore.localAvatarFavoriteGroups.length; ++i) { for (i = 0; i < favoriteStore.localAvatarFavoriteGroups.length; ++i) {
const groupName = favoriteStore.localAvatarFavoriteGroups[i]; const groupName = favoriteStore.localAvatarFavoriteGroups[i];
if (!favoriteStore.localAvatarFavorites[groupName] || group === groupName) { if (
!favoriteStore.localAvatarFavorites[groupName] ||
group === groupName
) {
continue; continue;
} }
for (let j = 0; j < favoriteStore.localAvatarFavorites[groupName].length; ++j) { for (
let j = 0;
j < favoriteStore.localAvatarFavorites[groupName].length;
++j
) {
const id = favoriteStore.localAvatarFavorites[groupName][j].id; const id = favoriteStore.localAvatarFavorites[groupName][j].id;
if (id === avatarId) { if (id === avatarId) {
avatarInFavorites = true; avatarInFavorites = true;
@@ -854,8 +878,13 @@ export function deleteLocalAvatarFavoriteGroup(group) {
if (!favoriteStore.localAvatarFavorites[groupName]) { if (!favoriteStore.localAvatarFavorites[groupName]) {
continue; continue;
} }
for (let j = 0; j < favoriteStore.localAvatarFavorites[groupName].length; ++j) { for (
const avatarId = favoriteStore.localAvatarFavorites[groupName][j].id; let j = 0;
j < favoriteStore.localAvatarFavorites[groupName].length;
++j
) {
const avatarId =
favoriteStore.localAvatarFavorites[groupName][j].id;
if (avatarIdRemoveList.has(avatarId)) { if (avatarIdRemoveList.has(avatarId)) {
avatarIdRemoveList.delete(avatarId); avatarIdRemoveList.delete(avatarId);
break; break;
@@ -872,7 +901,10 @@ export function deleteLocalAvatarFavoriteGroup(group) {
++i ++i
) { ) {
const groupName = favoriteStore.localAvatarFavoriteGroups[i]; const groupName = favoriteStore.localAvatarFavoriteGroups[i];
if (!favoriteStore.localAvatarFavorites[groupName] || group === groupName) { if (
!favoriteStore.localAvatarFavorites[groupName] ||
group === groupName
) {
continue loop; continue loop;
} }
for ( for (
@@ -880,7 +912,8 @@ export function deleteLocalAvatarFavoriteGroup(group) {
j < favoriteStore.localAvatarFavorites[groupName].length; j < favoriteStore.localAvatarFavorites[groupName].length;
++j ++j
) { ) {
const avatarId = favoriteStore.localAvatarFavorites[groupName][j].id; const avatarId =
favoriteStore.localAvatarFavorites[groupName][j].id;
if (id === avatarId) { if (id === avatarId) {
avatarInFavorites = true; avatarInFavorites = true;
break loop; break loop;
@@ -961,7 +994,8 @@ export function renameLocalAvatarFavoriteGroup(newName, group) {
); );
return; return;
} }
favoriteStore.localAvatarFavorites[newName] = favoriteStore.localAvatarFavorites[group]; favoriteStore.localAvatarFavorites[newName] =
favoriteStore.localAvatarFavorites[group];
delete favoriteStore.localAvatarFavorites[group]; delete favoriteStore.localAvatarFavorites[group];
database.renameAvatarFavoriteGroup(newName, group); database.renameAvatarFavoriteGroup(newName, group);
@@ -1038,10 +1072,7 @@ export async function checkInvalidLocalAvatars(
}); });
await new Promise((resolve) => setTimeout(resolve, 500)); await new Promise((resolve) => setTimeout(resolve, 500));
} catch (err) { } catch (err) {
console.error( console.error(`Failed to fetch avatar ${favorite.id}:`, err);
`Failed to fetch avatar ${favorite.id}:`,
err
);
result.invalid++; result.invalid++;
result.invalidIds.push(favorite.id); result.invalidIds.push(favorite.id);
} }
@@ -1075,9 +1106,7 @@ export async function removeInvalidLocalAvatars(avatarIds, targetGroup = null) {
} }
for (const avatarId of avatarIds) { for (const avatarId of avatarIds) {
const index = favoriteGroup.findIndex( const index = favoriteGroup.findIndex((fav) => fav.id === avatarId);
(fav) => fav.id === avatarId
);
if (index !== -1) { if (index !== -1) {
removeLocalAvatarFavorite(avatarId, group); removeLocalAvatarFavorite(avatarId, group);
result.removed++; result.removed++;
@@ -1210,16 +1239,14 @@ export function renameLocalFriendFavoriteGroup(newName, group) {
); );
return; return;
} }
favoriteStore.localFriendFavorites[newName] = favoriteStore.localFriendFavorites[group]; favoriteStore.localFriendFavorites[newName] =
favoriteStore.localFriendFavorites[group];
delete favoriteStore.localFriendFavorites[group]; delete favoriteStore.localFriendFavorites[group];
database.renameFriendFavoriteGroup(newName, group); database.renameFriendFavoriteGroup(newName, group);
const oldKey = `local:${group}`; const oldKey = `local:${group}`;
const idx = const idx = generalSettingsStore.localFavoriteFriendsGroups.indexOf(oldKey);
generalSettingsStore.localFavoriteFriendsGroups.indexOf(oldKey);
if (idx !== -1) { if (idx !== -1) {
const updated = [ const updated = [...generalSettingsStore.localFavoriteFriendsGroups];
...generalSettingsStore.localFavoriteFriendsGroups
];
updated[idx] = `local:${newName}`; updated[idx] = `local:${newName}`;
generalSettingsStore.setLocalFavoriteFriendsGroups(updated); generalSettingsStore.setLocalFavoriteFriendsGroups(updated);
} }
@@ -205,9 +205,7 @@ export function updateFriendship(ref) {
}; };
friendLogTable.value.data.push(friendLogHistoryDisplayName); friendLogTable.value.data.push(friendLogHistoryDisplayName);
database.addFriendLogHistory(friendLogHistoryDisplayName); database.addFriendLogHistory(friendLogHistoryDisplayName);
notificationStore.queueFriendLogNoty( notificationStore.queueFriendLogNoty(friendLogHistoryDisplayName);
friendLogHistoryDisplayName
);
sharedFeedStore.addEntry(friendLogHistoryDisplayName); sharedFeedStore.addEntry(friendLogHistoryDisplayName);
const friendLogCurrent = { const friendLogCurrent = {
userId: ref.id, userId: ref.id,
@@ -321,7 +319,10 @@ export function updateUserCurrentStatus(ref) {
friendStore.updateOnlineFriendCounter(); friendStore.updateOnlineFriendCounter();
if (appearanceSettingsStore.randomUserColours) { if (appearanceSettingsStore.randomUserColours) {
getNameColour(userStore.currentUser.id, appearanceSettingsStore.isDarkMode).then((colour) => { getNameColour(
userStore.currentUser.id,
appearanceSettingsStore.isDarkMode
).then((colour) => {
userStore.setCurrentUserColour(colour); userStore.setCurrentUserColour(colour);
}); });
} }
+4 -9
View File
@@ -150,8 +150,7 @@ export function runCheckIfGameCrashedFlow() {
// check if relaunched less than 2mins ago (prevent crash loop) // check if relaunched less than 2mins ago (prevent crash loop)
if ( if (
gameStore.state.lastCrashedTime && gameStore.state.lastCrashedTime &&
new Date().getTime() - new Date().getTime() - gameStore.state.lastCrashedTime.getTime() <
gameStore.state.lastCrashedTime.getTime() <
120_000 120_000
) { ) {
console.log('VRChat was recently crashed, not relaunching'); console.log('VRChat was recently crashed, not relaunching');
@@ -211,13 +210,9 @@ export async function runCheckVRChatDebugLoggingFlow() {
return; return;
} }
try { try {
const loggingEnabled = await gameStore.getVRChatRegistryKey( const loggingEnabled =
'LOGGING_ENABLED' await gameStore.getVRChatRegistryKey('LOGGING_ENABLED');
); if (loggingEnabled === null || typeof loggingEnabled === 'undefined') {
if (
loggingEnabled === null ||
typeof loggingEnabled === 'undefined'
) {
// key not found // key not found
return; return;
} }
+11 -17
View File
@@ -14,7 +14,10 @@ import {
import { i18n } from '../plugins/i18n'; import { i18n } from '../plugins/i18n';
import { AppDebug } from '../services/appConfig'; import { AppDebug } from '../services/appConfig';
import { database } from '../services/database'; import { database } from '../services/database';
import { runLastLocationResetFlow, runUpdateCurrentUserLocationFlow } from './locationCoordinator'; import {
runLastLocationResetFlow,
runUpdateCurrentUserLocationFlow
} from './locationCoordinator';
import { getGroupName } from '../shared/utils'; import { getGroupName } from '../shared/utils';
import { userRequest } from '../api'; import { userRequest } from '../api';
import { watchState } from '../services/watchState'; import { watchState } from '../services/watchState';
@@ -94,10 +97,7 @@ export async function tryLoadPlayerList() {
joinTime: Date.parse(ctx.created_at), joinTime: Date.parse(ctx.created_at),
lastAvatar: '' lastAvatar: ''
}; };
locationStore.lastLocation.playerList.set( locationStore.lastLocation.playerList.set(ctx.userId, userMap);
ctx.userId,
userMap
);
if (friendStore.friends.has(ctx.userId)) { if (friendStore.friends.has(ctx.userId)) {
locationStore.lastLocation.friendList.set( locationStore.lastLocation.friendList.set(
ctx.userId, ctx.userId,
@@ -133,7 +133,6 @@ export async function tryLoadPlayerList() {
/** /**
* Core game log entry processor. Dispatches game log events to the * Core game log entry processor. Dispatches game log events to the
* appropriate stores based on type. * appropriate stores based on type.
*
* @param {object} gameLog * @param {object} gameLog
* @param {string} location * @param {string} location
*/ */
@@ -160,10 +159,8 @@ export function addGameLogEntry(gameLog, location) {
let userId = String(gameLog.userId || ''); let userId = String(gameLog.userId || '');
if (!userId && gameLog.displayName) { if (!userId && gameLog.displayName) {
userId = userId =
findUserByDisplayName( findUserByDisplayName(userStore.cachedUsers, gameLog.displayName)
userStore.cachedUsers, ?.id ?? '';
gameLog.displayName
)?.id ?? '';
} }
switch (gameLog.type) { switch (gameLog.type) {
case 'location-destination': case 'location-destination':
@@ -213,10 +210,7 @@ export function addGameLogEntry(gameLog, location) {
instanceStore.applyWorldDialogInstances(); instanceStore.applyWorldDialogInstances();
instanceStore.applyGroupDialogInstances(); instanceStore.applyGroupDialogInstances();
} }
instanceStore.addInstanceJoinHistory( instanceStore.addInstanceJoinHistory(gameLog.location, gameLog.dt);
gameLog.location,
gameLog.dt
);
const L = parseLocation(gameLog.location); const L = parseLocation(gameLog.location);
entry = createLocationEntry( entry = createLocationEntry(
gameLog.dt, gameLog.dt,
@@ -282,7 +276,9 @@ export function addGameLogEntry(gameLog, location) {
const time = dayjs(gameLog.dt) - ref1.joinTime; const time = dayjs(gameLog.dt) - ref1.joinTime;
locationStore.lastLocation.playerList.delete(userId); locationStore.lastLocation.playerList.delete(userId);
locationStore.lastLocation.friendList.delete(userId); locationStore.lastLocation.friendList.delete(userId);
gameLogStore.state.lastLocationAvatarList.delete(gameLog.displayName); gameLogStore.state.lastLocationAvatarList.delete(
gameLog.displayName
);
photonStore.photonLobbyAvatars.delete(userId); photonStore.photonLobbyAvatars.delete(userId);
vrStore.updateVRLastLocation(); vrStore.updateVRLastLocation();
instanceStore.getCurrentInstanceUserList(); instanceStore.getCurrentInstanceUserList();
@@ -499,7 +495,6 @@ export function addGameLogEntry(gameLog, location) {
/** /**
* Parses raw game log JSON and delegates to addGameLogEntry. * Parses raw game log JSON and delegates to addGameLogEntry.
* Called from C# / updateLoop. * Called from C# / updateLoop.
*
* @param {string} json * @param {string} json
*/ */
export function addGameLogEvent(json) { export function addGameLogEvent(json) {
@@ -533,7 +528,6 @@ export async function getGameLogTable() {
/** /**
* Fetches all game log entries since dateTill and processes them. * Fetches all game log entries since dateTill and processes them.
*
* @param {string} dateTill * @param {string} dateTill
*/ */
async function updateGameLog(dateTill) { async function updateGameLog(dateTill) {
+23 -29
View File
@@ -67,11 +67,7 @@ export function applyGroup(json) {
} else { } else {
if (groupStore.currentUserGroups.has(ref.id)) { if (groupStore.currentUserGroups.has(ref.id)) {
// compare group props // compare group props
if ( if (ref.ownerId && json.ownerId && ref.ownerId !== json.ownerId) {
ref.ownerId &&
json.ownerId &&
ref.ownerId !== json.ownerId
) {
// owner changed // owner changed
groupOwnerChange(json, ref.ownerId, json.ownerId); groupOwnerChange(json, ref.ownerId, json.ownerId);
} }
@@ -172,8 +168,7 @@ export function applyGroupMember(json) {
id: json.groupId, id: json.groupId,
memberVisibility: json.visibility, memberVisibility: json.visibility,
isRepresenting: json.isRepresenting, isRepresenting: json.isRepresenting,
isSubscribedToAnnouncements: isSubscribedToAnnouncements: json.isSubscribedToAnnouncements,
json.isSubscribedToAnnouncements,
joinedAt: json.joinedAt, joinedAt: json.joinedAt,
roleIds: json.roleIds, roleIds: json.roleIds,
membershipStatus: json.membershipStatus membershipStatus: json.membershipStatus
@@ -258,9 +253,7 @@ function groupRoleChange(ref, oldRoles, newRoles, oldRoleIds, newRoleIds) {
for (const roleId of oldRoleIds) { for (const roleId of oldRoleIds) {
if (!newRoleIds.includes(roleId)) { if (!newRoleIds.includes(roleId)) {
let roleName = ''; let roleName = '';
const role = oldRoles.find( const role = oldRoles.find((fineRole) => fineRole.id === roleId);
(fineRole) => fineRole.id === roleId
);
if (role) { if (role) {
roleName = role.name; roleName = role.name;
} }
@@ -345,11 +338,7 @@ export function showGroupDialog(groupId, options = {}) {
const ref = args.ref || applyGroup(args.json); const ref = args.ref || applyGroup(args.json);
if (groupId === ref.id) { if (groupId === ref.id) {
D.ref = ref; D.ref = ref;
uiStore.setDialogCrumbLabel( uiStore.setDialogCrumbLabel('group', D.id, D.ref?.name || D.id);
'group',
D.id,
D.ref?.name || D.id
);
D.inGroup = ref.membershipStatus === 'member'; D.inGroup = ref.membershipStatus === 'member';
D.ownerDisplayName = ref.ownerId; D.ownerDisplayName = ref.ownerId;
D.visible = true; D.visible = true;
@@ -447,7 +436,10 @@ export function getGroupDialogGroup(groupId, existingRef) {
if (groupStore.groupDialog.id === args.params.groupId) { if (groupStore.groupDialog.id === args.params.groupId) {
D.calendar = args.json.results; D.calendar = args.json.results;
for (const event of D.calendar) { for (const event of D.calendar) {
Object.assign(event, groupStore.applyGroupEvent(event)); Object.assign(
event,
groupStore.applyGroupEvent(event)
);
// fetch again for isFollowing // fetch again for isFollowing
queryRequest queryRequest
.fetch('groupCalendarEvent', { .fetch('groupCalendarEvent', {
@@ -457,7 +449,9 @@ export function getGroupDialogGroup(groupId, existingRef) {
.then((args) => { .then((args) => {
Object.assign( Object.assign(
event, event,
groupStore.applyGroupEvent(args.json) groupStore.applyGroupEvent(
args.json
)
); );
}); });
} }
@@ -516,9 +510,7 @@ export function onGroupJoined(groupId) {
name: '', name: '',
iconUrl: '' iconUrl: ''
}); });
groupRequest groupRequest.getGroup({ groupId, includeRoles: true }).then((args) => {
.getGroup({ groupId, includeRoles: true })
.then((args) => {
applyGroup(args.json); applyGroup(args.json);
saveCurrentUserGroups(); saveCurrentUserGroups();
return args; return args;
@@ -541,7 +533,10 @@ export async function onGroupLeft(groupId) {
); );
return; return;
} }
if (groupStore.groupDialog.visible && groupStore.groupDialog.id === groupId) { if (
groupStore.groupDialog.visible &&
groupStore.groupDialog.id === groupId
) {
showGroupDialog(groupId); showGroupDialog(groupId);
} }
if (groupStore.currentUserGroups.has(groupId)) { if (groupStore.currentUserGroups.has(groupId)) {
@@ -615,10 +610,7 @@ export async function loadCurrentUserGroups(userId, groups) {
const promises = groups.map(async (groupId) => { const promises = groups.map(async (groupId) => {
const groupRef = groupStore.cachedGroups.get(groupId); const groupRef = groupStore.cachedGroups.get(groupId);
if ( if (typeof groupRef !== 'undefined' && groupRef.roles?.length > 0) {
typeof groupRef !== 'undefined' &&
groupRef.roles?.length > 0
) {
return; return;
} }
@@ -814,9 +806,7 @@ export function handleGroupRepresented(args) {
const D = userStore.userDialog; const D = userStore.userDialog;
const json = args.json; const json = args.json;
D.representedGroup = json; D.representedGroup = json;
D.representedGroup.$thumbnailUrl = convertFileUrlToImageUrl( D.representedGroup.$thumbnailUrl = convertFileUrlToImageUrl(json.iconUrl);
json.iconUrl
);
if (!json || !json.isRepresenting) { if (!json || !json.isRepresenting) {
D.isRepresentedGroupLoading = false; D.isRepresentedGroupLoading = false;
} }
@@ -887,7 +877,11 @@ export function handleGroupMemberProps(args) {
break; break;
} }
} }
for (i = 0; i < groupStore.groupDialog.memberSearchResults.length; ++i) { for (
i = 0;
i < groupStore.groupDialog.memberSearchResults.length;
++i
) {
member = groupStore.groupDialog.memberSearchResults[i]; member = groupStore.groupDialog.memberSearchResults[i];
if (member.userId === args.json.userId) { if (member.userId === args.json.userId) {
Object.assign(member, applyGroupMember(args.json)); Object.assign(member, applyGroupMember(args.json));
+11 -3
View File
@@ -68,7 +68,10 @@ export function runUpdateCurrentUserLocationFlow() {
} }
} }
export async function runSetCurrentUserLocationFlow(location, travelingToLocation) { export async function runSetCurrentUserLocationFlow(
location,
travelingToLocation
) {
const userStore = useUserStore(); const userStore = useUserStore();
const instanceStore = useInstanceStore(); const instanceStore = useInstanceStore();
const notificationStore = useNotificationStore(); const notificationStore = useNotificationStore();
@@ -147,7 +150,9 @@ export function runLastLocationResetFlow(gameLogDate) {
} }
const dateTimeStamp = Date.parse(dateTime); const dateTimeStamp = Date.parse(dateTime);
photonStore.resetLocationPhotonState(); photonStore.resetLocationPhotonState();
const playerList = Array.from(locationStore.lastLocation.playerList.values()); const playerList = Array.from(
locationStore.lastLocation.playerList.values()
);
const dataBaseEntries = []; const dataBaseEntries = [];
for (const ref of playerList) { for (const ref of playerList) {
const entry = { const entry = {
@@ -162,7 +167,10 @@ export function runLastLocationResetFlow(gameLogDate) {
gameLogStore.addGameLog(entry); gameLogStore.addGameLog(entry);
} }
database.addGamelogJoinLeaveBulk(dataBaseEntries); database.addGamelogJoinLeaveBulk(dataBaseEntries);
if (locationStore.lastLocation.date !== null && locationStore.lastLocation.date > 0) { if (
locationStore.lastLocation.date !== null &&
locationStore.lastLocation.date > 0
) {
const update = { const update = {
time: dateTimeStamp - locationStore.lastLocation.date, time: dateTimeStamp - locationStore.lastLocation.date,
created_at: new Date(locationStore.lastLocation.date).toJSON() created_at: new Date(locationStore.lastLocation.date).toJSON()
+1 -4
View File
@@ -34,10 +34,7 @@ export async function runRefreshPlayerModerationsFlow() {
moderationStore.deleteExpiredPlayerModerations(); moderationStore.deleteExpiredPlayerModerations();
}) })
.catch((error) => { .catch((error) => {
console.error( console.error('Failed to load player/avatar moderations:', error);
'Failed to load player/avatar moderations:',
error
);
}) })
.finally(() => { .finally(() => {
moderationStore.playerModerationTable.loading = false; moderationStore.playerModerationTable.loading = false;
+1 -3
View File
@@ -223,9 +223,7 @@ export async function runHandleUserUpdateFlow(
avatarName: '' avatarName: ''
}; };
try { try {
avatarInfo = await getAvatarName( avatarInfo = await getAvatarName(currentAvatarImageUrl);
currentAvatarImageUrl
);
} catch (err) { } catch (err) {
console.log(err); console.log(err);
} }
+1 -4
View File
@@ -1,9 +1,6 @@
export { queryClient } from './client'; export { queryClient } from './client';
export { queryKeys } from './keys'; export { queryKeys } from './keys';
export { export { entityQueryPolicies, toQueryOptions } from './policies';
entityQueryPolicies,
toQueryOptions
} from './policies';
export { export {
fetchWithEntityPolicy, fetchWithEntityPolicy,
patchAndRefetchActiveQuery, patchAndRefetchActiveQuery,
+2
View File
@@ -1364,6 +1364,8 @@ const gameLog = {
* *
* @param {string} startDate: utc string of startOfDay * @param {string} startDate: utc string of startOfDay
* @param {string} endDate: utc string endOfDay * @param {string} endDate: utc string endOfDay
* @param startDate
* @param endDate
* @returns * @returns
*/ */
async getInstanceActivity(startDate, endDate) { async getInstanceActivity(startDate, endDate) {
+1
View File
@@ -58,6 +58,7 @@ export const TAG_COLORS = Object.freeze([
/** /**
* Deterministically map a tag name to a color from the palette. * Deterministically map a tag name to a color from the palette.
* Uses djb2 hash so the same tag always gets the same color. * Uses djb2 hash so the same tag always gets the same color.
* @param tagName
*/ */
export function getTagColor(tagName) { export function getTagColor(tagName) {
let hash = 5381; let hash = 5381;
+1
View File
@@ -92,6 +92,7 @@ function getPlatformInfo(unityPackages) {
/** /**
* *
* @param {string} unitySortNumber * @param {string} unitySortNumber
* @param sdkUnityVersion
* @returns {boolean} * @returns {boolean}
*/ */
function compareUnityVersion(unitySortNumber, sdkUnityVersion) { function compareUnityVersion(unitySortNumber, sdkUnityVersion) {
+4 -4
View File
@@ -1,6 +1,6 @@
/** /**
* *
* @param {array} array * @param {Array} array
* @param {*} item * @param {*} item
* @returns {boolean} * @returns {boolean}
*/ */
@@ -17,8 +17,8 @@ function removeFromArray(array, item) {
/** /**
* *
* @param {array} a * @param {Array} a
* @param {array} b * @param {Array} b
* @returns {boolean} * @returns {boolean}
*/ */
function arraysMatch(a, b) { function arraysMatch(a, b) {
@@ -36,7 +36,7 @@ function arraysMatch(a, b) {
/** /**
* *
* @param {array} array * @param {Array} array
* @param {number} fromIndex * @param {number} fromIndex
* @param {number} toIndex * @param {number} toIndex
* @returns {void} * @returns {void}
+8 -2
View File
@@ -38,7 +38,10 @@ async function getBundleLocation(input) {
} }
if ( if (
unityPackage.platform === 'standalonewindows' && unityPackage.platform === 'standalonewindows' &&
compareUnityVersion(unityPackage.unitySortNumber, sdkUnityVersion) compareUnityVersion(
unityPackage.unitySortNumber,
sdkUnityVersion
)
) { ) {
assetUrl = unityPackage.assetUrl; assetUrl = unityPackage.assetUrl;
if (unityPackage.variant !== 'standard') { if (unityPackage.variant !== 'standard') {
@@ -61,7 +64,10 @@ async function getBundleLocation(input) {
unityPackage = unityPackages[i]; unityPackage = unityPackages[i];
if ( if (
unityPackage.platform === 'standalonewindows' && unityPackage.platform === 'standalonewindows' &&
compareUnityVersion(unityPackage.unitySortNumber, sdkUnityVersion) compareUnityVersion(
unityPackage.unitySortNumber,
sdkUnityVersion
)
) { ) {
assetUrl = unityPackage.assetUrl; assetUrl = unityPackage.assetUrl;
break; break;
+1
View File
@@ -316,6 +316,7 @@ async function refreshCustomScript() {
/** /**
* *
* @param {number} hue * @param {number} hue
* @param isDarkMode
* @returns {string} * @returns {string}
*/ */
function HueToHex(hue, isDarkMode) { function HueToHex(hue, isDarkMode) {
+1
View File
@@ -59,6 +59,7 @@ function getEmojiFileName(emoji) {
* @param {number} fps * @param {number} fps
* @param {number} frameCount * @param {number} frameCount
* @param {string} loopStyle * @param {string} loopStyle
* @param size
*/ */
function generateEmojiStyle(url, fps, frameCount, loopStyle, size) { function generateEmojiStyle(url, fps, frameCount, loopStyle, size) {
let framesPerLine = 2; let framesPerLine = 2;
+3 -1
View File
@@ -1,5 +1,7 @@
import { localeIncludes } from './base/string'; import { localeIncludes } from './base/string';
import removeConfusables, { removeWhitespace } from '../../services/confusables'; import removeConfusables, {
removeWhitespace
} from '../../services/confusables';
/** /**
* Tests whether a name matches a query using locale-aware comparison. * Tests whether a name matches a query using locale-aware comparison.
-3
View File
@@ -4,7 +4,6 @@ import { displayLocation } from './locationParser';
* Extracts the notification title and body from a notification object. * Extracts the notification title and body from a notification object.
* This is the single source of truth for notification message content, * This is the single source of truth for notification message content,
* used by desktop toast, XS overlay, OVRT overlay, and TTS. * used by desktop toast, XS overlay, OVRT overlay, and TTS.
*
* @param {object} noty - The notification object * @param {object} noty - The notification object
* @param {string} message - Pre-built invite/request message string * @param {string} message - Pre-built invite/request message string
* @param {string} [displayNameOverride] - Optional override for the display * @param {string} [displayNameOverride] - Optional override for the display
@@ -212,7 +211,6 @@ const CUSTOM_FORMAT_MESSAGES = {
/** /**
* Combines title and body into a single notification text string. * Combines title and body into a single notification text string.
* Handles per-type formatting differences for XS/OVRT overlays. * Handles per-type formatting differences for XS/OVRT overlays.
*
* @param {string} title * @param {string} title
* @param {string} body * @param {string} body
* @param {string} type - The notification type * @param {string} type - The notification type
@@ -236,7 +234,6 @@ export function toNotificationText(title, body, type) {
* Extract a userId from a notification object by checking common fields. * Extract a userId from a notification object by checking common fields.
* Does NOT perform display-name-based lookups - the caller should handle * Does NOT perform display-name-based lookups - the caller should handle
* that fallback when a cached user map is available. * that fallback when a cached user map is available.
*
* @param {object} noty * @param {object} noty
* @returns {string} * @returns {string}
*/ */
-1
View File
@@ -1,7 +1,6 @@
/** /**
* Generic resolver for user/world/group references. * Generic resolver for user/world/group references.
* Normalises the input, optionally fetches the display name if missing. * Normalises the input, optionally fetches the display name if missing.
*
* @param {string|object|null|undefined} input * @param {string|object|null|undefined} input
* @param {object} opts * @param {object} opts
* @param {object} opts.emptyDefault - value to return when input is falsy * @param {object} opts.emptyDefault - value to return when input is falsy
+2 -6
View File
@@ -181,8 +181,7 @@ function userImage(
} }
if ( if (
(isUserDialogIcon && user.userIcon) || (isUserDialogIcon && user.userIcon) ||
(displayVRCPlusIconsAsAvatar && (displayVRCPlusIconsAsAvatar && user.userIcon)
user.userIcon)
) { ) {
if (isIcon) { if (isIcon) {
return convertFileUrlToImageUrl(user.userIcon); return convertFileUrlToImageUrl(user.userIcon);
@@ -233,10 +232,7 @@ function userImageFull(user, displayVRCPlusIconsAsAvatar = false) {
if (!user) { if (!user) {
return ''; return '';
} }
if ( if (displayVRCPlusIconsAsAvatar && user.userIcon) {
displayVRCPlusIconsAsAvatar &&
user.userIcon
) {
return user.userIcon; return user.userIcon;
} }
if (user.profilePicOverride) { if (user.profilePicOverride) {
+4 -2
View File
@@ -104,10 +104,12 @@ export const useAuthStore = defineStore('Auth', () => {
* *
*/ */
async function init() { async function init() {
const [lastUserLoggedIn, savedEnableCustomEndpoint] = await Promise.all([ const [lastUserLoggedIn, savedEnableCustomEndpoint] = await Promise.all(
[
configRepository.getString('lastUserLoggedIn', ''), configRepository.getString('lastUserLoggedIn', ''),
configRepository.getBool('VRCX_enableCustomEndpoint', false) configRepository.getBool('VRCX_enableCustomEndpoint', false)
]); ]
);
loginForm.value.lastUserLoggedIn = lastUserLoggedIn; loginForm.value.lastUserLoggedIn = lastUserLoggedIn;
enableCustomEndpoint.value = savedEnableCustomEndpoint; enableCustomEndpoint.value = savedEnableCustomEndpoint;
} }
+1 -3
View File
@@ -1,9 +1,7 @@
import { ref, watch } from 'vue'; import { ref, watch } from 'vue';
import { defineStore } from 'pinia'; import { defineStore } from 'pinia';
import { import { checkVRChatCache } from '../shared/utils';
checkVRChatCache
} from '../shared/utils';
import { database } from '../services/database'; import { database } from '../services/database';
import { watchState } from '../services/watchState'; import { watchState } from '../services/watchState';
-1
View File
@@ -7,7 +7,6 @@ import {
/** /**
* Creates the media parser functions for the GameLog store. * Creates the media parser functions for the GameLog store.
*
* @param {object} deps * @param {object} deps
* @param {import('vue').Ref} deps.nowPlaying * @param {import('vue').Ref} deps.nowPlaying
* @param {Function} deps.setNowPlaying * @param {Function} deps.setNowPlaying
+1 -4
View File
@@ -2,10 +2,7 @@ import { reactive, ref, watch } from 'vue';
import { defineStore } from 'pinia'; import { defineStore } from 'pinia';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { import { hasGroupPermission, replaceBioSymbols } from '../shared/utils';
hasGroupPermission,
replaceBioSymbols
} from '../shared/utils';
import { groupRequest, queryRequest } from '../api'; import { groupRequest, queryRequest } from '../api';
import { groupDialogFilterOptions } from '../shared/constants/'; import { groupDialogFilterOptions } from '../shared/constants/';
import { watchState } from '../services/watchState'; import { watchState } from '../services/watchState';
-2
View File
@@ -85,8 +85,6 @@ export const useInviteStore = defineStore('Invite', () => {
}); });
} }
return { return {
inviteMessageTable, inviteMessageTable,
inviteResponseMessageTable, inviteResponseMessageTable,
-1
View File
@@ -50,4 +50,3 @@ export const useLocationStore = defineStore('Location', () => {
setLastLocationDestinationTime setLastLocationDestinationTime
}; };
}); });
+6 -6
View File
@@ -3,13 +3,13 @@ import { ref } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
/** /**
* @typedef {Object} ConfirmResult * @typedef {object} ConfirmResult
* @property {boolean} ok * @property {boolean} ok
* @property {'ok' | 'cancel' | 'dismiss' | 'replaced'} reason * @property {'ok' | 'cancel' | 'dismiss' | 'replaced'} reason
*/ */
/** /**
* @typedef {Object} ConfirmOptions * @typedef {object} ConfirmOptions
* @property {string} title * @property {string} title
* @property {string} description * @property {string} description
* @property {string=} confirmText * @property {string=} confirmText
@@ -18,7 +18,7 @@ import { useI18n } from 'vue-i18n';
*/ */
/** /**
* @typedef {Object} AlertOptions * @typedef {object} AlertOptions
* @property {string} title * @property {string} title
* @property {string} description * @property {string} description
* @property {string=} confirmText * @property {string=} confirmText
@@ -26,14 +26,14 @@ import { useI18n } from 'vue-i18n';
*/ */
/** /**
* @typedef {Object} PromptResult * @typedef {object} PromptResult
* @property {boolean} ok * @property {boolean} ok
* @property {'ok' | 'cancel' | 'dismiss' | 'replaced'} reason * @property {'ok' | 'cancel' | 'dismiss' | 'replaced'} reason
* @property {string} value * @property {string} value
*/ */
/** /**
* @typedef {Object} PromptOptions * @typedef {object} PromptOptions
* @property {string} title * @property {string} title
* @property {string} description * @property {string} description
* @property {string=} confirmText * @property {string=} confirmText
@@ -46,7 +46,7 @@ import { useI18n } from 'vue-i18n';
*/ */
/** /**
* @typedef {Object} OtpPromptOptions * @typedef {object} OtpPromptOptions
* @property {string} title * @property {string} title
* @property {string} description * @property {string} description
* @property {'totp' | 'emailOtp' | 'otp'} mode * @property {'totp' | 'emailOtp' | 'otp'} mode
+1 -3
View File
@@ -173,12 +173,10 @@ export const useModerationStore = defineStore('Moderation', () => {
} }
} }
/** /**
* Get user moderations * Get user moderations
* @param {string} userId * @param {string} userId
* @return {object} moderations * @returns {object} moderations
* @property {boolean} isBlocked * @property {boolean} isBlocked
* @property {boolean} isMuted * @property {boolean} isMuted
* @property {boolean} isAvatarInteractionDisabled * @property {boolean} isAvatarInteractionDisabled

Some files were not shown because too many files have changed in this diff Show More