Skip to content

Commit

Permalink
User dialog group sorting, fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Natsumi-sama committed Nov 7, 2024
1 parent 253b537 commit 8bc3b7f
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 40 deletions.
4 changes: 2 additions & 2 deletions Dotnet/AssetBundleCacher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ public int ReverseHexToDecimal(string hexString)
return 0; // it's cooked

try {
var versionHexString = hexString.Substring(16, 8); // 16..24
var variantVersionHexString = hexString.Substring(24, 8); // 24..32
var variantVersionHexString = hexString.Substring(16, 8); // 16..24
var versionHexString = hexString.Substring(24, 8); // 24..32
var versionBytes = new byte[4];
var variantVersionBytes = new byte[4];
for (var i = 0; i < 4; i++)
Expand Down
146 changes: 112 additions & 34 deletions html/src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -4412,6 +4412,7 @@ speechSynthesis.getVoices();
if (typeof ctx === 'undefined') {
return;
}
var ref = API.cachedUsers.get(id);
if (stateInput) {
ctx.pendingState = stateInput;
if (typeof ref !== 'undefined') {
Expand All @@ -4426,7 +4427,6 @@ speechSynthesis.getVoices();
ctx.pendingOffline = false;
ctx.pendingOfflineTime = '';
}
var ref = API.cachedUsers.get(id);
var isVIP = this.localFavoriteFriends.has(id);
var location = '';
var $location_at = '';
Expand Down Expand Up @@ -4513,6 +4513,9 @@ speechSynthesis.getVoices();
}
return;
}
if (this.debugFriendState) {
console.log(ctx.name, 'pendingOfflineBegin');
}
ctx.pendingOffline = true;
ctx.pendingOfflineTime = Date.now();
// wait 2minutes then check if user came back online
Expand All @@ -4534,6 +4537,9 @@ speechSynthesis.getVoices();
}
return;
}
if (this.debugFriendState) {
console.log(ctx.name, 'pendingOfflineEnd');
}
this.updateFriendDelayedCheck(ctx, location, $location_at);
}, this.pendingOfflineDelay);
} else {
Expand Down Expand Up @@ -4772,6 +4778,16 @@ speechSynthesis.getVoices();
return 0;
};

var compareByMemberCount = function (a, b) {
if (
typeof a.memberCount !== 'number' ||
typeof b.memberCount !== 'number'
) {
return 0;
}
return a.memberCount - b.memberCount;
};

// private
var compareByPrivate = function (a, b) {
if (typeof a.ref === 'undefined' || typeof b.ref === 'undefined') {
Expand Down Expand Up @@ -8896,6 +8912,10 @@ speechSynthesis.getVoices();
name: $t('dialog.user.worlds.order.descending'),
value: 'descending'
},
groupSorting: {
name: $t('dialog.user.groups.sorting.alphabetical'),
value: 'alphabetical'
},
avatarSorting: 'update',
avatarReleaseStatus: 'all',

Expand Down Expand Up @@ -8948,6 +8968,15 @@ speechSynthesis.getVoices();
await this.refreshUserDialogWorlds();
};

$app.methods.setUserDialogGroupSorting = async function (sortOrder) {
var D = this.userDialog;
if (D.groupSorting === sortOrder) {
return;
}
D.groupSorting = sortOrder;
await this.sortCurrentUserGroups();
};

$app.methods.getFaviconUrl = function (resource) {
try {
var url = new URL(resource);
Expand Down Expand Up @@ -9292,10 +9321,7 @@ speechSynthesis.getVoices();
);
this.setUserDialogAvatars(userId);
this.userDialogLastAvatar = userId;
if (
userId === API.currentUser.id &&
D.avatars.length === 0
) {
if (userId === API.currentUser.id) {
this.refreshUserDialogAvatars();
}
this.setUserDialogAvatarsRemote(userId);
Expand Down Expand Up @@ -9934,6 +9960,7 @@ speechSynthesis.getVoices();

$app.methods.setUserDialogAvatarsRemote = async function (userId) {
if (this.avatarRemoteDatabase && userId !== API.currentUser.id) {
this.userDialog.isAvatarsLoading = true;
var data = await this.lookupAvatars('authorId', userId);
var avatars = new Set();
this.userDialogAvatars.forEach((avatar) => {
Expand All @@ -9942,12 +9969,19 @@ speechSynthesis.getVoices();
if (data && typeof data === 'object') {
data.forEach((avatar) => {
if (avatar.id && !avatars.has(avatar.id)) {
this.userDialog.avatars.push(avatar);
if (avatar.authorId === userId) {
this.userDialog.avatars.push(avatar);
} else {
console.error(
`Avatar authorId mismatch for ${avatar.id} - ${avatar.name}`
);
}
}
});
}
this.userDialog.avatarSorting = 'name';
this.userDialog.avatarReleaseStatus = 'all';
this.userDialog.isAvatarsLoading = false;
}
this.sortUserDialogAvatars(this.userDialog.avatars);
};
Expand Down Expand Up @@ -10145,6 +10179,8 @@ speechSynthesis.getVoices();
if (fileId) {
D.loading = true;
}
D.avatarSorting = 'update';
D.avatarReleaseStatus = 'all';
var params = {
n: 50,
offset: 0,
Expand Down Expand Up @@ -15520,10 +15556,7 @@ speechSynthesis.getVoices();
this.setUserDialogAvatars(userId);
if (this.userDialogLastAvatar !== userId) {
this.userDialogLastAvatar = userId;
if (
userId === API.currentUser.id &&
this.userDialog.avatars.length === 0
) {
if (userId === API.currentUser.id) {
this.refreshUserDialogAvatars();
} else {
this.setUserDialogAvatarsRemote(userId);
Expand Down Expand Up @@ -16765,10 +16798,18 @@ speechSynthesis.getVoices();
this.userGroups.remainingGroups.unshift(group);
}
}
this.userDialog.isGroupsLoading = false;
if (userId === API.currentUser.id) {
this.sortCurrentUserGroups();
this.userDialog.groupSorting =
this.userDialogGroupSortingOptions.inGame;
} else if (
this.userDialog.groupSorting ===
this.userDialogGroupSortingOptions.inGame
) {
this.userDialog.groupSorting =
this.userDialogGroupSortingOptions.alphabetical;
}
await this.sortCurrentUserGroups();
this.userDialog.isGroupsLoading = false;
};

$app.methods.getCurrentUserGroups = async function () {
Expand All @@ -16782,28 +16823,47 @@ speechSynthesis.getVoices();
this.saveCurrentUserGroups();
};

$app.methods.sortCurrentUserGroups = function () {
var groupList = [];
var sortGroups = function (a, b) {
var aIndex = groupList.indexOf(a?.id);
var bIndex = groupList.indexOf(b?.id);
if (aIndex === -1 && bIndex === -1) {
return 0;
}
if (aIndex === -1) {
return 1;
}
if (bIndex === -1) {
return -1;
}
return aIndex - bIndex;
};
AppApi.GetVRChatRegistryKey(
`VRC_GROUP_ORDER_${API.currentUser.id}`
).then((json) => {
groupList = JSON.parse(json);
this.userGroups.remainingGroups.sort(sortGroups);
});
$app.methods.sortCurrentUserGroups = async function () {
var D = this.userDialog;
var inGameGroupList = [];
var sortMethod = function () {};

switch (D.groupSorting.value) {
case 'alphabetical':
sortMethod = compareByName;
break;
case 'members':
sortMethod = compareByMemberCount;
break;
case 'inGame':
sortMethod = function (a, b) {
var aIndex = inGameGroupList.indexOf(a?.id);
var bIndex = inGameGroupList.indexOf(b?.id);
if (aIndex === -1 && bIndex === -1) {
return 0;
}
if (aIndex === -1) {
return 1;
}
if (bIndex === -1) {
return -1;
}
return aIndex - bIndex;
};
try {
var json = await AppApi.GetVRChatRegistryKey(
`VRC_GROUP_ORDER_${API.currentUser.id}`
);
inGameGroupList = JSON.parse(json);
} catch (err) {
console.error(err);
}
break;
}

this.userGroups.ownGroups.sort(sortMethod);
this.userGroups.mutualGroups.sort(sortMethod);
this.userGroups.remainingGroups.sort(sortMethod);
};

// #endregion
Expand Down Expand Up @@ -20778,6 +20838,21 @@ speechSynthesis.getVoices();
value: 'ascending'
}
};

this.userDialogGroupSortingOptions = {
alphabetical: {
name: $t('dialog.user.groups.sorting.alphabetical'),
value: 'alphabetical'
},
members: {
name: $t('dialog.user.groups.sorting.members'),
value: 'members'
},
inGame: {
name: $t('dialog.user.groups.sorting.in_game'),
value: 'inGame'
}
};
};

$app.methods.applyGroupDialogSortingStrings = function () {
Expand Down Expand Up @@ -20816,6 +20891,9 @@ speechSynthesis.getVoices();
this.userDialogWorldSortingOptions.updated;
this.userDialog.worldOrder =
this.userDialogWorldOrderOptions.descending;
this.userDialog.groupSorting =
this.userDialogGroupSortingOptions.alphabetical;

this.groupDialog.memberFilter = this.groupDialogFilterOptions.everyone;
this.groupDialog.memberSortOrder =
this.groupDialogSortingOptions.joinedAtDesc;
Expand Down
8 changes: 7 additions & 1 deletion html/src/localization/en/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -640,9 +640,15 @@
"groups": {
"header": "Groups",
"total_count": "Total {count}",
"sort_by": "Sort by:",
"own_groups": "Own Groups",
"mutual_groups": "Mutual Groups",
"groups": "Groups"
"groups": "Groups",
"sorting": {
"alphabetical": "Alphabetical",
"members": "Members",
"in_game": "In-Game Order"
}
},
"worlds": {
"header": "Worlds",
Expand Down
11 changes: 9 additions & 2 deletions html/src/mixins/dialogs/userDialog.pug
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,13 @@ mixin userDialog()
el-tab-pane(:label="$t('dialog.user.groups.header')")
el-button(type="default" :loading="userDialog.isGroupsLoading" @click="getUserGroups(userDialog.id)" size="mini" icon="el-icon-refresh" circle)
span(style="margin-left:5px") {{ $t('dialog.user.groups.total_count', { count: userGroups.groups.length }) }}
div(style="float:right")
span(style="margin-right:5px") {{ $t('dialog.user.groups.sort_by') }}
el-dropdown(@click.native.stop trigger="click" size="small" style="margin-right:5px" :disabled="userDialog.isGroupsLoading")
el-button(size="mini")
span {{ userDialog.groupSorting.name }} #[i.el-icon-arrow-down.el-icon--right]
el-dropdown-menu(#default="dropdown")
el-dropdown-item(:disabled="item === userDialogGroupSortingOptions.inGame && userDialog.id !== API.currentUser.id" v-for="(item) in userDialogGroupSortingOptions" v-text="item.name" @click.native="setUserDialogGroupSorting(item)")
div(v-loading="userDialog.isGroupsLoading" style="margin-top:10px")
template(v-if="userGroups.ownGroups.length > 0")
span(style="font-weight:bold;font-size:16px") {{ $t('dialog.user.groups.own_groups') }}
Expand Down Expand Up @@ -396,8 +403,8 @@ mixin userDialog()
span.name(v-text="world.name")
span.extra(v-if="world.occupants") ({{ world.occupants }})
el-tab-pane(:label="$t('dialog.user.avatars.header')")
template(v-if="userDialog.ref.id === API.currentUser.id")
el-button(type="default" :loading="userDialog.isAvatarsLoading" @click="refreshUserDialogAvatars()" size="mini" icon="el-icon-refresh" circle)
el-button(v-if="userDialog.ref.id === API.currentUser.id" type="default" :loading="userDialog.isAvatarsLoading" @click="refreshUserDialogAvatars()" size="mini" icon="el-icon-refresh" circle)
el-button(v-else type="default" :loading="userDialog.isAvatarsLoading" @click="setUserDialogAvatarsRemote(userDialog.id)" size="mini" icon="el-icon-refresh" circle)
span(style="margin-left:5px") {{ $t('dialog.user.avatars.total_count', { count: userDialogAvatars.length }) }}
el-radio-group(v-if="userDialog.ref.id === API.currentUser.id" v-model="userDialog.avatarSorting" size="mini" style="margin-left:30px;margin-right:30px" @change="changeUserDialogAvatarSorting")
el-radio(label="name") {{ $t('dialog.user.avatars.sort_by_name') }}
Expand Down
2 changes: 1 addition & 1 deletion html/src/mixins/tabs/friendLog.pug
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ mixin friendLogTab()
el-select(v-model="friendLogTable.filters[0].value" @change="saveTableFilters" multiple clearable collapse-tags style="flex:1" :placeholder="$t('view.friend_log.filter_placeholder')")
el-option(v-once v-for="type in ['Friend', 'Unfriend', 'FriendRequest', 'CancelFriendRequest', 'DisplayName', 'TrustLevel']" :key="type" :label="type" :value="type")
el-input(v-model="friendLogTable.filters[1].value" :placeholder="$t('view.friend_log.search_placeholder')" style="flex:none;width:150px;margin-left:10px")
el-table-column(:label="$t('table.friendLog.date')" prop="created_at" sortable="custom" width="150")
el-table-column(:label="$t('table.friendLog.date')" prop="created_at" sortable="custom" width="200")
template(v-once #default="scope")
span {{ scope.row.created_at | formatDate('long') }}
el-table-column(:label="$t('table.friendLog.type')" prop="type" width="150")
Expand Down

0 comments on commit 8bc3b7f

Please sign in to comment.