diff --git a/Dotnet/AppApi/AppApiVr.cs b/Dotnet/AppApi/AppApiVr.cs
index 82adf4c83..a4f611aba 100644
--- a/Dotnet/AppApi/AppApiVr.cs
+++ b/Dotnet/AppApi/AppApiVr.cs
@@ -9,6 +9,8 @@ public class AppApiVr
{
public static readonly AppApiVr Instance;
+ private readonly PerformanceCounter _uptime = new PerformanceCounter("System", "System Up Time");
+
static AppApiVr()
{
Instance = new AppApiVr();
@@ -45,9 +47,8 @@ public string[][] GetVRDevices()
/// The number of milliseconds that the system has been running.
public double GetUptime()
{
- using var uptime = new PerformanceCounter("System", "System Up Time");
- uptime.NextValue();
- return TimeSpan.FromSeconds(uptime.NextValue()).TotalMilliseconds;
+ _uptime.NextValue();
+ return TimeSpan.FromSeconds(_uptime.NextValue()).TotalMilliseconds;
}
///
diff --git a/Dotnet/AppApi/Folders.cs b/Dotnet/AppApi/Folders.cs
index a65d92237..74a7683f1 100644
--- a/Dotnet/AppApi/Folders.cs
+++ b/Dotnet/AppApi/Folders.cs
@@ -1,4 +1,5 @@
using System;
+using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using Newtonsoft.Json;
@@ -170,6 +171,7 @@ public void OpenFolderAndSelectItem(string path, bool isFolder = false)
var result = WinApi.SHParseDisplayName(folderPath, IntPtr.Zero, out pidlFolder, 0, out psfgaoOut);
if (result != 0)
{
+ OpenFolderAndSelectItemFallback(path);
return;
}
@@ -178,6 +180,7 @@ public void OpenFolderAndSelectItem(string path, bool isFolder = false)
{
// Free the PIDL we allocated earlier if we failed to parse the display name of the file.
Marshal.FreeCoTaskMem(pidlFolder);
+ OpenFolderAndSelectItemFallback(path);
return;
}
@@ -189,6 +192,10 @@ public void OpenFolderAndSelectItem(string path, bool isFolder = false)
// It can select multiple items, but we only need to select one.
WinApi.SHOpenFolderAndSelectItems(pidlFolder, (uint)files.Length, files, 0);
}
+ catch
+ {
+ OpenFolderAndSelectItemFallback(path);
+ }
finally
{
// Free the PIDLs we allocated earlier
@@ -196,5 +203,21 @@ public void OpenFolderAndSelectItem(string path, bool isFolder = false)
Marshal.FreeCoTaskMem(pidlFile);
}
}
+
+ public void OpenFolderAndSelectItemFallback(string path)
+ {
+ if (!File.Exists(path) && !Directory.Exists(path))
+ return;
+
+ if (Directory.Exists(path))
+ {
+ Process.Start("explorer.exe", path);
+ }
+ else
+ {
+ // open folder with file highlighted
+ Process.Start("explorer.exe", $"/select,\"{path}\"");
+ }
+ }
}
}
\ No newline at end of file
diff --git a/Dotnet/LogWatcher.cs b/Dotnet/LogWatcher.cs
index 8f813d873..ef83a1a85 100644
--- a/Dotnet/LogWatcher.cs
+++ b/Dotnet/LogWatcher.cs
@@ -1157,7 +1157,7 @@ private bool ParseOscFailedToStart(FileInfo fileInfo, LogContext logContext, str
{
// 2023.09.26 04:12:57 Warning - Could not Start OSC: Address already in use
- if (string.Compare(line, offset, "Could not Start OSC: ", 0, 21, StringComparison.Ordinal) != 0)
+ if (string.Compare(line, offset, "VRChat could not start OSC server: ", 0, 21, StringComparison.Ordinal) != 0)
return false;
AppendLog(new[]
diff --git a/html/src/app.js b/html/src/app.js
index 0c00f6d12..2952f1c88 100644
--- a/html/src/app.js
+++ b/html/src/app.js
@@ -8135,7 +8135,7 @@ speechSynthesis.getVoices();
);
this.isFriendsGroup2 = await configRepository.getBool(
'VRCX_isFriendsGroupActive',
- true
+ false
);
this.isFriendsGroup3 = await configRepository.getBool(
'VRCX_isFriendsGroupOffline',
@@ -26836,7 +26836,51 @@ speechSynthesis.getVoices();
$app.getLocalWorldFavorites();
});
- // pending offline timer
+ $app.data.worldFavoriteSearch = '';
+ $app.data.worldFavoriteSearchResults = [];
+
+ $app.methods.searchWorldFavorites = function () {
+ var search = this.worldFavoriteSearch.toLowerCase();
+ if (search.length < 3) {
+ this.worldFavoriteSearchResults = [];
+ return;
+ }
+
+ var results = [];
+ for (var i = 0; i < this.localWorldFavoriteGroups.length; ++i) {
+ var group = this.localWorldFavoriteGroups[i];
+ if (!this.localWorldFavorites[group]) {
+ continue;
+ }
+ for (var j = 0; j < this.localWorldFavorites[group].length; ++j) {
+ var ref = this.localWorldFavorites[group][j];
+ if (
+ ref.name.toLowerCase().includes(search) ||
+ ref.authorName.toLowerCase().includes(search)
+ ) {
+ results.push(ref);
+ }
+ }
+ }
+
+ for (var i = 0; i < this.favoriteWorlds.length; ++i) {
+ var ref = this.favoriteWorlds[i].ref;
+ if (!ref) {
+ continue;
+ }
+ if (
+ ref.name.toLowerCase().includes(search) ||
+ ref.authorName.toLowerCase().includes(search)
+ ) {
+ results.push(ref);
+ }
+ }
+
+ this.worldFavoriteSearchResults = results;
+ };
+
+ // #endregion
+ // #region | App: pending offline timer
$app.methods.promptSetPendingOffline = function () {
this.$prompt(
@@ -28135,26 +28179,22 @@ speechSynthesis.getVoices();
D.memberRoles.push(role);
}
}
- if (D.inGroup) {
- API.getAllGroupPosts({
- groupId
- }).then((args2) => {
- if (groupId === args2.params.groupId) {
- for (var post of args2.posts) {
- post.title = this.replaceBioSymbols(
- post.title
- );
- post.text = this.replaceBioSymbols(
- post.text
- );
- }
- if (args2.posts.length > 0) {
- D.announcement = args2.posts[0];
- }
- D.posts = args2.posts;
- this.updateGroupPostSearch();
+ API.getAllGroupPosts({
+ groupId
+ }).then((args2) => {
+ if (groupId === args2.params.groupId) {
+ for (var post of args2.posts) {
+ post.title = this.replaceBioSymbols(post.title);
+ post.text = this.replaceBioSymbols(post.text);
}
- });
+ if (args2.posts.length > 0) {
+ D.announcement = args2.posts[0];
+ }
+ D.posts = args2.posts;
+ this.updateGroupPostSearch();
+ }
+ });
+ if (D.inGroup) {
API.getGroupInstances({
groupId
}).then((args3) => {
diff --git a/html/src/index.pug b/html/src/index.pug
index 27958f937..a7fc87193 100644
--- a/html/src/index.pug
+++ b/html/src/index.pug
@@ -1033,7 +1033,7 @@ html
timer(:epoch="user.$travelingToTime")
span.extra(v-else)
timer(:epoch="user.$location_at")
- .x-friend-item(v-if="groupDialog.ref.membershipStatus === 'member'" style="width:100%;cursor:default")
+ .x-friend-item(style="width:100%;cursor:default")
.detail
span.name {{ $t('dialog.group.info.announcement') }}
span(style="display:block" v-text="groupDialog.announcement.title")
@@ -2361,7 +2361,7 @@ html
el-button(type="default" @click="deleteVRCPlusIcon(image.id)" size="mini" icon="el-icon-delete" circle style="margin-left:5px")
el-tab-pane(v-if="galleryDialogVisible" v-loading="galleryDialogIconsLoading")
span(slot="label") {{ $t('dialog.gallery_icons.emojis') }}
- span(style="color:#909399;font-size:12px;margin-left:5px") {{ emojiTable.length }}/5
+ span(style="color:#909399;font-size:12px;margin-left:5px") {{ emojiTable.length }}/9
input(type="file" accept="image/*" @change="onFileChangeEmoji" id="EmojiUploadButton" style="display:none")
el-button-group(style="margin-right:10px")
el-button(type="default" size="small" @click="refreshEmojiTable" icon="el-icon-refresh") {{ $t('dialog.gallery_icons.refresh') }}
diff --git a/html/src/localization/en/en.json b/html/src/localization/en/en.json
index e608adb28..6f9163d46 100644
--- a/html/src/localization/en/en.json
+++ b/html/src/localization/en/en.json
@@ -85,6 +85,7 @@
},
"worlds": {
"header": "Worlds",
+ "search": "Search",
"vrchat_favorites": "VRChat Favorites",
"local_favorites": "Local Favorites",
"new_group": "New Group"
diff --git a/html/src/mixins/tabs/favorites.pug b/html/src/mixins/tabs/favorites.pug
index 83e162ee8..8b51f0b68 100644
--- a/html/src/mixins/tabs/favorites.pug
+++ b/html/src/mixins/tabs/favorites.pug
@@ -58,6 +58,23 @@ mixin favoritesTab()
div(style="display:inline-block;float:right;font-size:13px;margin-right:10px")
span.name(style="margin-right:5px") {{ $t('view.favorite.sort_by') }}
el-switch(v-model="sortFavorites" :inactive-text="$t('view.settings.appearance.appearance.sort_favorite_by_name')" :active-text="$t('view.settings.appearance.appearance.sort_favorite_by_date')" @change="saveSortFavoritesOption")
+ span(style="display:block;margin-top:20px") {{ $t('view.favorite.worlds.search') }}
+ el-input(v-model="worldFavoriteSearch" @input="searchWorldFavorites" clearable size="mini" :placeholder="$t('view.favorite.worlds.search')" style="width:300px;margin-top:10px")
+ .x-friend-list(style="margin-top:10px")
+ div(style="display:inline-block;width:300px;margin-right:15px" v-for="favorite in worldFavoriteSearchResults" :key="favorite.id" @click="showWorldDialog(favorite.id)")
+ .x-friend-item
+ template(v-if="favorite.name")
+ .avatar
+ img(v-lazy="favorite.thumbnailImageUrl")
+ .detail
+ span.name(v-text="favorite.name")
+ span.extra(v-if="favorite.occupants") {{ favorite.authorName }} ({{ favorite.occupants }})
+ span.extra(v-else v-text="favorite.authorName")
+ template(v-else)
+ .avatar
+ .detail
+ span(v-text="favorite.id")
+
span(style="display:block;margin-top:20px") {{ $t('view.favorite.worlds.vrchat_favorites') }}
el-collapse-item(v-for="group in API.favoriteWorldGroups" :key="group.name")
template(slot="title")