mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-05-05 06:16:05 +02:00
Custom save locations for prints & stickers (#1041)
This commit is contained in:
@@ -629,7 +629,7 @@ namespace VRCX
|
|||||||
|
|
||||||
public async Task<bool> SavePrintToFile(string url, string path, string fileName)
|
public async Task<bool> SavePrintToFile(string url, string path, string fileName)
|
||||||
{
|
{
|
||||||
var folder = Path.Combine(GetVRChatPhotosLocation(), "Prints", MakeValidFileName(path));
|
var folder = Path.Combine(GetUGCPhotoLocation(), "Prints", MakeValidFileName(path));
|
||||||
Directory.CreateDirectory(folder);
|
Directory.CreateDirectory(folder);
|
||||||
var filePath = Path.Combine(folder, MakeValidFileName(fileName));
|
var filePath = Path.Combine(folder, MakeValidFileName(fileName));
|
||||||
if (File.Exists(filePath))
|
if (File.Exists(filePath))
|
||||||
@@ -640,7 +640,7 @@ namespace VRCX
|
|||||||
|
|
||||||
public async Task<bool> SaveStickerToFile(string url, string path, string fileName)
|
public async Task<bool> SaveStickerToFile(string url, string path, string fileName)
|
||||||
{
|
{
|
||||||
var folder = Path.Combine(GetVRChatPhotosLocation(), "Stickers", MakeValidFileName(path));
|
var folder = Path.Combine(GetUGCPhotoLocation(), "Stickers", MakeValidFileName(path));
|
||||||
Directory.CreateDirectory(folder);
|
Directory.CreateDirectory(folder);
|
||||||
var filePath = Path.Combine(folder, MakeValidFileName(fileName));
|
var filePath = Path.Combine(folder, MakeValidFileName(fileName));
|
||||||
if (File.Exists(filePath))
|
if (File.Exists(filePath))
|
||||||
|
|||||||
@@ -6,6 +6,9 @@ using System.Text.RegularExpressions;
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace VRCX
|
namespace VRCX
|
||||||
{
|
{
|
||||||
@@ -54,6 +57,33 @@ namespace VRCX
|
|||||||
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures), "VRChat");
|
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures), "VRChat");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the folder the user has selected for User-Generated content such as prints / stickers from the JS side.
|
||||||
|
/// If there is no override on the folder, it returns the default VRChat Photos path.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The UGC Photo Location.</returns>
|
||||||
|
public string GetUGCPhotoLocation(string path = "")
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(path))
|
||||||
|
{
|
||||||
|
return GetVRChatPhotosLocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!Directory.Exists(path))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(path);
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Console.WriteLine(e);
|
||||||
|
return GetVRChatPhotosLocation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private string GetSteamUserdataPathFromRegistry()
|
private string GetSteamUserdataPathFromRegistry()
|
||||||
{
|
{
|
||||||
string steamUserdataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), @"Steam\userdata");
|
string steamUserdataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), @"Steam\userdata");
|
||||||
@@ -145,6 +175,16 @@ namespace VRCX
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool OpenUGCPhotosFolder(string ugcPath = "")
|
||||||
|
{
|
||||||
|
var path = GetUGCPhotoLocation(ugcPath);
|
||||||
|
if (!Directory.Exists(path))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
OpenFolderAndSelectItem(path, true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public bool OpenVrcScreenshotsFolder()
|
public bool OpenVrcScreenshotsFolder()
|
||||||
{
|
{
|
||||||
var path = GetVRChatScreenshotsLocation();
|
var path = GetVRChatScreenshotsLocation();
|
||||||
@@ -248,6 +288,44 @@ namespace VRCX
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Opens a folder dialog to select a folder and pass it back to the JS side.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="defaultPath">The default path for the folder picker.</param>
|
||||||
|
public async Task<string> OpenFolderSelectorDialog(string defaultPath = "")
|
||||||
|
{
|
||||||
|
var tcs = new TaskCompletionSource<string>();
|
||||||
|
var staThread = new Thread(() =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var openFolderDialog = new FolderBrowserDialog())
|
||||||
|
{
|
||||||
|
openFolderDialog.InitialDirectory = Directory.Exists(defaultPath) ? defaultPath : GetVRChatPhotosLocation();
|
||||||
|
|
||||||
|
var dialogResult = openFolderDialog.ShowDialog(MainForm.nativeWindow);
|
||||||
|
if (dialogResult == DialogResult.OK)
|
||||||
|
{
|
||||||
|
tcs.SetResult(openFolderDialog.SelectedPath);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tcs.SetResult(defaultPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
tcs.SetException(ex);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
staThread.SetApartmentState(ApartmentState.STA);
|
||||||
|
staThread.Start();
|
||||||
|
|
||||||
|
return await tcs.Task;
|
||||||
|
}
|
||||||
|
|
||||||
private static readonly Regex _folderRegex = new Regex(string.Format(@"([{0}]*\.+$)|([{0}]+)",
|
private static readonly Regex _folderRegex = new Regex(string.Format(@"([{0}]*\.+$)|([{0}]+)",
|
||||||
Regex.Escape(new string(Path.GetInvalidPathChars()))));
|
Regex.Escape(new string(Path.GetInvalidPathChars()))));
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ namespace VRCX
|
|||||||
public partial class MainForm : WinformBase
|
public partial class MainForm : WinformBase
|
||||||
{
|
{
|
||||||
public static MainForm Instance;
|
public static MainForm Instance;
|
||||||
|
public static NativeWindow nativeWindow;
|
||||||
private static NLog.Logger jslogger = NLog.LogManager.GetLogger("Javascript");
|
private static NLog.Logger jslogger = NLog.LogManager.GetLogger("Javascript");
|
||||||
public ChromiumWebBrowser Browser;
|
public ChromiumWebBrowser Browser;
|
||||||
private readonly Timer _saveTimer;
|
private readonly Timer _saveTimer;
|
||||||
@@ -43,6 +44,7 @@ namespace VRCX
|
|||||||
{
|
{
|
||||||
Instance = this;
|
Instance = this;
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
nativeWindow = NativeWindow.FromHandle(this.Handle);
|
||||||
|
|
||||||
// adding a 5s delay here to avoid excessive writes to disk
|
// adding a 5s delay here to avoid excessive writes to disk
|
||||||
_saveTimer = new Timer();
|
_saveTimer = new Timer();
|
||||||
|
|||||||
@@ -20455,6 +20455,45 @@ speechSynthesis.getVoices();
|
|||||||
this.noteExportDialog.loading = false;
|
this.noteExportDialog.loading = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// user generated content
|
||||||
|
$app.data.ugcFolderPath = await configRepository.getString(
|
||||||
|
'VRCX_userGeneratedContentPath',
|
||||||
|
''
|
||||||
|
);
|
||||||
|
|
||||||
|
$app.data.userGeneratedContentDialog = {
|
||||||
|
visible: false
|
||||||
|
};
|
||||||
|
|
||||||
|
$app.methods.setUGCFolderPath = async function (path) {
|
||||||
|
await configRepository.setString(
|
||||||
|
'VRCX_userGeneratedContentPath',
|
||||||
|
path
|
||||||
|
);
|
||||||
|
this.ugcFolderPath = path;
|
||||||
|
};
|
||||||
|
|
||||||
|
$app.methods.resetUGCFolder = function () {
|
||||||
|
this.setUGCFolderPath('');
|
||||||
|
}
|
||||||
|
|
||||||
|
$app.methods.openUGCFolder = async function () {
|
||||||
|
await AppApi.OpenUGCPhotosFolder(this.ugcFolderPath);
|
||||||
|
};
|
||||||
|
|
||||||
|
$app.methods.openUGCFolderSelector = async function () {
|
||||||
|
var D = this.userGeneratedContentDialog;
|
||||||
|
|
||||||
|
if(D.visible)
|
||||||
|
return;
|
||||||
|
|
||||||
|
D.visible = true;
|
||||||
|
var newUGCFolder = await AppApi.OpenFolderSelectorDialog(this.ugcFolderPath);
|
||||||
|
D.visible = false;
|
||||||
|
|
||||||
|
await this.setUGCFolderPath(newUGCFolder);
|
||||||
|
};
|
||||||
|
|
||||||
// avatar database provider
|
// avatar database provider
|
||||||
|
|
||||||
$app.data.avatarProviderDialog = {
|
$app.data.avatarProviderDialog = {
|
||||||
|
|||||||
@@ -516,6 +516,13 @@
|
|||||||
"portal_spawn": "Portal Spawn:",
|
"portal_spawn": "Portal Spawn:",
|
||||||
"video_play": "Video Play:",
|
"video_play": "Video Play:",
|
||||||
"event": "Event:"
|
"event": "Event:"
|
||||||
|
},
|
||||||
|
"user_generated_content": {
|
||||||
|
"header": "User Generated Content",
|
||||||
|
"folder": "Open Folder",
|
||||||
|
"description": "Open or set the folder where content such as 'Prints' and 'Stickers' are stored.",
|
||||||
|
"set_folder": "Set Folder",
|
||||||
|
"reset_override": "Reset"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"photon": {
|
"photon": {
|
||||||
|
|||||||
@@ -506,6 +506,16 @@ mixin settingsTab()
|
|||||||
div.options-container-item
|
div.options-container-item
|
||||||
span.name(style="min-width:300px") {{ $t('view.settings.advanced.advanced.local_world_persistence.description') }}
|
span.name(style="min-width:300px") {{ $t('view.settings.advanced.advanced.local_world_persistence.description') }}
|
||||||
el-switch(v-model="disableWorldDatabase" :active-value="false" :inactive-value="true" @change="saveVRCXWindowOption")
|
el-switch(v-model="disableWorldDatabase" :active-value="false" :inactive-value="true" @change="saveVRCXWindowOption")
|
||||||
|
//- Advanced | User Generated Content
|
||||||
|
div.options-container
|
||||||
|
span.header {{ $t('view.settings.advanced.advanced.user_generated_content.header') }}
|
||||||
|
div.options-container-item
|
||||||
|
span.name(style="min-width:300px") {{ $t('view.settings.advanced.advanced.user_generated_content.description') }}
|
||||||
|
br
|
||||||
|
el-button(size="small" icon="el-icon-folder" @click="openUGCFolder()" style="margin-top:5px") {{ $t('view.settings.advanced.advanced.user_generated_content.folder') }}
|
||||||
|
el-button(size="small" icon="el-icon-folder-opened" @click="openUGCFolderSelector()") {{ $t('view.settings.advanced.advanced.user_generated_content.set_folder') }}
|
||||||
|
el-button(size="small" icon="el-icon-delete" @click="resetUGCFolder()" v-if="ugcFolderPath") {{ $t('view.settings.advanced.advanced.user_generated_content.reset_override') }}
|
||||||
|
br
|
||||||
span.sub-header {{ $t('view.settings.advanced.advanced.save_instance_prints_to_file.header') }}
|
span.sub-header {{ $t('view.settings.advanced.advanced.save_instance_prints_to_file.header') }}
|
||||||
el-tooltip(placement="top" style="margin-left:5px" :content="$t('view.settings.advanced.advanced.save_instance_prints_to_file.header_tooltip')")
|
el-tooltip(placement="top" style="margin-left:5px" :content="$t('view.settings.advanced.advanced.save_instance_prints_to_file.header_tooltip')")
|
||||||
i.el-icon-info
|
i.el-icon-info
|
||||||
|
|||||||
Reference in New Issue
Block a user