mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-04-12 19:33:50 +02:00
* feat: Friends Sidebar Group By Instance * fix and improve performance of filter data * rm log
This commit is contained in:
89
src/app.js
89
src/app.js
@@ -185,6 +185,10 @@ console.log(`isLinux: ${LINUX}`);
|
||||
this.checkForVRCXUpdate();
|
||||
}
|
||||
await AppApi.CheckGameRunning();
|
||||
this.isSidebarGroupByInstance =
|
||||
(await configRepository.getBool(
|
||||
'VRCX_sidebarGroupByInstance'
|
||||
)) ?? true;
|
||||
this.isGameNoVR = await configRepository.getBool('isGameNoVR');
|
||||
await AppApi.SetAppLauncherSettings(
|
||||
this.enableAppLauncher,
|
||||
@@ -23108,6 +23112,91 @@ console.log(`isLinux: ${LINUX}`);
|
||||
return LINUX;
|
||||
};
|
||||
|
||||
// friendsListSiderBar
|
||||
$app.methods.handleSwitchGroupByInstance = async function () {
|
||||
this.isSidebarGroupByInstance = !this.isSidebarGroupByInstance;
|
||||
await configRepository.setBool(
|
||||
'VRCX_sidebarGroupByInstance',
|
||||
this.isSidebarGroupByInstance
|
||||
);
|
||||
};
|
||||
|
||||
// friendsListSidebar
|
||||
// - SidebarGroupByInstance
|
||||
|
||||
$app.data.isSidebarGroupByInstance = true;
|
||||
$app.computed.onlineFriendsInSameInstance = function () {
|
||||
const groupedItems = {};
|
||||
|
||||
this.onlineFriends.forEach((item) => {
|
||||
const key = item.ref?.$location.tag;
|
||||
if (!key || key === 'private' || key === 'offline') return;
|
||||
if (!groupedItems[key]) {
|
||||
groupedItems[key] = [];
|
||||
}
|
||||
groupedItems[key].push(item);
|
||||
});
|
||||
|
||||
const sortedGroups = [];
|
||||
for (const group of Object.values(groupedItems)) {
|
||||
if (group.length > 1) {
|
||||
sortedGroups.push(
|
||||
group.sort(
|
||||
(a, b) => a.ref?.$location_at - b.ref?.$location_at
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return sortedGroups.sort((a, b) => b.length - a.length);
|
||||
};
|
||||
|
||||
$app.computed.onlineFriendsNotInSameInstance = function () {
|
||||
const friendsInSameInstance = new Set(
|
||||
this.onlineFriendsInSameInstance.flat().map((friend) => friend.id)
|
||||
);
|
||||
|
||||
return this.onlineFriends.filter(
|
||||
(friend) => !friendsInSameInstance.has(friend.id)
|
||||
);
|
||||
};
|
||||
|
||||
$app.computed.vipFriendsInSameInstance = function () {
|
||||
const groupedItems = {};
|
||||
|
||||
this.vipFriends.forEach((item) => {
|
||||
const key = item.ref?.$location.tag;
|
||||
if (!key || key === 'private' || key === 'offline') return;
|
||||
if (!groupedItems[key]) {
|
||||
groupedItems[key] = [];
|
||||
}
|
||||
groupedItems[key].push(item);
|
||||
});
|
||||
|
||||
const sortedGroups = [];
|
||||
for (const group of Object.values(groupedItems)) {
|
||||
if (group.length > 1) {
|
||||
sortedGroups.push(
|
||||
group.sort(
|
||||
(a, b) => a.ref?.$location_at - b.ref?.$location_at
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return sortedGroups.sort((a, b) => b.length - a.length);
|
||||
};
|
||||
|
||||
$app.computed.vipFriendsNotInSameInstance = function () {
|
||||
const friendsInSameInstance = new Set(
|
||||
this.vipFriendsInSameInstance.flat().map((friend) => friend.id)
|
||||
);
|
||||
|
||||
return this.vipFriends.filter(
|
||||
(friend) => !friendsInSameInstance.has(friend.id)
|
||||
);
|
||||
};
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region | Electron
|
||||
|
||||
@@ -383,7 +383,9 @@
|
||||
"placeholder": "Sort Order",
|
||||
"dropdown_header": "Choose Sort Order"
|
||||
},
|
||||
"width": "Width"
|
||||
"width": "Width",
|
||||
"group_by_instance": "Group by Instance",
|
||||
"group_by_instance_tooltip": "Enabling this will group friends by instance when there is more than one friend in the same instance."
|
||||
},
|
||||
"user_dialog": {
|
||||
"header": "User Dialog",
|
||||
@@ -2011,4 +2013,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -40,34 +40,102 @@ mixin friendsListSidebar()
|
||||
i.el-icon-arrow-right(:class="{ rotate: isVIPFriends }")
|
||||
span(style="margin-left:5px") {{ $t('side_panel.favorite') }} ― {{ vipFriends.length }}
|
||||
div(v-show="isVIPFriends")
|
||||
.x-friend-item(v-for="friend in vipFriends" :key="friend.id" @click="showUserDialog(friend.id)")
|
||||
template(v-if="friend.ref")
|
||||
.avatar(:class="userStatusClass(friend.ref, friend.pendingOffline)")
|
||||
img(v-lazy="userImage(friend.ref)")
|
||||
.detail
|
||||
span.name(v-if="!hideNicknames && friend.$nickName" :style="{'color':friend.ref.$userColour}") {{ friend.ref.displayName }} ({{ friend.$nickName }})
|
||||
span.name(v-else v-text="friend.ref.displayName" :style="{'color':friend.ref.$userColour}")
|
||||
span.extra(v-if="friend.pendingOffline") #[i.el-icon-warning-outline] {{ $t('side_panel.pending_offline') }}
|
||||
location.extra(v-else :location="friend.ref.location" :traveling="friend.ref.travelingToLocation" :link="false")
|
||||
template(v-else)
|
||||
span(v-text="friend.name || friend.id")
|
||||
el-button(type="text" icon="el-icon-close" size="mini" @click.stop="confirmDeleteFriend(friend.id)" style="margin-left:5px")
|
||||
template(v-if='isSidebarGroupByInstance')
|
||||
div(v-for="(friendArr, idx) in vipFriendsInSameInstance" :key="friendArr[0].ref?.location.tag")
|
||||
div(style="margin-bottom: 3px")
|
||||
location.extra(:location="friendArr[0].ref?.location" style="color:#c7c7c7")
|
||||
span(style="margin-left: 5px") {{ `(${friendArr.length})` }}
|
||||
div(style="margin-bottom: 10px")
|
||||
div.x-friend-item(v-if="friendArr && friendArr.length" v-for="friend in friendArr" :key="friend.id" @click="showUserDialog(friend.id)")
|
||||
template(v-if="friend.ref")
|
||||
.avatar(:class="userStatusClass(friend.ref, friend.pendingOffline)")
|
||||
img(v-lazy="userImage(friend.ref)")
|
||||
.detail
|
||||
span.name(v-if="!hideNicknames && friend.$nickName" :style="{'color':friend.ref.$userColour}") {{ friend.ref.displayName }} ({{ friend.$nickName }})
|
||||
span.name(v-else v-text="friend.ref.displayName" :style="{'color':friend.ref.$userColour}")
|
||||
span.extra(v-if="friend.pendingOffline") #[i.el-icon-warning-outline] {{ $t('side_panel.pending_offline') }}
|
||||
template(v-else)
|
||||
i(v-if="friend.ref.travelingToLocation" class="el-icon el-icon-loading" style="display:inline-block;margin-right:5px")
|
||||
timer(:epoch="friend.ref?.$location_at" style="color:#c7c7c7")
|
||||
template(v-else)
|
||||
span(v-text="friend.name || friend.id")
|
||||
el-button(type="text" icon="el-icon-close" size="mini" @click.stop="confirmDeleteFriend(friend.id)" style="margin-left:5px")
|
||||
div(v-if="idx === vipFriendsInSameInstance.length - 1" style="color:#c7c7c7") {{ "Others" }}
|
||||
.x-friend-item(v-for="friend in vipFriendsNotInSameInstance" :key="friend.id" @click="showUserDialog(friend.id)")
|
||||
template(v-if="friend.ref")
|
||||
.avatar(:class="userStatusClass(friend.ref, friend.pendingOffline)")
|
||||
img(v-lazy="userImage(friend.ref)")
|
||||
.detail
|
||||
span.name(v-if="!hideNicknames && friend.$nickName" :style="{'color':friend.ref.$userColour}") {{ friend.ref.displayName }} ({{ friend.$nickName }})
|
||||
span.name(v-else v-text="friend.ref.displayName" :style="{'color':friend.ref.$userColour}")
|
||||
span.extra(v-if="friend.pendingOffline") #[i.el-icon-warning-outline] {{ $t('side_panel.pending_offline') }}
|
||||
location.extra(v-else :location="friend.ref.location" :traveling="friend.ref.travelingToLocation" :link="false")
|
||||
template(v-else)
|
||||
span(v-text="friend.name || friend.id")
|
||||
el-button(type="text" icon="el-icon-close" size="mini" @click.stop="confirmDeleteFriend(friend.id)" style="margin-left:5px")
|
||||
template(v-else)
|
||||
.x-friend-item(v-for="friend in vipFriends" :key="friend.id" @click="showUserDialog(friend.id)")
|
||||
template(v-if="friend.ref")
|
||||
.avatar(:class="userStatusClass(friend.ref, friend.pendingOffline)")
|
||||
img(v-lazy="userImage(friend.ref)")
|
||||
.detail
|
||||
span.name(v-if="!hideNicknames && friend.$nickName" :style="{'color':friend.ref.$userColour}") {{ friend.ref.displayName }} ({{ friend.$nickName }})
|
||||
span.name(v-else v-text="friend.ref.displayName" :style="{'color':friend.ref.$userColour}")
|
||||
span.extra(v-if="friend.pendingOffline") #[i.el-icon-warning-outline] {{ $t('side_panel.pending_offline') }}
|
||||
location.extra(v-else :location="friend.ref.location" :traveling="friend.ref.travelingToLocation" :link="false")
|
||||
template(v-else)
|
||||
span(v-text="friend.name || friend.id")
|
||||
el-button(type="text" icon="el-icon-close" size="mini" @click.stop="confirmDeleteFriend(friend.id)" style="margin-left:5px")
|
||||
.x-friend-group.x-link(@click="isOnlineFriends = !isOnlineFriends; saveFriendsGroupStates()" v-show="onlineFriends.length")
|
||||
i.el-icon-arrow-right(:class="{ rotate: isOnlineFriends }")
|
||||
span(style="margin-left:5px") {{ $t('side_panel.online') }} ― {{ onlineFriends.length }}
|
||||
div(v-show="isOnlineFriends")
|
||||
.x-friend-item(v-for="friend in onlineFriends" :key="friend.id" @click="showUserDialog(friend.id)")
|
||||
template(v-if="friend.ref")
|
||||
.avatar(:class="userStatusClass(friend.ref, friend.pendingOffline)")
|
||||
img(v-lazy="userImage(friend.ref)")
|
||||
.detail
|
||||
span.name(v-if="!hideNicknames && friend.$nickName" :style="{'color':friend.ref.$userColour}") {{ friend.ref.displayName }} ({{ friend.$nickName }})
|
||||
span.name(v-else v-text="friend.ref.displayName" :style="{'color':friend.ref.$userColour}")
|
||||
span.extra(v-if="friend.pendingOffline") #[i.el-icon-warning-outline] {{ $t('side_panel.pending_offline') }}
|
||||
location.extra(v-else :location="friend.ref.location" :traveling="friend.ref.travelingToLocation" :link="false")
|
||||
template(v-else)
|
||||
span(v-text="friend.name || friend.id")
|
||||
el-button(type="text" icon="el-icon-close" size="mini" @click.stop="confirmDeleteFriend(friend.id)" style="margin-left:5px")
|
||||
template(v-if='isSidebarGroupByInstance')
|
||||
div(v-for="(friendArr, idx) in onlineFriendsInSameInstance" :key="friendArr[0].ref?.location.tag")
|
||||
div(style="margin-bottom: 3px")
|
||||
location.extra(:location="friendArr[0].ref?.location" style="color:#c7c7c7")
|
||||
span(style="margin-left: 5px") {{ `(${friendArr.length})` }}
|
||||
div(style="margin-bottom: 10px")
|
||||
div.x-friend-item(v-if="friendArr && friendArr.length" v-for="friend in friendArr" :key="friend.id" @click="showUserDialog(friend.id)")
|
||||
template(v-if="friend.ref")
|
||||
.avatar(:class="userStatusClass(friend.ref, friend.pendingOffline)")
|
||||
img(v-lazy="userImage(friend.ref)")
|
||||
.detail
|
||||
span.name(v-if="!hideNicknames && friend.$nickName" :style="{'color':friend.ref.$userColour}") {{ friend.ref.displayName }} ({{ friend.$nickName }})
|
||||
span.name(v-else v-text="friend.ref.displayName" :style="{'color':friend.ref.$userColour}")
|
||||
span.extra(v-if="friend.pendingOffline") #[i.el-icon-warning-outline] {{ $t('side_panel.pending_offline') }}
|
||||
template(v-else)
|
||||
i(v-if="friend.ref.travelingToLocation" class="el-icon el-icon-loading" style="display:inline-block;margin-right:5px")
|
||||
timer(:epoch="friend.ref?.$location_at" style="color:#c7c7c7")
|
||||
template(v-else)
|
||||
span(v-text="friend.name || friend.id")
|
||||
el-button(type="text" icon="el-icon-close" size="mini" @click.stop="confirmDeleteFriend(friend.id)" style="margin-left:5px")
|
||||
div(v-if="idx === onlineFriendsInSameInstance.length - 1" style="color:#c7c7c7") {{ "Others" }}
|
||||
.x-friend-item(v-for="friend in onlineFriendsNotInSameInstance" :key="friend.id" @click="showUserDialog(friend.id)")
|
||||
template(v-if="friend.ref")
|
||||
.avatar(:class="userStatusClass(friend.ref, friend.pendingOffline)")
|
||||
img(v-lazy="userImage(friend.ref)")
|
||||
.detail
|
||||
span.name(v-if="!hideNicknames && friend.$nickName" :style="{'color':friend.ref.$userColour}") {{ friend.ref.displayName }} ({{ friend.$nickName }})
|
||||
span.name(v-else v-text="friend.ref.displayName" :style="{'color':friend.ref.$userColour}")
|
||||
span.extra(v-if="friend.pendingOffline") #[i.el-icon-warning-outline] {{ $t('side_panel.pending_offline') }}
|
||||
location.extra(v-else :location="friend.ref.location" :traveling="friend.ref.travelingToLocation" :link="false")
|
||||
template(v-else)
|
||||
span(v-text="friend.name || friend.id")
|
||||
el-button(type="text" icon="el-icon-close" size="mini" @click.stop="confirmDeleteFriend(friend.id)" style="margin-left:5px")
|
||||
template(v-else)
|
||||
.x-friend-item(v-for="friend in onlineFriends" :key="friend.id" @click="showUserDialog(friend.id)")
|
||||
template(v-if="friend.ref")
|
||||
.avatar(:class="userStatusClass(friend.ref, friend.pendingOffline)")
|
||||
img(v-lazy="userImage(friend.ref)")
|
||||
.detail
|
||||
span.name(v-if="!hideNicknames && friend.$nickName" :style="{'color':friend.ref.$userColour}") {{ friend.ref.displayName }} ({{ friend.$nickName }})
|
||||
span.name(v-else v-text="friend.ref.displayName" :style="{'color':friend.ref.$userColour}")
|
||||
span.extra(v-if="friend.pendingOffline") #[i.el-icon-warning-outline] {{ $t('side_panel.pending_offline') }}
|
||||
location.extra(v-else :location="friend.ref.location" :traveling="friend.ref.travelingToLocation" :link="false")
|
||||
template(v-else)
|
||||
span(v-text="friend.name || friend.id")
|
||||
el-button(type="text" icon="el-icon-close" size="mini" @click.stop="confirmDeleteFriend(friend.id)" style="margin-left:5px")
|
||||
.x-friend-group.x-link(@click="isActiveFriends = !isActiveFriends; saveFriendsGroupStates()" v-show="activeFriends.length")
|
||||
i.el-icon-arrow-right(:class="{ rotate: isActiveFriends }")
|
||||
span(style="margin-left:5px") {{ $t('side_panel.active') }} ― {{ activeFriends.length }}
|
||||
|
||||
@@ -231,6 +231,8 @@ mixin settingsTab()
|
||||
div.options-container-item
|
||||
span.name(style="vertical-align:top;padding-top:10px") {{ $t('view.settings.appearance.side_panel.width') }}
|
||||
el-slider(v-model="asideWidth" @input="setAsideWidth" :show-tooltip="false" :marks="{300: ''}" :min="200" :max="500" style="display:inline-block;width:300px")
|
||||
div.options-container-item
|
||||
simple-switch(:label='$t("view.settings.appearance.side_panel.group_by_instance")' :value='isSidebarGroupByInstance' @change='handleSwitchGroupByInstance' :tooltip='$t("view.settings.appearance.side_panel.group_by_instance_tooltip")')
|
||||
//- Appearance | User Dialog
|
||||
div.options-container
|
||||
span.header {{ $t('view.settings.appearance.user_dialog.header') }}
|
||||
|
||||
Reference in New Issue
Block a user