mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-05-06 06:46:04 +02:00
fix and constants
This commit is contained in:
+49
-135
@@ -194,9 +194,6 @@
|
|||||||
</el-popover>
|
</el-popover>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
|
||||||
<div></div>
|
|
||||||
</template>
|
|
||||||
</div>
|
</div>
|
||||||
<CustomNavDialog
|
<CustomNavDialog
|
||||||
v-model:visible="customNavDialogVisible"
|
v-model:visible="customNavDialogVisible"
|
||||||
@@ -222,114 +219,42 @@
|
|||||||
useUiStore,
|
useUiStore,
|
||||||
useVRCXUpdaterStore
|
useVRCXUpdaterStore
|
||||||
} from '../stores';
|
} from '../stores';
|
||||||
import { THEME_CONFIG } from '../shared/constants';
|
import { THEME_CONFIG, links, navDefinitions } from '../shared/constants';
|
||||||
import { openExternalLink } from '../shared/utils';
|
import { openExternalLink } from '../shared/utils';
|
||||||
|
|
||||||
import CustomNavDialog from './dialogs/CustomNavDialog.vue';
|
import CustomNavDialog from './dialogs/CustomNavDialog.vue';
|
||||||
import configRepository from '../service/config';
|
import configRepository from '../service/config';
|
||||||
|
|
||||||
const { t } = useI18n();
|
import 'remixicon/fonts/remixicon.css';
|
||||||
|
|
||||||
|
const { t, locale } = useI18n();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const navDefinitions = [
|
const createDefaultNavLayout = () => [
|
||||||
|
{ type: 'item', key: 'feed' },
|
||||||
|
{ type: 'item', key: 'friends-locations' },
|
||||||
|
{ type: 'item', key: 'game-log' },
|
||||||
|
{ type: 'item', key: 'player-list' },
|
||||||
|
{ type: 'item', key: 'search' },
|
||||||
{
|
{
|
||||||
key: 'feed',
|
type: 'folder',
|
||||||
icon: 'ri-rss-line',
|
id: 'default-folder-favorites',
|
||||||
tooltip: 'nav_tooltip.feed',
|
nameKey: 'nav_tooltip.favorites',
|
||||||
labelKey: 'nav_tooltip.feed',
|
name: t('nav_tooltip.favorites'),
|
||||||
routeName: 'feed'
|
icon: 'ri-star-line',
|
||||||
|
items: ['favorite-friends', 'favorite-worlds', 'favorite-avatars']
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'friends-locations',
|
type: 'folder',
|
||||||
icon: 'ri-user-location-line',
|
id: 'default-folder-social',
|
||||||
tooltip: 'nav_tooltip.friends_locations',
|
nameKey: 'nav_tooltip.social',
|
||||||
labelKey: 'nav_tooltip.friends_locations',
|
name: t('nav_tooltip.social'),
|
||||||
routeName: 'friends-locations'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'game-log',
|
|
||||||
icon: 'ri-history-line',
|
|
||||||
tooltip: 'nav_tooltip.game_log',
|
|
||||||
labelKey: 'nav_tooltip.game_log',
|
|
||||||
routeName: 'game-log'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'player-list',
|
|
||||||
icon: 'ri-group-3-line',
|
|
||||||
tooltip: 'nav_tooltip.player_list',
|
|
||||||
labelKey: 'nav_tooltip.player_list',
|
|
||||||
routeName: 'player-list'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'search',
|
|
||||||
icon: 'ri-search-line',
|
|
||||||
tooltip: 'nav_tooltip.search',
|
|
||||||
labelKey: 'nav_tooltip.search',
|
|
||||||
routeName: 'search'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'favorite-friends',
|
|
||||||
icon: 'ri-heart-2-line',
|
|
||||||
tooltip: 'nav_tooltip.favorite_friends',
|
|
||||||
labelKey: 'nav_tooltip.favorite_friends',
|
|
||||||
routeName: 'favorite-friends'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'favorite-worlds',
|
|
||||||
icon: 'ri-earth-line',
|
|
||||||
tooltip: 'nav_tooltip.favorite_worlds',
|
|
||||||
labelKey: 'nav_tooltip.favorite_worlds',
|
|
||||||
routeName: 'favorite-worlds'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'favorite-avatars',
|
|
||||||
icon: 'ri-user-heart-line',
|
|
||||||
tooltip: 'nav_tooltip.favorite_avatars',
|
|
||||||
labelKey: 'nav_tooltip.favorite_avatars',
|
|
||||||
routeName: 'favorite-avatars'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'friend-log',
|
|
||||||
icon: 'ri-booklet-line',
|
|
||||||
tooltip: 'nav_tooltip.friend_log',
|
|
||||||
labelKey: 'nav_tooltip.friend_log',
|
|
||||||
routeName: 'friend-log'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'friend-list',
|
|
||||||
icon: 'ri-group-line',
|
icon: 'ri-group-line',
|
||||||
tooltip: 'nav_tooltip.friend_list',
|
items: ['friend-log', 'friend-list', 'moderation']
|
||||||
labelKey: 'nav_tooltip.friend_list',
|
|
||||||
routeName: 'friend-list'
|
|
||||||
},
|
},
|
||||||
{
|
{ type: 'item', key: 'notification' },
|
||||||
key: 'moderation',
|
{ type: 'item', key: 'charts' },
|
||||||
icon: 'ri-shield-user-line',
|
{ type: 'item', key: 'tools' }
|
||||||
tooltip: 'nav_tooltip.moderation',
|
|
||||||
labelKey: 'nav_tooltip.moderation',
|
|
||||||
routeName: 'moderation'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'notification',
|
|
||||||
icon: 'ri-notification-2-line',
|
|
||||||
tooltip: 'nav_tooltip.notification',
|
|
||||||
labelKey: 'nav_tooltip.notification',
|
|
||||||
routeName: 'notification'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'charts',
|
|
||||||
icon: 'ri-bar-chart-line',
|
|
||||||
tooltip: 'nav_tooltip.charts',
|
|
||||||
labelKey: 'nav_tooltip.charts',
|
|
||||||
routeName: 'charts'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'tools',
|
|
||||||
icon: 'ri-tools-line',
|
|
||||||
tooltip: 'nav_tooltip.tools',
|
|
||||||
labelKey: 'nav_tooltip.tools',
|
|
||||||
routeName: 'tools'
|
|
||||||
}
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const navDefinitionMap = new Map(navDefinitions.map((item) => [item.key, item]));
|
const navDefinitionMap = new Map(navDefinitions.map((item) => [item.key, item]));
|
||||||
@@ -368,7 +293,6 @@
|
|||||||
const supportMenuVisible = ref(false);
|
const supportMenuVisible = ref(false);
|
||||||
const navMenuRef = ref(null);
|
const navMenuRef = ref(null);
|
||||||
const navPopoverRefs = new Map();
|
const navPopoverRefs = new Map();
|
||||||
|
|
||||||
const navLayout = ref([]);
|
const navLayout = ref([]);
|
||||||
const navLayoutReady = ref(false);
|
const navLayoutReady = ref(false);
|
||||||
|
|
||||||
@@ -466,32 +390,25 @@
|
|||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
const generateFolderId = () => `nav-folder-${dayjs().toISOString()}-${Math.random().toString().slice(2, 4)}`;
|
watch(
|
||||||
|
() => locale.value,
|
||||||
|
() => {
|
||||||
|
if (!navLayoutReady.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
navLayout.value = navLayout.value.map((entry) => {
|
||||||
|
if (entry.type === 'folder' && entry.nameKey) {
|
||||||
|
return {
|
||||||
|
...entry,
|
||||||
|
name: t(entry.nameKey)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return entry;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const defaultNavLayout = [
|
const generateFolderId = () => `nav-folder-${dayjs().toISOString()}-${Math.random().toString().slice(2, 4)}`;
|
||||||
{ type: 'item', key: 'feed' },
|
|
||||||
{ type: 'item', key: 'friends-locations' },
|
|
||||||
{ type: 'item', key: 'game-log' },
|
|
||||||
{ type: 'item', key: 'player-list' },
|
|
||||||
{ type: 'item', key: 'search' },
|
|
||||||
{
|
|
||||||
type: 'folder',
|
|
||||||
id: 'default-folder-favorites',
|
|
||||||
name: t('nav_tooltip.favorites'),
|
|
||||||
icon: 'ri-star-line',
|
|
||||||
items: ['favorite-friends', 'favorite-worlds', 'favorite-avatars']
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'folder',
|
|
||||||
id: 'default-folder-social',
|
|
||||||
name: t('nav_tooltip.social'),
|
|
||||||
icon: 'ri-group-line',
|
|
||||||
items: ['friend-log', 'friend-list', 'moderation']
|
|
||||||
},
|
|
||||||
{ type: 'item', key: 'notification' },
|
|
||||||
{ type: 'item', key: 'charts' },
|
|
||||||
{ type: 'item', key: 'tools' }
|
|
||||||
];
|
|
||||||
|
|
||||||
const sanitizeLayout = (layout) => {
|
const sanitizeLayout = (layout) => {
|
||||||
const usedKeys = new Set();
|
const usedKeys = new Set();
|
||||||
@@ -523,10 +440,13 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (folderItems.length >= 2) {
|
if (folderItems.length >= 2) {
|
||||||
|
const folderNameKey = entry.nameKey || null;
|
||||||
|
const folderName = folderNameKey ? t(folderNameKey) : entry.name || '';
|
||||||
normalized.push({
|
normalized.push({
|
||||||
type: 'folder',
|
type: 'folder',
|
||||||
id: entry.id || generateFolderId(),
|
id: entry.id || generateFolderId(),
|
||||||
name: entry.name || '',
|
name: folderName,
|
||||||
|
nameKey: folderNameKey,
|
||||||
icon: entry.icon || DEFAULT_FOLDER_ICON,
|
icon: entry.icon || DEFAULT_FOLDER_ICON,
|
||||||
items: folderItems
|
items: folderItems
|
||||||
});
|
});
|
||||||
@@ -607,7 +527,7 @@
|
|||||||
cancelButtonText: t('nav_menu.custom_nav.cancel')
|
cancelButtonText: t('nav_menu.custom_nav.cancel')
|
||||||
})
|
})
|
||||||
.then(async () => {
|
.then(async () => {
|
||||||
const defaults = sanitizeLayout(defaultNavLayout);
|
const defaults = sanitizeLayout(createDefaultNavLayout());
|
||||||
navLayout.value = defaults;
|
navLayout.value = defaults;
|
||||||
await saveNavLayout(defaults);
|
await saveNavLayout(defaults);
|
||||||
customNavDialogVisible.value = false;
|
customNavDialogVisible.value = false;
|
||||||
@@ -630,7 +550,7 @@
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to load custom nav', error);
|
console.error('Failed to load custom nav', error);
|
||||||
} finally {
|
} finally {
|
||||||
const fallbackLayout = layoutData?.length ? layoutData : defaultNavLayout;
|
const fallbackLayout = layoutData?.length ? layoutData : createDefaultNavLayout();
|
||||||
navLayout.value = sanitizeLayout(fallbackLayout);
|
navLayout.value = sanitizeLayout(fallbackLayout);
|
||||||
navLayoutReady.value = true;
|
navLayoutReady.value = true;
|
||||||
navigateToFirstNavEntry();
|
navigateToFirstNavEntry();
|
||||||
@@ -644,15 +564,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const supportLinks = {
|
|
||||||
wiki: 'https://github.com/vrcx-team/VRCX/wiki',
|
|
||||||
github: 'https://github.com/vrcx-team/VRCX',
|
|
||||||
discord: 'https://vrcx.app/discord'
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSupportLink = (id) => {
|
const handleSupportLink = (id) => {
|
||||||
supportMenuVisible.value = false;
|
supportMenuVisible.value = false;
|
||||||
const target = supportLinks[id];
|
const target = links[id];
|
||||||
if (target) {
|
if (target) {
|
||||||
openExternalLink(target);
|
openExternalLink(target);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,8 +31,8 @@
|
|||||||
"discord": "Join our Discord",
|
"discord": "Join our Discord",
|
||||||
"whats_new": "What's New?",
|
"whats_new": "What's New?",
|
||||||
"custom_nav": {
|
"custom_nav": {
|
||||||
"header": "Custom Navigation Menu",
|
"header": "Custom Navigation",
|
||||||
"dialog_title": "Customize Navigation",
|
"dialog_title": "Customize Navigation Menu",
|
||||||
"add_folder": "Add Folder",
|
"add_folder": "Add Folder",
|
||||||
"folder_name_placeholder": "Folder name",
|
"folder_name_placeholder": "Folder name",
|
||||||
"folder_icon_placeholder": "Icon class (e.g. ri-menu-fold-line)",
|
"folder_icon_placeholder": "Icon class (e.g. ri-menu-fold-line)",
|
||||||
|
|||||||
@@ -8,3 +8,5 @@ export * from './instance';
|
|||||||
export * from './world';
|
export * from './world';
|
||||||
export * from './moderation';
|
export * from './moderation';
|
||||||
export * from './themes';
|
export * from './themes';
|
||||||
|
export * from './link';
|
||||||
|
export * from './ui';
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
const links = {
|
||||||
|
wiki: 'https://github.com/vrcx-team/VRCX/wiki',
|
||||||
|
github: 'https://github.com/vrcx-team/VRCX',
|
||||||
|
discord: 'https://vrcx.app/discord'
|
||||||
|
};
|
||||||
|
|
||||||
|
export { links };
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
const navDefinitions = [
|
||||||
|
{
|
||||||
|
key: 'feed',
|
||||||
|
icon: 'ri-rss-line',
|
||||||
|
tooltip: 'nav_tooltip.feed',
|
||||||
|
labelKey: 'nav_tooltip.feed',
|
||||||
|
routeName: 'feed'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'friends-locations',
|
||||||
|
icon: 'ri-user-location-line',
|
||||||
|
tooltip: 'nav_tooltip.friends_locations',
|
||||||
|
labelKey: 'nav_tooltip.friends_locations',
|
||||||
|
routeName: 'friends-locations'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'game-log',
|
||||||
|
icon: 'ri-history-line',
|
||||||
|
tooltip: 'nav_tooltip.game_log',
|
||||||
|
labelKey: 'nav_tooltip.game_log',
|
||||||
|
routeName: 'game-log'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'player-list',
|
||||||
|
icon: 'ri-group-3-line',
|
||||||
|
tooltip: 'nav_tooltip.player_list',
|
||||||
|
labelKey: 'nav_tooltip.player_list',
|
||||||
|
routeName: 'player-list'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'search',
|
||||||
|
icon: 'ri-search-line',
|
||||||
|
tooltip: 'nav_tooltip.search',
|
||||||
|
labelKey: 'nav_tooltip.search',
|
||||||
|
routeName: 'search'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'favorite-friends',
|
||||||
|
icon: 'ri-heart-2-line',
|
||||||
|
tooltip: 'nav_tooltip.favorite_friends',
|
||||||
|
labelKey: 'nav_tooltip.favorite_friends',
|
||||||
|
routeName: 'favorite-friends'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'favorite-worlds',
|
||||||
|
icon: 'ri-earth-line',
|
||||||
|
tooltip: 'nav_tooltip.favorite_worlds',
|
||||||
|
labelKey: 'nav_tooltip.favorite_worlds',
|
||||||
|
routeName: 'favorite-worlds'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'favorite-avatars',
|
||||||
|
icon: 'ri-user-heart-line',
|
||||||
|
tooltip: 'nav_tooltip.favorite_avatars',
|
||||||
|
labelKey: 'nav_tooltip.favorite_avatars',
|
||||||
|
routeName: 'favorite-avatars'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'friend-log',
|
||||||
|
icon: 'ri-booklet-line',
|
||||||
|
tooltip: 'nav_tooltip.friend_log',
|
||||||
|
labelKey: 'nav_tooltip.friend_log',
|
||||||
|
routeName: 'friend-log'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'friend-list',
|
||||||
|
icon: 'ri-group-line',
|
||||||
|
tooltip: 'nav_tooltip.friend_list',
|
||||||
|
labelKey: 'nav_tooltip.friend_list',
|
||||||
|
routeName: 'friend-list'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'moderation',
|
||||||
|
icon: 'ri-shield-user-line',
|
||||||
|
tooltip: 'nav_tooltip.moderation',
|
||||||
|
labelKey: 'nav_tooltip.moderation',
|
||||||
|
routeName: 'moderation'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'notification',
|
||||||
|
icon: 'ri-notification-2-line',
|
||||||
|
tooltip: 'nav_tooltip.notification',
|
||||||
|
labelKey: 'nav_tooltip.notification',
|
||||||
|
routeName: 'notification'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'charts',
|
||||||
|
icon: 'ri-bar-chart-line',
|
||||||
|
tooltip: 'nav_tooltip.charts',
|
||||||
|
labelKey: 'nav_tooltip.charts',
|
||||||
|
routeName: 'charts'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'tools',
|
||||||
|
icon: 'ri-tools-line',
|
||||||
|
tooltip: 'nav_tooltip.tools',
|
||||||
|
labelKey: 'nav_tooltip.tools',
|
||||||
|
routeName: 'tools'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
export { navDefinitions };
|
||||||
@@ -18,16 +18,16 @@
|
|||||||
}}</span>
|
}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="x-friend-item" @click="openExternalLink('https://github.com/vrcx-team/VRCX')">
|
<div class="x-friend-item" @click="openExternalLink(links.github)">
|
||||||
<div class="detail">
|
<div class="detail">
|
||||||
<span class="name">{{ t('view.settings.general.general.repository_url') }}</span>
|
<span class="name">{{ t('view.settings.general.general.repository_url') }}</span>
|
||||||
<span v-once class="extra">https://github.com/vrcx-team/VRCX</span>
|
<span v-once class="extra">{{ links.github }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="x-friend-item" @click="openExternalLink('https://vrcx.app/discord')">
|
<div class="x-friend-item" @click="openExternalLink(links.discord)">
|
||||||
<div class="detail">
|
<div class="detail">
|
||||||
<span class="name">{{ t('view.settings.general.general.support') }}</span>
|
<span class="name">{{ t('view.settings.general.general.support') }}</span>
|
||||||
<span v-once class="extra">https://vrcx.app/discord</span>
|
<span v-once class="extra">{{ links.discord }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -301,6 +301,7 @@
|
|||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
import { useFavoriteStore, useGeneralSettingsStore, useVRCXUpdaterStore, useVrStore } from '../../../../stores';
|
import { useFavoriteStore, useGeneralSettingsStore, useVRCXUpdaterStore, useVrStore } from '../../../../stores';
|
||||||
|
import { links } from '../../../../shared/constants';
|
||||||
import { openExternalLink } from '../../../../shared/utils';
|
import { openExternalLink } from '../../../../shared/utils';
|
||||||
|
|
||||||
import SimpleSwitch from '../SimpleSwitch.vue';
|
import SimpleSwitch from '../SimpleSwitch.vue';
|
||||||
|
|||||||
Reference in New Issue
Block a user