mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-05-06 22:46:06 +02:00
Mutual friends on friendsList
This commit is contained in:
@@ -2214,8 +2214,12 @@
|
|||||||
}
|
}
|
||||||
setUserDialogMutualFriendSorting(userDialog.value.mutualFriendSorting);
|
setUserDialogMutualFriendSorting(userDialog.value.mutualFriendSorting);
|
||||||
},
|
},
|
||||||
done: () => {
|
done: (success) => {
|
||||||
userDialog.value.isMutualFriendsLoading = false;
|
userDialog.value.isMutualFriendsLoading = false;
|
||||||
|
if (success) {
|
||||||
|
const mutualIds = userDialog.value.mutualFriends.map((u) => u.id);
|
||||||
|
database.updateMutualsForFriend(userId, mutualIds);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -273,7 +273,8 @@
|
|||||||
"filter_placeholder": "Filter",
|
"filter_placeholder": "Filter",
|
||||||
"refresh_tooltip": "Refresh",
|
"refresh_tooltip": "Refresh",
|
||||||
"clear_tooltip": "Clear Results",
|
"clear_tooltip": "Clear Results",
|
||||||
"cancel_tooltip": "Cancel"
|
"cancel_tooltip": "Cancel",
|
||||||
|
"load_mutual_friends": "Load Mutual Friends"
|
||||||
},
|
},
|
||||||
"charts": {
|
"charts": {
|
||||||
"header": "Charts",
|
"header": "Charts",
|
||||||
@@ -2201,7 +2202,8 @@
|
|||||||
"lastActivity": "Last Activity",
|
"lastActivity": "Last Activity",
|
||||||
"lastLogin": "Last Login",
|
"lastLogin": "Last Login",
|
||||||
"dateJoined": "Date Joined",
|
"dateJoined": "Date Joined",
|
||||||
"unfriend": "Unfriend"
|
"unfriend": "Unfriend",
|
||||||
|
"mutualFriends": "Mutual Friends"
|
||||||
},
|
},
|
||||||
"profile": {
|
"profile": {
|
||||||
"invite_messages": {
|
"invite_messages": {
|
||||||
|
|||||||
@@ -86,6 +86,51 @@ const mutualGraph = {
|
|||||||
await sqliteService.executeNonQuery('ROLLBACK');
|
await sqliteService.executeNonQuery('ROLLBACK');
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async updateMutualsForFriend(friendId, mutualIds) {
|
||||||
|
if (!dbVars.userPrefix || !friendId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const friendTable = `${dbVars.userPrefix}_mutual_graph_friends`;
|
||||||
|
const linkTable = `${dbVars.userPrefix}_mutual_graph_links`;
|
||||||
|
const safeFriendId = friendId.replace(/'/g, "''");
|
||||||
|
await sqliteService.executeNonQuery(
|
||||||
|
`INSERT OR REPLACE INTO ${friendTable} (friend_id) VALUES ('${safeFriendId}')`
|
||||||
|
);
|
||||||
|
await sqliteService.executeNonQuery(
|
||||||
|
`DELETE FROM ${linkTable} WHERE friend_id='${safeFriendId}'`
|
||||||
|
);
|
||||||
|
let edgeValues = '';
|
||||||
|
for (const mutual of mutualIds) {
|
||||||
|
if (!mutual) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const safeMutualId = String(mutual).replace(/'/g, "''");
|
||||||
|
edgeValues += `('${safeFriendId}', '${safeMutualId}'),`;
|
||||||
|
}
|
||||||
|
if (edgeValues) {
|
||||||
|
edgeValues = edgeValues.slice(0, -1);
|
||||||
|
await sqliteService.executeNonQuery(
|
||||||
|
`INSERT OR REPLACE INTO ${linkTable} (friend_id, mutual_id) VALUES ${edgeValues}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async getMutualCountForAllUsers() {
|
||||||
|
const mutualCountMap = new Map();
|
||||||
|
if (!dbVars.userPrefix) {
|
||||||
|
return mutualCountMap;
|
||||||
|
}
|
||||||
|
const linkTable = `${dbVars.userPrefix}_mutual_graph_links`;
|
||||||
|
await sqliteService.execute((dbRow) => {
|
||||||
|
const mutualId = dbRow[0];
|
||||||
|
const count = dbRow[1];
|
||||||
|
if (mutualId) {
|
||||||
|
mutualCountMap.set(mutualId, count);
|
||||||
|
}
|
||||||
|
}, `SELECT mutual_id, COUNT(*) FROM ${linkTable} GROUP BY mutual_id`);
|
||||||
|
return mutualCountMap;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -915,6 +915,16 @@ export const useFriendStore = defineStore('Friend', () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getAllUserMutualCount() {
|
||||||
|
const mutualCountMap = await database.getMutualCountForAllUsers();
|
||||||
|
for (const [userId, mutualCount] of mutualCountMap.entries()) {
|
||||||
|
const ref = friends.get(userId);
|
||||||
|
if (ref?.ref) {
|
||||||
|
ref.ref.$mutualCount = mutualCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {string} id
|
* @param {string} id
|
||||||
@@ -1625,6 +1635,7 @@ export const useFriendStore = defineStore('Friend', () => {
|
|||||||
refreshFriendsList,
|
refreshFriendsList,
|
||||||
updateOnlineFriendCounter,
|
updateOnlineFriendCounter,
|
||||||
getAllUserStats,
|
getAllUserStats,
|
||||||
|
getAllUserMutualCount,
|
||||||
initFriendLog,
|
initFriendLog,
|
||||||
migrateFriendLog,
|
migrateFriendLog,
|
||||||
getFriendLog,
|
getFriendLog,
|
||||||
|
|||||||
@@ -523,6 +523,7 @@ export const useUserStore = defineStore('User', () => {
|
|||||||
$joinCount: 0,
|
$joinCount: 0,
|
||||||
$timeSpent: 0,
|
$timeSpent: 0,
|
||||||
$lastSeen: '',
|
$lastSeen: '',
|
||||||
|
$mutualCount: 0,
|
||||||
$nickName: '',
|
$nickName: '',
|
||||||
$previousLocation: '',
|
$previousLocation: '',
|
||||||
$customTag: '',
|
$customTag: '',
|
||||||
|
|||||||
Vendored
+1
@@ -55,6 +55,7 @@ export interface VrcxUser extends GetUserResponse {
|
|||||||
$joinCount: number;
|
$joinCount: number;
|
||||||
$timeSpent: number;
|
$timeSpent: number;
|
||||||
$lastSeen: string;
|
$lastSeen: string;
|
||||||
|
$mutualCount: number;
|
||||||
$nickName: string;
|
$nickName: string;
|
||||||
$previousLocation: string;
|
$previousLocation: string;
|
||||||
$customTag: string;
|
$customTag: string;
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
<div style="display: flex; align-items: center; justify-content: space-between">
|
<div style="display: flex; align-items: center; justify-content: space-between">
|
||||||
<span class="header">{{ t('view.friend_list.header') }}</span>
|
<span class="header">{{ t('view.friend_list.header') }}</span>
|
||||||
<div style="font-size: 13px; display: flex; align-items: center">
|
<div style="font-size: 13px; display: flex; align-items: center">
|
||||||
|
<el-button size="small" @click="openChartsTab" style="margin-right: 10px">
|
||||||
|
{{ t('view.friend_list.load_mutual_friends') }}
|
||||||
|
</el-button>
|
||||||
<div v-if="friendsListBulkUnfriendMode" style="display: inline-block; margin-right: 10px">
|
<div v-if="friendsListBulkUnfriendMode" style="display: inline-block; margin-right: 10px">
|
||||||
<el-button size="small" @click="showBulkUnfriendSelectionConfirm">
|
<el-button size="small" @click="showBulkUnfriendSelectionConfirm">
|
||||||
{{ t('view.friend_list.bulk_unfriend_selection') }}
|
{{ t('view.friend_list.bulk_unfriend_selection') }}
|
||||||
@@ -214,6 +217,11 @@
|
|||||||
<span>{{ formatDateFilter(row.$lastSeen, 'long') }}</span>
|
<span>{{ formatDateFilter(row.$lastSeen, 'long') }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<el-table-column :label="t('table.friendList.mutualFriends')" width="120" prop="$mutualCount" sortable>
|
||||||
|
<template #default="{ row }">
|
||||||
|
<span v-if="row.$mutualCount">{{ row.$mutualCount }}</span>
|
||||||
|
<span v-else></span> </template
|
||||||
|
></el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
:label="t('table.friendList.lastActivity')"
|
:label="t('table.friendList.lastActivity')"
|
||||||
width="170"
|
width="170"
|
||||||
@@ -284,13 +292,14 @@
|
|||||||
} from '../../stores';
|
} from '../../stores';
|
||||||
import { friendRequest, userRequest } from '../../api';
|
import { friendRequest, userRequest } from '../../api';
|
||||||
import removeConfusables, { removeWhitespace } from '../../service/confusables';
|
import removeConfusables, { removeWhitespace } from '../../service/confusables';
|
||||||
|
import { router } from '../../plugin/router';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
const emit = defineEmits(['lookup-user']);
|
const emit = defineEmits(['lookup-user']);
|
||||||
|
|
||||||
const { friends } = storeToRefs(useFriendStore());
|
const { friends } = storeToRefs(useFriendStore());
|
||||||
const { getAllUserStats, confirmDeleteFriend, handleFriendDelete } = useFriendStore();
|
const { getAllUserStats, getAllUserMutualCount, confirmDeleteFriend, handleFriendDelete } = useFriendStore();
|
||||||
const { randomUserColours } = storeToRefs(useAppearanceSettingsStore());
|
const { randomUserColours } = storeToRefs(useAppearanceSettingsStore());
|
||||||
const { showUserDialog } = useUserStore();
|
const { showUserDialog } = useUserStore();
|
||||||
const { stringComparer, friendsListSearch } = storeToRefs(useSearchStore());
|
const { stringComparer, friendsListSearch } = storeToRefs(useSearchStore());
|
||||||
@@ -363,6 +372,7 @@
|
|||||||
results.push(ctx.ref);
|
results.push(ctx.ref);
|
||||||
}
|
}
|
||||||
getAllUserStats();
|
getAllUserStats();
|
||||||
|
getAllUserMutualCount();
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
friendsListTable.data = results;
|
friendsListTable.data = results;
|
||||||
friendsListLoading.value = false;
|
friendsListLoading.value = false;
|
||||||
@@ -449,4 +459,8 @@
|
|||||||
const bs = b.$languages.map((i) => i.value).sort();
|
const bs = b.$languages.map((i) => i.value).sort();
|
||||||
return JSON.stringify(as).localeCompare(JSON.stringify(bs));
|
return JSON.stringify(as).localeCompare(JSON.stringify(bs));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function openChartsTab() {
|
||||||
|
router.push({ name: 'charts' });
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user