diff --git a/html/src/app.js b/html/src/app.js index 40237b24..ec199437 100644 --- a/html/src/app.js +++ b/html/src/app.js @@ -7646,6 +7646,10 @@ speechSynthesis.getVoices(); 'VRCX_feedTableVIPFilter', false ); + $app.data.gameLogTable.vip = await configRepository.getBool( + 'VRCX_gameLogTableVIPFilter', + false + ); $app.data.gameLogTable.filter = JSON.parse( await configRepository.getString('VRCX_gameLogTableFilters', '[]') ); diff --git a/html/src/classes/gameLog.js b/html/src/classes/gameLog.js index d1942743..a48a5baf 100644 --- a/html/src/classes/gameLog.js +++ b/html/src/classes/gameLog.js @@ -450,6 +450,18 @@ export default class extends baseClass { // event time can be before last gameLog entry this.updateSharedFeed(true); } + + // If the VIP friend filter is enabled, logs from other friends will be ignored. + if ( + this.gameLogTable.vip && + !this.localFavoriteFriends.has(entry.userId) && + (entry.type === 'OnPlayerJoined' || + entry.type === 'OnPlayerLeft' || + entry.type === 'PortalSpawn' || + entry.type === 'External') + ) { + return; + } if ( entry.type === 'LocationDestination' || entry.type === 'AvatarChange' || @@ -866,10 +878,19 @@ export default class extends baseClass { 'VRCX_gameLogTableFilters', JSON.stringify(this.gameLogTable.filter) ); + await configRepository.setBool( + 'VRCX_gameLogTableVIPFilter', + this.gameLogTable.vip + ); this.gameLogTable.loading = true; + let vipList = []; + if (this.gameLogTable.vip) { + vipList = Array.from(this.localFavoriteFriends.values()); + } this.gameLogTable.data = await database.lookupGameLogDatabase( this.gameLogTable.search, - this.gameLogTable.filter + this.gameLogTable.filter, + vipList ); this.gameLogTable.loading = false; }, diff --git a/html/src/mixins/tabs/gameLog.pug b/html/src/mixins/tabs/gameLog.pug index 2076ab73..6a724e60 100644 --- a/html/src/mixins/tabs/gameLog.pug +++ b/html/src/mixins/tabs/gameLog.pug @@ -3,6 +3,9 @@ mixin gameLogTab() data-tables(v-bind="gameLogTable" v-loading="gameLogTable.loading") template(#tool) div(style="margin:0 0 10px;display:flex;align-items:center") + div(style="flex:none;margin-right:10px") + el-tooltip(placement="bottom" :content="$t('view.feed.favorites_only_tooltip')" :disabled="hideTooltips") + el-switch(v-model="gameLogTable.vip" @change="gameLogTableLookup" active-color="#13ce66") el-select(v-model="gameLogTable.filter" @change="gameLogTableLookup" multiple clearable collapse-tags style="flex:1" :placeholder="$t('view.game_log.filter_placeholder')") el-option(v-once v-for="type in ['Location', 'OnPlayerJoined', 'OnPlayerLeft', 'PortalSpawn', 'VideoPlay', 'Event', 'External', 'StringLoad', 'ImageLoad']" :key="type" :label="type" :value="type") el-input(v-model="gameLogTable.search" :placeholder="$t('view.game_log.search_placeholder')" @keyup.native.13="gameLogTableLookup" @change="gameLogTableLookup" clearable style="flex:none;width:150px;margin:0 10px") diff --git a/html/src/repository/database.js b/html/src/repository/database.js index 46d7da53..9b011c11 100644 --- a/html/src/repository/database.js +++ b/html/src/repository/database.js @@ -1631,11 +1631,30 @@ class Database { return gamelogDatabase; } - async lookupGameLogDatabase(search, filters) { + /** + * Lookup the game log database for a specific search term + * @param {string} search The search term + * @param {Array} filters The filters to apply + * @param {Array} [vipList] The list of VIP users + * @returns {Promise} The game log data + */ + + async lookupGameLogDatabase(search, filters, vipList = []) { var search = search.replaceAll("'", "''"); if (search.startsWith('wrld_')) { return Database.getGameLogByLocation(search, filters); } + let vipQuery = ''; + if (vipList.length > 0) { + vipQuery = 'AND user_id IN ('; + vipList.forEach((vip, i) => { + vipQuery += `'${vip.replaceAll("'", "''")}'`; + if (i < vipList.length - 1) { + vipQuery += ', '; + } + }); + vipQuery += ')'; + } var location = true; var onplayerjoined = true; var onplayerleft = true; @@ -1723,7 +1742,7 @@ class Database { time: dbRow[6] }; gamelogDatabase.unshift(row); - }, `SELECT * FROM gamelog_join_leave WHERE (display_name LIKE '%${search}%' AND user_id != '${Database.userId}') ${query} ORDER BY id DESC LIMIT ${Database.maxTableSize}`); + }, `SELECT * FROM gamelog_join_leave WHERE (display_name LIKE '%${search}%' AND user_id != '${Database.userId}') ${vipQuery} ${query} ORDER BY id DESC LIMIT ${Database.maxTableSize}`); } if (portalspawn) { await sqliteService.execute((dbRow) => { @@ -1738,7 +1757,7 @@ class Database { worldName: dbRow[6] }; gamelogDatabase.unshift(row); - }, `SELECT * FROM gamelog_portal_spawn WHERE (display_name LIKE '%${search}%' OR world_name LIKE '%${search}%') ORDER BY id DESC LIMIT ${Database.maxTableSize}`); + }, `SELECT * FROM gamelog_portal_spawn WHERE (display_name LIKE '%${search}%' OR world_name LIKE '%${search}%') ${vipQuery} ORDER BY id DESC LIMIT ${Database.maxTableSize}`); } if (msgevent) { await sqliteService.execute((dbRow) => { @@ -1763,7 +1782,7 @@ class Database { location: dbRow[5] }; gamelogDatabase.unshift(row); - }, `SELECT * FROM gamelog_external WHERE (display_name LIKE '%${search}%' OR message LIKE '%${search}%') ORDER BY id DESC LIMIT ${Database.maxTableSize}`); + }, `SELECT * FROM gamelog_external WHERE (display_name LIKE '%${search}%' OR message LIKE '%${search}%') ${vipQuery} ORDER BY id DESC LIMIT ${Database.maxTableSize}`); } if (videoplay) { await sqliteService.execute((dbRow) => {