mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-05-07 06:56:04 +02:00
feat: add resizable sidebar with splitter layout
This commit is contained in:
+28
-20
@@ -13,39 +13,42 @@
|
|||||||
<VRCXUpdateDialog></VRCXUpdateDialog>
|
<VRCXUpdateDialog></VRCXUpdateDialog>
|
||||||
|
|
||||||
<template v-if="watchState.isLoggedIn">
|
<template v-if="watchState.isLoggedIn">
|
||||||
<!-- ### Menu ### -->
|
|
||||||
<NavMenu></NavMenu>
|
<NavMenu></NavMenu>
|
||||||
|
|
||||||
<!-- ### Sidebar ### -->
|
<el-splitter @resize-end="setAsideWidth" v-show="isSideBarTabShow">
|
||||||
<Sidebar></Sidebar>
|
<el-splitter-panel>
|
||||||
|
<Feed></Feed>
|
||||||
|
|
||||||
<!-- ### Tabs ### -->
|
<GameLog></GameLog>
|
||||||
<Feed></Feed>
|
|
||||||
|
|
||||||
<GameLog></GameLog>
|
<PlayerList></PlayerList>
|
||||||
|
|
||||||
<PlayerList></PlayerList>
|
<Search></Search>
|
||||||
|
|
||||||
<Search></Search>
|
<Favorites></Favorites>
|
||||||
|
|
||||||
<Favorites></Favorites>
|
<FriendLog></FriendLog>
|
||||||
|
|
||||||
<FriendLog></FriendLog>
|
<Moderation></Moderation>
|
||||||
|
|
||||||
<Moderation></Moderation>
|
<Notification></Notification>
|
||||||
|
|
||||||
<Notification></Notification>
|
<Tools></Tools>
|
||||||
|
|
||||||
|
<Profile></Profile>
|
||||||
|
|
||||||
|
<Settings></Settings>
|
||||||
|
</el-splitter-panel>
|
||||||
|
|
||||||
|
<el-splitter-panel :min="200" :max="700" :size="asideWidth">
|
||||||
|
<Sidebar></Sidebar>
|
||||||
|
</el-splitter-panel>
|
||||||
|
</el-splitter>
|
||||||
|
|
||||||
<FriendList></FriendList>
|
<FriendList></FriendList>
|
||||||
|
|
||||||
<Charts></Charts>
|
<Charts></Charts>
|
||||||
|
|
||||||
<Tools></Tools>
|
|
||||||
|
|
||||||
<Profile></Profile>
|
|
||||||
|
|
||||||
<Settings></Settings>
|
|
||||||
|
|
||||||
<!-- ## Dialogs ## -->
|
<!-- ## Dialogs ## -->
|
||||||
<UserDialog></UserDialog>
|
<UserDialog></UserDialog>
|
||||||
|
|
||||||
@@ -137,9 +140,10 @@
|
|||||||
import PrimaryPasswordDialog from './views/Settings/dialogs/PrimaryPasswordDialog.vue';
|
import PrimaryPasswordDialog from './views/Settings/dialogs/PrimaryPasswordDialog.vue';
|
||||||
|
|
||||||
import { onMounted, computed, onBeforeMount } from 'vue';
|
import { onMounted, computed, onBeforeMount } from 'vue';
|
||||||
import { createGlobalStores } from './stores';
|
|
||||||
import { watchState } from './service/watchState';
|
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
|
import { createGlobalStores, useAppearanceSettingsStore } from './stores';
|
||||||
|
import { watchState } from './service/watchState';
|
||||||
import { initNoty } from './plugin/noty';
|
import { initNoty } from './plugin/noty';
|
||||||
|
|
||||||
console.log(`isLinux: ${LINUX}`);
|
console.log(`isLinux: ${LINUX}`);
|
||||||
@@ -186,4 +190,8 @@
|
|||||||
store.vrcx.checkAutoBackupRestoreVrcRegistry();
|
store.vrcx.checkAutoBackupRestoreVrcRegistry();
|
||||||
store.game.checkVRChatDebugLogging();
|
store.game.checkVRChatDebugLogging();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const appearanceStore = useAppearanceSettingsStore();
|
||||||
|
const { setAsideWidth } = appearanceStore;
|
||||||
|
const { asideWidth, isSideBarTabShow } = storeToRefs(appearanceStore);
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -241,6 +241,8 @@ a {
|
|||||||
padding: 10px;
|
padding: 10px;
|
||||||
overflow: hidden auto;
|
overflow: hidden auto;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
|
box-sizing: border-box;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.x-login-container {
|
.x-login-container {
|
||||||
@@ -366,6 +368,8 @@ hr.x-vertical-divider {
|
|||||||
background: #f8f8f8;
|
background: #f8f8f8;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
order: 99;
|
order: 99;
|
||||||
|
height: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
// .el-popper.x-quick-search {
|
// .el-popper.x-quick-search {
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import { useNotificationStore } from '../notification';
|
|||||||
import { useUserStore } from '../user';
|
import { useUserStore } from '../user';
|
||||||
import { useVrStore } from '../vr';
|
import { useVrStore } from '../vr';
|
||||||
import { useVrcxStore } from '../vrcx';
|
import { useVrcxStore } from '../vrcx';
|
||||||
|
import { useUiStore } from '../ui';
|
||||||
|
|
||||||
export const useAppearanceSettingsStore = defineStore(
|
export const useAppearanceSettingsStore = defineStore(
|
||||||
'AppearanceSettings',
|
'AppearanceSettings',
|
||||||
@@ -36,6 +37,7 @@ export const useAppearanceSettingsStore = defineStore(
|
|||||||
const gameLogStore = useGameLogStore();
|
const gameLogStore = useGameLogStore();
|
||||||
const vrcxStore = useVrcxStore();
|
const vrcxStore = useVrcxStore();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
const uiStore = useUiStore();
|
||||||
|
|
||||||
const { t, availableLocales, locale } = useI18n();
|
const { t, availableLocales, locale } = useI18n();
|
||||||
|
|
||||||
@@ -250,6 +252,12 @@ export const useAppearanceSettingsStore = defineStore(
|
|||||||
const randomUserColours = computed(() => state.randomUserColours);
|
const randomUserColours = computed(() => state.randomUserColours);
|
||||||
const trustColor = computed(() => state.trustColor);
|
const trustColor = computed(() => state.trustColor);
|
||||||
const currentCulture = computed(() => state.currentCulture);
|
const currentCulture = computed(() => state.currentCulture);
|
||||||
|
const isSideBarTabShow = computed(() => {
|
||||||
|
return !(
|
||||||
|
uiStore.menuActiveIndex === 'friendList' ||
|
||||||
|
uiStore.menuActiveIndex === 'charts'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => watchState.isFriendsLoaded,
|
() => watchState.isFriendsLoaded,
|
||||||
@@ -521,13 +529,19 @@ export const useAppearanceSettingsStore = defineStore(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @param {number} width
|
* @param {number} panelNumber
|
||||||
|
* @param {Array<number>} widthArray
|
||||||
*/
|
*/
|
||||||
function setAsideWidth(width) {
|
function setAsideWidth(panelNumber, widthArray) {
|
||||||
requestAnimationFrame(() => {
|
if (Array.isArray(widthArray) && widthArray[1]) {
|
||||||
state.asideWidth = width;
|
requestAnimationFrame(() => {
|
||||||
configRepository.setInt('VRCX_sidePanelWidth', width);
|
state.asideWidth = widthArray[1];
|
||||||
});
|
configRepository.setInt(
|
||||||
|
'VRCX_sidePanelWidth',
|
||||||
|
widthArray[1]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
function setIsSidebarGroupByInstance() {
|
function setIsSidebarGroupByInstance() {
|
||||||
state.isSidebarGroupByInstance = !state.isSidebarGroupByInstance;
|
state.isSidebarGroupByInstance = !state.isSidebarGroupByInstance;
|
||||||
@@ -735,6 +749,7 @@ export const useAppearanceSettingsStore = defineStore(
|
|||||||
randomUserColours,
|
randomUserColours,
|
||||||
trustColor,
|
trustColor,
|
||||||
currentCulture,
|
currentCulture,
|
||||||
|
isSideBarTabShow,
|
||||||
|
|
||||||
setAppLanguage,
|
setAppLanguage,
|
||||||
setDisplayVRCPlusIconsAsAvatar,
|
setDisplayVRCPlusIconsAsAvatar,
|
||||||
|
|||||||
@@ -586,19 +586,6 @@
|
|||||||
</el-option-group>
|
</el-option-group>
|
||||||
</el-select>
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
<div class="options-container-item">
|
|
||||||
<span class="name" style="vertical-align: top; padding-top: 10px">{{
|
|
||||||
t('view.settings.appearance.side_panel.width')
|
|
||||||
}}</span>
|
|
||||||
<el-slider
|
|
||||||
:model-value="asideWidth"
|
|
||||||
:show-tooltip="false"
|
|
||||||
:marks="{ 300: '' }"
|
|
||||||
:min="200"
|
|
||||||
:max="500"
|
|
||||||
style="display: inline-block; width: 300px; padding-top: 16px"
|
|
||||||
@input="setAsideWidth"></el-slider>
|
|
||||||
</div>
|
|
||||||
<simple-switch
|
<simple-switch
|
||||||
:label="t('view.settings.appearance.side_panel.group_by_instance')"
|
:label="t('view.settings.appearance.side_panel.group_by_instance')"
|
||||||
:value="isSidebarGroupByInstance"
|
:value="isSidebarGroupByInstance"
|
||||||
@@ -2075,7 +2062,6 @@
|
|||||||
setSidebarSortMethod1,
|
setSidebarSortMethod1,
|
||||||
setSidebarSortMethod2,
|
setSidebarSortMethod2,
|
||||||
setSidebarSortMethod3,
|
setSidebarSortMethod3,
|
||||||
setAsideWidth,
|
|
||||||
setIsSidebarGroupByInstance,
|
setIsSidebarGroupByInstance,
|
||||||
setIsHideFriendsInSameInstance,
|
setIsHideFriendsInSameInstance,
|
||||||
setIsSidebarDivideByFriendGroup,
|
setIsSidebarDivideByFriendGroup,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-show="isSideBarTabShow" id="aside" class="x-aside-container" :style="{ width: `${asideWidth}px` }">
|
<div class="x-aside-container">
|
||||||
<div style="display: flex; align-items: baseline">
|
<div style="display: flex; align-items: baseline">
|
||||||
<el-select
|
<el-select
|
||||||
clearable
|
clearable
|
||||||
@@ -81,31 +81,18 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { Refresh, Compass } from '@element-plus/icons-vue';
|
import { Refresh, Compass } from '@element-plus/icons-vue';
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import { computed } from 'vue';
|
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { userImage } from '../../shared/utils';
|
import { userImage } from '../../shared/utils';
|
||||||
import {
|
import { useFriendStore, useGroupStore, useSearchStore } from '../../stores';
|
||||||
useAppearanceSettingsStore,
|
|
||||||
useFriendStore,
|
|
||||||
useGroupStore,
|
|
||||||
useSearchStore,
|
|
||||||
useUiStore
|
|
||||||
} from '../../stores';
|
|
||||||
import FriendsSidebar from './components/FriendsSidebar.vue';
|
import FriendsSidebar from './components/FriendsSidebar.vue';
|
||||||
import GroupsSidebar from './components/GroupsSidebar.vue';
|
import GroupsSidebar from './components/GroupsSidebar.vue';
|
||||||
|
|
||||||
const { friends, isRefreshFriendsLoading, onlineFriendCount } = storeToRefs(useFriendStore());
|
const { friends, isRefreshFriendsLoading, onlineFriendCount } = storeToRefs(useFriendStore());
|
||||||
const { refreshFriendsList, confirmDeleteFriend } = useFriendStore();
|
const { refreshFriendsList, confirmDeleteFriend } = useFriendStore();
|
||||||
const { asideWidth } = storeToRefs(useAppearanceSettingsStore());
|
|
||||||
const { menuActiveIndex } = storeToRefs(useUiStore());
|
|
||||||
const { quickSearchRemoteMethod, quickSearchChange, directAccessPaste } = useSearchStore();
|
const { quickSearchRemoteMethod, quickSearchChange, directAccessPaste } = useSearchStore();
|
||||||
const { quickSearchItems } = storeToRefs(useSearchStore());
|
const { quickSearchItems } = storeToRefs(useSearchStore());
|
||||||
const { inGameGroupOrder, groupInstances } = storeToRefs(useGroupStore());
|
const { inGameGroupOrder, groupInstances } = storeToRefs(useGroupStore());
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
const isSideBarTabShow = computed(() => {
|
|
||||||
return !(menuActiveIndex.value === 'friendList' || menuActiveIndex.value === 'charts');
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
Reference in New Issue
Block a user