mirror of
https://github.com/vrcx-team/VRCX.git
synced 2026-04-06 00:32:02 +02:00
Add applauncher settings, refactor some pug code (#544)
* fix(.NET): Stop CheckGameRunning from force checking processes I'm not really sure what I was thinking when I did that the way I did; They are not supposed to force check if they're closed after the first time...That's what the monitor is for. * feat(.NET): Add optional child process culling, clean up applauncher Add an AppApi method to set applauncher settings Enabled/KillChildrenOnExit Refactor repeated applauncher event code, move into methods * refactor: Move the pug code for every tab into its own file * refactor: Add PoC mixins to settings.pug ^& add comments for navigation Some proof of concept replacements of the categories, switches and a radio group in the General settings seection. Also added comments for each header-separated section for marginally better navigation of the file. * refactor: Move the login page to its own file * fix(.NET): Correct wrong variable being set in SetAppLauncherSettings * fix(.NET): Remove redundant/exception causing process refresh in monitor * refactor(.NET): Allow launcher to be disabled; Disabled by default. * refactor: Change screenshot helper default to true * feat: Expose new app launcher settings, add new settings category Translation keys added/removed: + view.settings.advanced.advanced.app_launcher.header + view.settings.advanced.advanced.app_launcher.folder_tooltip + view.settings.advanced.advanced.app_launcher.enable + view.settings.advanced.advanced.app_launcher.auto_close - view.settings.advanced.advanced.auto_launch - view.settings.advanced.advanced.auto_launch_tooltip * Add GPU Fix and Udon Exception Logging options, unload favorites tab when not in use * Fix GPUFix typo * Fix GPUFix typo 1 * Add logging for AVPro streams without usharp videoplayer * Lint --------- Co-authored-by: Natsumi <cmcooper123@hotmail.com>
This commit is contained in:
19
.vscode/settings.json
vendored
19
.vscode/settings.json
vendored
@@ -1,10 +1,13 @@
|
||||
{
|
||||
"i18n-ally.localesPaths": ["html/src/localization/strings"],
|
||||
"i18n-ally.keystyle": "nested",
|
||||
"i18n-ally.sourceLanguage": "en",
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true,
|
||||
"[javascript]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
}
|
||||
"i18n-ally.localesPaths": ["html/src/localization/strings"],
|
||||
"i18n-ally.keystyle": "nested",
|
||||
"i18n-ally.sourceLanguage": "en",
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true,
|
||||
"[javascript]": {
|
||||
"editor.defaultFormatter": "vscode.typescript-language-features"
|
||||
},
|
||||
"[jade]": {
|
||||
"editor.defaultFormatter": "svipas.prettier-plus"
|
||||
}
|
||||
}
|
||||
|
||||
13
AppApi.cs
13
AppApi.cs
@@ -134,12 +134,12 @@ namespace VRCX
|
||||
var isGameRunning = false;
|
||||
var isSteamVRRunning = false;
|
||||
|
||||
if (ProcessMonitor.Instance.IsProcessRunning("VRChat", true))
|
||||
if (ProcessMonitor.Instance.IsProcessRunning("VRChat"))
|
||||
{
|
||||
isGameRunning = true;
|
||||
}
|
||||
|
||||
if (ProcessMonitor.Instance.IsProcessRunning("vrserver", true))
|
||||
if (ProcessMonitor.Instance.IsProcessRunning("vrserver"))
|
||||
{
|
||||
isSteamVRRunning = true;
|
||||
}
|
||||
@@ -670,6 +670,15 @@ namespace VRCX
|
||||
}
|
||||
}
|
||||
|
||||
// what the fuck even is this
|
||||
// refactor when
|
||||
// #AppApiLivesDontMatter
|
||||
public void SetAppLauncherSettings(bool enabled, bool killOnExit)
|
||||
{
|
||||
AutoAppLaunchManager.Instance.Enabled = enabled;
|
||||
AutoAppLaunchManager.Instance.KillChildrenOnExit = killOnExit;
|
||||
}
|
||||
|
||||
public void AddScreenshotMetadata(string path, string metadataString, string worldId, bool changeFilename = false)
|
||||
{
|
||||
var fileName = Path.GetFileNameWithoutExtension(path);
|
||||
|
||||
@@ -12,19 +12,23 @@ namespace VRCX
|
||||
public class AutoAppLaunchManager
|
||||
{
|
||||
public static AutoAppLaunchManager Instance { get; private set; }
|
||||
public bool Enabled = true;
|
||||
public static readonly string VRChatProcessName = "VRChat";
|
||||
|
||||
public bool Enabled = false;
|
||||
/// <summary> Whether or not to kill child processes when VRChat closes. </summary>
|
||||
public bool KillChildrenOnExit = true;
|
||||
public readonly string AppShortcutDirectory;
|
||||
|
||||
private DateTime startTime = DateTime.Now;
|
||||
private List<Process> startedProcesses = new List<Process>();
|
||||
private Dictionary<string, Process> startedProcesses = new Dictionary<string, Process>();
|
||||
private static readonly byte[] shortcutSignatureBytes = { 0x4C, 0x00, 0x00, 0x00 }; // signature for ShellLinkHeader\
|
||||
|
||||
static AutoAppLaunchManager()
|
||||
static AutoAppLaunchManager()
|
||||
{
|
||||
Instance = new AutoAppLaunchManager();
|
||||
}
|
||||
|
||||
public AutoAppLaunchManager()
|
||||
public AutoAppLaunchManager()
|
||||
{
|
||||
AppShortcutDirectory = Path.Combine(Program.AppDataDirectory, "startup");
|
||||
|
||||
@@ -39,11 +43,41 @@ namespace VRCX
|
||||
|
||||
private void OnProcessExited(MonitoredProcess monitoredProcess)
|
||||
{
|
||||
if (startedProcesses.Count == 0 || !monitoredProcess.HasName("VRChat"))
|
||||
if (startedProcesses.Count == 0 || !monitoredProcess.HasName(VRChatProcessName))
|
||||
return;
|
||||
|
||||
foreach (var process in startedProcesses)
|
||||
if (KillChildrenOnExit)
|
||||
KillChildProcesses();
|
||||
}
|
||||
|
||||
private void OnProcessStarted(MonitoredProcess monitoredProcess)
|
||||
{
|
||||
if (!Enabled || !monitoredProcess.HasName(VRChatProcessName) || monitoredProcess.Process.StartTime < startTime)
|
||||
return;
|
||||
|
||||
if (KillChildrenOnExit)
|
||||
KillChildProcesses();
|
||||
|
||||
var shortcutFiles = FindShortcutFiles(AppShortcutDirectory);
|
||||
|
||||
foreach (var file in shortcutFiles)
|
||||
{
|
||||
if (!IsChildProcessRunning(file))
|
||||
{
|
||||
StartChildProcess(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Kills all running child processes.
|
||||
/// </summary>
|
||||
internal void KillChildProcesses()
|
||||
{
|
||||
foreach (var pair in startedProcesses)
|
||||
{
|
||||
var process = pair.Value;
|
||||
|
||||
if (!process.HasExited)
|
||||
process.Kill();
|
||||
}
|
||||
@@ -51,32 +85,40 @@ namespace VRCX
|
||||
startedProcesses.Clear();
|
||||
}
|
||||
|
||||
private void OnProcessStarted(MonitoredProcess monitoredProcess)
|
||||
/// <summary>
|
||||
/// Starts a new child process.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
internal void StartChildProcess(string path)
|
||||
{
|
||||
if (!monitoredProcess.HasName("VRChat") || monitoredProcess.Process.StartTime < startTime)
|
||||
return;
|
||||
var process = Process.Start(path);
|
||||
startedProcesses.Add(path, process);
|
||||
}
|
||||
|
||||
if (startedProcesses.Count > 0)
|
||||
/// <summary>
|
||||
/// Updates the child processes list.
|
||||
/// Removes any processes that have exited.
|
||||
/// </summary>
|
||||
internal void UpdateChildProcesses()
|
||||
{
|
||||
foreach (var pair in startedProcesses.ToList())
|
||||
{
|
||||
foreach (var process in startedProcesses)
|
||||
{
|
||||
if (!process.HasExited)
|
||||
process.Kill();
|
||||
}
|
||||
|
||||
startedProcesses.Clear();
|
||||
var process = pair.Value;
|
||||
if (process.HasExited)
|
||||
startedProcesses.Remove(pair.Key);
|
||||
}
|
||||
}
|
||||
|
||||
var shortcutFiles = FindShortcutFiles(AppShortcutDirectory);
|
||||
|
||||
if (shortcutFiles.Length > 0)
|
||||
{
|
||||
foreach (var file in shortcutFiles)
|
||||
{
|
||||
var process = Process.Start(file);
|
||||
startedProcesses.Add(process);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Checks to see if a given file matches a current running child process.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if child process running; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
internal bool IsChildProcessRunning(string path)
|
||||
{
|
||||
return startedProcesses.ContainsKey(path);
|
||||
}
|
||||
|
||||
internal void Init()
|
||||
@@ -88,11 +130,7 @@ namespace VRCX
|
||||
{
|
||||
Enabled = false;
|
||||
|
||||
foreach (var process in startedProcesses)
|
||||
{
|
||||
if (!process.HasExited)
|
||||
process.Kill();
|
||||
}
|
||||
KillChildProcesses();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -220,6 +220,7 @@ namespace VRCX
|
||||
ParseLogAvatarPedestalChange(fileInfo, logContext, line, offset) ||
|
||||
ParseLogVideoError(fileInfo, logContext, line, offset) ||
|
||||
ParseLogVideoChange(fileInfo, logContext, line, offset) ||
|
||||
ParseLogAVProVideoChange(fileInfo, logContext, line, offset) ||
|
||||
ParseLogUsharpVideoPlay(fileInfo, logContext, line, offset) ||
|
||||
ParseLogUsharpVideoSync(fileInfo, logContext, line, offset) ||
|
||||
ParseLogWorldVRCX(fileInfo, logContext, line, offset) ||
|
||||
@@ -617,6 +618,31 @@ namespace VRCX
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool ParseLogAVProVideoChange(FileInfo fileInfo, LogContext logContext, string line, int offset)
|
||||
{
|
||||
// 2023.05.12 15:53:48 Log - [Video Playback] Resolving URL 'rtspt://topaz.chat/live/kiriri520'
|
||||
|
||||
if (string.Compare(line, offset, "[Video Playback] Resolving URL '", 0, 32, StringComparison.Ordinal) != 0)
|
||||
return false;
|
||||
|
||||
var pos = line.LastIndexOf("'");
|
||||
if (pos < 0)
|
||||
return false;
|
||||
|
||||
var data = line.Substring(offset + 32);
|
||||
data = data.Remove(data.Length - 1);
|
||||
|
||||
AppendLog(new[]
|
||||
{
|
||||
fileInfo.Name,
|
||||
ConvertLogTimeToISO8601(line),
|
||||
"video-play",
|
||||
data
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool ParseLogSDK2VideoPlay(FileInfo fileInfo, LogContext logContext, string line, int offset)
|
||||
{
|
||||
// 2021.04.23 13:12:25 Log - User Natsumi-sama added URL https://www.youtube.com/watch?v=dQw4w9WgXcQ
|
||||
|
||||
@@ -77,8 +77,6 @@ namespace VRCX
|
||||
monitoredProcess.ProcessExited();
|
||||
ProcessExited?.Invoke(monitoredProcess);
|
||||
}
|
||||
|
||||
monitoredProcess.Process.Refresh();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -109,8 +109,8 @@ namespace VRCX
|
||||
|
||||
private static void LoadFromConfig()
|
||||
{
|
||||
if (!GPUFix) GPUFix = VRCXStorage.Instance.Get("GPU_Fix") == "true";
|
||||
if (!LaunchDebug) LaunchDebug = VRCXStorage.Instance.Get("Launch_Debug") == "true";
|
||||
if (!GPUFix)
|
||||
GPUFix = VRCXStorage.Instance.Get("VRCX_GPUFix") == "true";
|
||||
}
|
||||
}
|
||||
}
|
||||
56
html/src/api.js
Normal file
56
html/src/api.js
Normal file
@@ -0,0 +1,56 @@
|
||||
const API = {}
|
||||
|
||||
API.eventHandlers = new Map();
|
||||
|
||||
API.$emit = function (name, ...args) {
|
||||
if ($app.debug) {
|
||||
console.log(name, ...args);
|
||||
}
|
||||
var handlers = this.eventHandlers.get(name);
|
||||
if (typeof handlers === 'undefined') {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
for (var handler of handlers) {
|
||||
handler.apply(this, args);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
};
|
||||
|
||||
API.$on = function (name, handler) {
|
||||
var handlers = this.eventHandlers.get(name);
|
||||
if (typeof handlers === 'undefined') {
|
||||
handlers = [];
|
||||
this.eventHandlers.set(name, handlers);
|
||||
}
|
||||
handlers.push(handler);
|
||||
};
|
||||
|
||||
API.$off = function (name, handler) {
|
||||
var handlers = this.eventHandlers.get(name);
|
||||
if (typeof handlers === 'undefined') {
|
||||
return;
|
||||
}
|
||||
var {length} = handlers;
|
||||
for (var i = 0; i < length; ++i) {
|
||||
if (handlers[i] === handler) {
|
||||
if (length > 1) {
|
||||
handlers.splice(i, 1);
|
||||
} else {
|
||||
this.eventHandlers.delete(name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
API.pendingGetRequests = new Map();
|
||||
API.failedGetRequests = new Map();
|
||||
API.endpointDomainVrchat = 'https://api.vrchat.cloud/api/1';
|
||||
API.websocketDomainVrchat = 'wss://pipeline.vrchat.cloud';
|
||||
API.endpointDomain = 'https://api.vrchat.cloud/api/1';
|
||||
API.websocketDomain = 'wss://pipeline.vrchat.cloud';
|
||||
|
||||
module.exports = API
|
||||
@@ -4911,6 +4911,10 @@ speechSynthesis.getVoices();
|
||||
}
|
||||
});
|
||||
AppApi.CheckGameRunning();
|
||||
AppApi.SetAppLauncherSettings(
|
||||
this.enableAppLauncher,
|
||||
this.enableAppLauncherAutoClose
|
||||
);
|
||||
API.$on('SHOW_WORLD_DIALOG', (tag) => this.showWorldDialog(tag));
|
||||
API.$on('SHOW_WORLD_DIALOG_SHORTNAME', (tag) =>
|
||||
this.verifyShortName('', tag)
|
||||
@@ -5089,9 +5093,6 @@ speechSynthesis.getVoices();
|
||||
isGameRunning,
|
||||
isSteamVRRunning
|
||||
) {
|
||||
console.log(
|
||||
`updateIsGameRunning isGameRunning:${isGameRunning} isSteamVRRunning:${isSteamVRRunning}`
|
||||
);
|
||||
if (isGameRunning !== this.isGameRunning) {
|
||||
this.isGameRunning = isGameRunning;
|
||||
if (isGameRunning) {
|
||||
@@ -5113,11 +5114,11 @@ speechSynthesis.getVoices();
|
||||
60000
|
||||
);
|
||||
this.nextDiscordUpdate = 0;
|
||||
console.log('isGameRunning changed', isGameRunning);
|
||||
console.log('isGameRunning:', isGameRunning);
|
||||
}
|
||||
if (isSteamVRRunning !== this.isSteamVRRunning) {
|
||||
this.isSteamVRRunning = isSteamVRRunning;
|
||||
console.log('isSteamVRRunning changed', isSteamVRRunning);
|
||||
console.log('isSteamVRRunning:', isSteamVRRunning);
|
||||
}
|
||||
this.updateOpenVR();
|
||||
};
|
||||
@@ -9032,6 +9033,7 @@ speechSynthesis.getVoices();
|
||||
this.photonLobbyUserData = new Map();
|
||||
this.photonLobbyWatcherLoopStop();
|
||||
this.photonLobbyAvatars = new Map();
|
||||
this.photonLobbyLastModeration = new Map();
|
||||
this.photonLobbyJointime = new Map();
|
||||
this.photonEvent7List = new Map();
|
||||
this.photonLastEvent7List = '';
|
||||
@@ -9674,7 +9676,9 @@ speechSynthesis.getVoices();
|
||||
this.updateOpenVR();
|
||||
break;
|
||||
case 'udon-exception':
|
||||
console.log('UdonException', gameLog.data);
|
||||
if (this.udonExceptionLogging) {
|
||||
console.log('UdonException', gameLog.data);
|
||||
}
|
||||
// var entry = {
|
||||
// created_at: gameLog.dt,
|
||||
// type: 'Event',
|
||||
@@ -9707,6 +9711,7 @@ speechSynthesis.getVoices();
|
||||
$app.data.photonLobbyUserData = new Map();
|
||||
$app.data.photonLobbyCurrent = new Map();
|
||||
$app.data.photonLobbyAvatars = new Map();
|
||||
$app.data.photonLobbyLastModeration = new Map();
|
||||
$app.data.photonLobbyWatcherLoop = false;
|
||||
$app.data.photonLobbyTimeout = [];
|
||||
$app.data.photonLobbyJointime = new Map();
|
||||
@@ -10305,10 +10310,12 @@ speechSynthesis.getVoices();
|
||||
break;
|
||||
case 254:
|
||||
// Leave
|
||||
this.photonUserLeave(data.Parameters[254], gameLogDate);
|
||||
this.photonLobbyCurrent.delete(data.Parameters[254]);
|
||||
this.photonLobbyJointime.delete(data.Parameters[254]);
|
||||
this.photonEvent7List.delete(data.Parameters[254]);
|
||||
var photonId = data.Parameters[254];
|
||||
this.photonUserLeave(photonId, gameLogDate);
|
||||
this.photonLobbyCurrent.delete(photonId);
|
||||
this.photonLobbyLastModeration.delete(photonId);
|
||||
this.photonLobbyJointime.delete(photonId);
|
||||
this.photonEvent7List.delete(photonId);
|
||||
this.parsePhotonLobbyIds(data.Parameters[252]);
|
||||
if (typeof data.Parameters[203] !== 'undefined') {
|
||||
this.setPhotonLobbyMaster(
|
||||
@@ -10891,6 +10898,7 @@ speechSynthesis.getVoices();
|
||||
gameLogDate
|
||||
) {
|
||||
database.getModeration(ref.id).then((row) => {
|
||||
var lastType = this.photonLobbyLastModeration.get(photonId);
|
||||
var type = '';
|
||||
var text = '';
|
||||
if (block) {
|
||||
@@ -10910,7 +10918,7 @@ speechSynthesis.getVoices();
|
||||
}
|
||||
if (block === row.block && mute === row.mute) {
|
||||
// no change
|
||||
if (type) {
|
||||
if (type && type !== lastType) {
|
||||
this.addEntryPhotonEvent({
|
||||
photonId,
|
||||
text: `Moderation ${text}`,
|
||||
@@ -10919,9 +10927,11 @@ speechSynthesis.getVoices();
|
||||
created_at: gameLogDate
|
||||
});
|
||||
}
|
||||
this.photonLobbyLastModeration.set(photonId, type);
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.photonLobbyLastModeration.set(photonId, type);
|
||||
this.moderationAgainstTable.forEach((item) => {
|
||||
if (item.userId === ref.id && item.type === type) {
|
||||
removeFromArray(this.moderationAgainstTable, item);
|
||||
@@ -13419,6 +13429,10 @@ speechSynthesis.getVoices();
|
||||
'VRCX_randomUserColours',
|
||||
this.randomUserColours
|
||||
);
|
||||
configRepository.setBool(
|
||||
'VRCX_udonExceptionLogging',
|
||||
this.udonExceptionLogging
|
||||
);
|
||||
this.updateSharedFeed(true);
|
||||
this.updateVRConfigVars();
|
||||
this.updateVRLastLocation();
|
||||
@@ -13493,19 +13507,23 @@ speechSynthesis.getVoices();
|
||||
);
|
||||
$app.data.isStartAsMinimizedState = false;
|
||||
$app.data.isCloseToTray = false;
|
||||
$app.data.gpuFix = false;
|
||||
VRCXStorage.Get('VRCX_StartAsMinimizedState').then((result) => {
|
||||
$app.isStartAsMinimizedState = result === 'true';
|
||||
});
|
||||
VRCXStorage.Get('VRCX_CloseToTray').then((result) => {
|
||||
$app.isCloseToTray = result === 'true';
|
||||
});
|
||||
VRCXStorage.Get('VRCX_GPUFix').then((result) => {
|
||||
$app.gpuFix = result === 'true';
|
||||
});
|
||||
if (configRepository.getBool('VRCX_CloseToTray')) {
|
||||
// move back to JSON
|
||||
$app.data.isCloseToTray = configRepository.getBool('VRCX_CloseToTray');
|
||||
VRCXStorage.Set('VRCX_CloseToTray', $app.data.isCloseToTray.toString());
|
||||
configRepository.remove('VRCX_CloseToTray');
|
||||
}
|
||||
var saveVRCXWindowOption = function () {
|
||||
$app.methods.saveVRCXWindowOption = function () {
|
||||
configRepository.setBool(
|
||||
'VRCX_StartAtWindowsStartup',
|
||||
this.isStartAtWindowsStartup
|
||||
@@ -13515,11 +13533,9 @@ speechSynthesis.getVoices();
|
||||
this.isStartAsMinimizedState.toString()
|
||||
);
|
||||
VRCXStorage.Set('VRCX_CloseToTray', this.isCloseToTray.toString());
|
||||
VRCXStorage.Set('VRCX_GPUFix', this.gpuFix.toString());
|
||||
AppApi.SetStartup(this.isStartAtWindowsStartup);
|
||||
};
|
||||
$app.watch.isStartAtWindowsStartup = saveVRCXWindowOption;
|
||||
$app.watch.isStartAsMinimizedState = saveVRCXWindowOption;
|
||||
$app.watch.isCloseToTray = saveVRCXWindowOption;
|
||||
$app.data.photonEventOverlay = configRepository.getBool(
|
||||
'VRCX_PhotonEventOverlay'
|
||||
);
|
||||
@@ -13539,6 +13555,9 @@ speechSynthesis.getVoices();
|
||||
$app.data.gameLogDisabled = configRepository.getBool(
|
||||
'VRCX_gameLogDisabled'
|
||||
);
|
||||
$app.data.udonExceptionLogging = configRepository.getBool(
|
||||
'VRCX_udonExceptionLogging'
|
||||
);
|
||||
$app.data.instanceUsersSortAlphabetical = configRepository.getBool(
|
||||
'VRCX_instanceUsersSortAlphabetical'
|
||||
);
|
||||
@@ -13877,12 +13896,24 @@ speechSynthesis.getVoices();
|
||||
);
|
||||
|
||||
$app.data.screenshotHelper = configRepository.getBool(
|
||||
'VRCX_screenshotHelper'
|
||||
'VRCX_screenshotHelper',
|
||||
true
|
||||
);
|
||||
|
||||
$app.data.screenshotHelperModifyFilename = configRepository.getBool(
|
||||
'VRCX_screenshotHelperModifyFilename'
|
||||
);
|
||||
|
||||
$app.data.enableAppLauncher = configRepository.getBool(
|
||||
'VRCX_enableAppLauncher',
|
||||
true
|
||||
);
|
||||
|
||||
$app.data.enableAppLauncherAutoClose = configRepository.getBool(
|
||||
'VRCX_enableAppLauncherAutoClose',
|
||||
true
|
||||
);
|
||||
|
||||
$app.methods.updateVRConfigVars = function () {
|
||||
var notificationTheme = 'relax';
|
||||
if (this.isDarkMode) {
|
||||
@@ -20662,6 +20693,22 @@ speechSynthesis.getVoices();
|
||||
AppApi.OpenShortcutFolder();
|
||||
};
|
||||
|
||||
$app.methods.updateAppLauncherSettings = function () {
|
||||
configRepository.setBool(
|
||||
'VRCX_enableAppLauncher',
|
||||
this.enableAppLauncher
|
||||
);
|
||||
configRepository.setBool(
|
||||
'VRCX_enableAppLauncherAutoClose',
|
||||
this.enableAppLauncherAutoClose
|
||||
);
|
||||
|
||||
AppApi.SetAppLauncherSettings(
|
||||
this.enableAppLauncher,
|
||||
this.enableAppLauncherAutoClose
|
||||
);
|
||||
};
|
||||
|
||||
// Screenshot Helper
|
||||
|
||||
$app.methods.saveScreenshotHelper = function () {
|
||||
|
||||
1536
html/src/index.pug
1536
html/src/index.pug
File diff suppressed because it is too large
Load Diff
@@ -354,8 +354,6 @@
|
||||
"header": "Advanced",
|
||||
"launch_options": "Launch Options",
|
||||
"screenshot_metadata": "Screenshot Metadata",
|
||||
"auto_launch": "Auto-Launch Folder",
|
||||
"auto_launch_tooltip": "To auto-launch apps with VRChat, place shortcuts in this folder.",
|
||||
"pending_offline": {
|
||||
"header": "Pending Offline",
|
||||
"description": "Delay before marking user as offline (fixes false positives)",
|
||||
@@ -401,8 +399,17 @@
|
||||
"modify_filename": "Modify Filename",
|
||||
"modify_filename_tooltip": "Will add the World ID to screenshot filename, in addition to file metadata."
|
||||
},
|
||||
"app_launcher": {
|
||||
"header": "App Launcher",
|
||||
"folder": "Auto-Launch Folder",
|
||||
"folder_tooltip": "To auto-launch apps with VRChat, place shortcuts in this folder.",
|
||||
"enable": "Enable",
|
||||
"auto_close": "Auto close apps"
|
||||
},
|
||||
"cache_debug": {
|
||||
"header": "VRCX Instance Cache/Debug",
|
||||
"udon_exception_logging": "Udon Exception Logging",
|
||||
"gpu_fix": "SteamVR Overlay GPU Fix",
|
||||
"disable_gamelog": "Disable GameLog",
|
||||
"disable_gamelog_notice": "(will likely break things)",
|
||||
"user_cache": "User cache:",
|
||||
|
||||
39
html/src/mixins/loginPage.pug
Normal file
39
html/src/mixins/loginPage.pug
Normal file
@@ -0,0 +1,39 @@
|
||||
mixin loginPage()
|
||||
.x-login-container(v-show="!API.isLoggedIn" v-loading="loginForm.loading")
|
||||
div(style="position:absolute;margin:5px")
|
||||
el-button(type="default" @click="showVRCXUpdateDialog" size="mini" icon="el-icon-download" circle)
|
||||
div(style="width:300px;margin:auto")
|
||||
div(style="margin:15px" v-if="Object.keys(loginForm.savedCredentials).length !== 0")
|
||||
h2(style="font-weight:bold;text-align:center;margin:0") {{ $t("view.login.savedAccounts") }}
|
||||
.x-friend-list(style="margin-top:10px")
|
||||
.x-friend-item(v-for="user in loginForm.savedCredentials" :key="user.user.id")
|
||||
.x-friend-item(@click="relogin(user)" style="width:202px;padding:0")
|
||||
.avatar
|
||||
img(v-lazy="userImage(user.user)")
|
||||
.detail
|
||||
span.name(v-text="user.user.displayName")
|
||||
span.extra(v-text="user.user.username")
|
||||
span.extra(v-text="user.loginParmas.endpoint")
|
||||
el-button(type="default" @click="deleteSavedLogin(user.user.id)" size="mini" icon="el-icon-delete" circle)
|
||||
div(style="margin:15px")
|
||||
h2(style="font-weight:bold;text-align:center;margin:0") {{ $t("view.login.login") }}
|
||||
el-form(ref="loginForm" :model="loginForm" :rules="loginForm.rules" @submit.native.prevent="login()")
|
||||
el-form-item(:label="$t('view.login.field.username')" prop="username" required)
|
||||
el-input(v-model="loginForm.username" name="username" :placeholder="$t('view.login.field.username')" clearable)
|
||||
el-form-item(:label="$t('view.login.field.password')" prop="password" required style="margin-top:10px")
|
||||
el-input(type="password" v-model="loginForm.password" name="password" :placeholder="$t('view.login.field.password')" clearable show-password)
|
||||
el-checkbox(v-model="loginForm.saveCredentials" style="margin-top:15px") {{ $t("view.login.field.saveCredentials") }}
|
||||
el-checkbox(v-model="enableCustomEndpoint" @change="toggleCustomEndpoint" style="margin-top:10px") {{ $t("view.login.field.devEndpoint") }}
|
||||
el-form-item(v-if="enableCustomEndpoint" :label="$t('view.login.field.endpoint')" prop="endpoint" style="margin-top:10px")
|
||||
el-input(v-model="loginForm.endpoint" name="endpoint" :placeholder="API.endpointDomainVrchat" clearable)
|
||||
el-form-item(v-if="enableCustomEndpoint" :label="$t('view.login.field.websocket')" prop="endpoint" style="margin-top:10px")
|
||||
el-input(v-model="loginForm.websocket" name="websocket" :placeholder="API.websocketDomainVrchat" clearable)
|
||||
el-form-item(style="margin-top:15px")
|
||||
el-button(native-type="submit" type="primary" :loading="loginForm.loading" style="width:100%") {{ $t("view.login.login") }}
|
||||
el-button(type="primary" @click="openExternalLink('https://vrchat.com/register')" :loading="loginForm.loading" style="width:100%") {{ $t("view.login.register") }}
|
||||
div(style="text-align:center;font-size:12px")
|
||||
p #[a.x-link(@click="openExternalLink('https://vrchat.com/home/password')") {{ $t("view.login.forgotPassword") }}]
|
||||
p © 2019-2022 #[a.x-link(@click="openExternalLink('https://github.com/pypy-vrc')") pypy] (mina#5656) & #[a.x-link(@click="openExternalLink('https://github.com/Natsumi-sama')") Natsumi]
|
||||
p {{ $t("view.settings.general.legal_notice.info") }}
|
||||
p {{ $t("view.settings.general.legal_notice.disclaimer1") }}
|
||||
p {{ $t("view.settings.general.legal_notice.disclaimer2") }}
|
||||
156
html/src/mixins/tabs/favorites.pug
Normal file
156
html/src/mixins/tabs/favorites.pug
Normal file
@@ -0,0 +1,156 @@
|
||||
mixin favoritesTab()
|
||||
.x-container(v-show="$refs.menu && $refs.menu.activeIndex === 'favorite'" v-if="$refs.menu && $refs.menu.activeIndex === 'favorite'")
|
||||
el-tooltip(placement="bottom" :content="$t('view.favorite.refresh_tooltip')" :disabled="hideTooltips")
|
||||
el-button(type="default" :loading="API.isFavoriteLoading" @click="API.refreshFavorites(); getLocalWorldFavorites()" size="small" icon="el-icon-refresh" circle style="position:relative;float:right;z-index:1")
|
||||
el-tabs(ref="favoriteTabRef" type="card" v-loading="API.isFavoriteLoading")
|
||||
el-tab-pane(:label="$t('view.favorite.friends.header')")
|
||||
el-collapse(v-if="$refs.menu && $refs.menu.activeIndex === 'favorite' && $refs.favoriteTabRef && $refs.favoriteTabRef.currentName === '0'" style="border:0")
|
||||
el-button(size="small" @click="showFriendExportDialog") {{ $t('view.favorite.export') }}
|
||||
el-button(size="small" @click="showFriendImportDialog") {{ $t('view.favorite.import') }}
|
||||
el-collapse-item(v-for="group in API.favoriteFriendGroups" :key="group.name")
|
||||
template(slot="title")
|
||||
span(v-text="group.displayName" style="font-weight:bold;font-size:14px;margin-left:10px")
|
||||
span(style="color:#909399;font-size:12px;margin-left:10px") {{ group.count }}/{{ group.capacity }}
|
||||
el-tooltip(placement="top" :content="$t('view.favorite.rename_tooltip')" :disabled="hideTooltips")
|
||||
el-button(@click.stop="changeFavoriteGroupName(group)" size="mini" icon="el-icon-edit" circle style="margin-left:10px")
|
||||
el-tooltip(placement="right" :content="$t('view.favorite.clear_tooltip')" :disabled="hideTooltips")
|
||||
el-button(@click.stop="clearFavoriteGroup(group)" size="mini" icon="el-icon-delete" circle style="margin-left:5px")
|
||||
.x-friend-list(v-if="group.count" style="margin-top:10px")
|
||||
div(style="display:inline-block;width:300px;margin-right:15px" v-for="favorite in favoriteFriends" v-if="favorite.groupKey === group.key" :key="favorite.id" @click="showUserDialog(favorite.id)")
|
||||
.x-friend-item
|
||||
template(v-if="favorite.ref")
|
||||
.avatar(:class="userStatusClass(favorite.ref)")
|
||||
img(v-lazy="userImage(favorite.ref)")
|
||||
.detail
|
||||
span.name(v-text="favorite.ref.displayName" :style="{'color':favorite.ref.$userColour}")
|
||||
location.extra(v-if="favorite.ref.location !== 'offline'" :location="favorite.ref.location" :traveling="favorite.ref.travelingToLocation" :link="false")
|
||||
span(v-else v-text="favorite.ref.statusDescription")
|
||||
el-tooltip(placement="left" :content="$t('view.favorite.move_tooltip')" :disabled="hideTooltips")
|
||||
el-dropdown(trigger="click" @click.native.stop size="mini" style="margin-left:5px")
|
||||
el-button(type="default" icon="el-icon-back" size="mini" circle)
|
||||
el-dropdown-menu(#default="dropdown")
|
||||
template(v-if="groupAPI.name !== group.name" v-for="groupAPI in API.favoriteFriendGroups" :key="groupAPI.name")
|
||||
el-dropdown-item(style="display:block;margin:10px 0" @click.native="moveFavorite(favorite.ref, groupAPI, 'friend')" :disabled="groupAPI.count >= groupAPI.capacity") {{ groupAPI.displayName }} ({{ groupAPI.count }} / {{ groupAPI.capacity }})
|
||||
el-tooltip(placement="right" :content="$t('view.favorite.unfavorite_tooltip')" :disabled="hideTooltips")
|
||||
el-button(@click.stop="deleteFavorite(favorite.id)" size="mini" icon="el-icon-delete" circle style="margin-left:5px")
|
||||
template(v-else)
|
||||
span(v-text="favorite.name || favorite.id")
|
||||
el-button(type="text" icon="el-icon-close" size="mini" @click.stop="deleteFavorite(favorite.id)" style="margin-left:5px")
|
||||
el-tab-pane(:label="$t('view.favorite.worlds.header')")
|
||||
el-collapse(v-if="$refs.menu && $refs.menu.activeIndex === 'favorite' && $refs.favoriteTabRef && $refs.favoriteTabRef.currentName === '1'" style="border:0")
|
||||
el-button(size="small" @click="showWorldExportDialog") {{ $t('view.favorite.export') }}
|
||||
el-button(size="small" @click="showWorldImportDialog") {{ $t('view.favorite.import') }}
|
||||
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")
|
||||
span(v-text="group.displayName" style="font-weight:bold;font-size:14px;margin-left:10px")
|
||||
i.x-user-status(style="margin-left:5px" :class="userFavoriteWorldsStatus(group.visibility)")
|
||||
span(style="color:#909399;font-size:12px;margin-left:10px") {{ group.count }}/{{ group.capacity }}
|
||||
el-tooltip(placement="top" :content="$t('view.favorite.visibility_tooltip')" :disabled="hideTooltips")
|
||||
el-dropdown(trigger="click" @click.native.stop size="mini" style="margin-left:10px")
|
||||
el-button(type="default" icon="el-icon-view" size="mini" circle)
|
||||
el-dropdown-menu(#default="dropdown")
|
||||
el-dropdown-item(v-if="group.visibility !== visibility" v-for="visibility in worldGroupVisibilityOptions" :key="visibility" style="display:block;margin:10px 0" v-text="visibility" @click.native="changeWorldGroupVisibility(group.name, visibility)")
|
||||
el-tooltip(placement="top" :content="$t('view.favorite.rename_tooltip')" :disabled="hideTooltips")
|
||||
el-button(@click.stop="changeFavoriteGroupName(group)" size="mini" icon="el-icon-edit" circle style="margin-left:5px")
|
||||
el-tooltip(placement="right" :content="$t('view.favorite.clear_tooltip')" :disabled="hideTooltips")
|
||||
el-button(@click.stop="clearFavoriteGroup(group)" size="mini" icon="el-icon-delete" circle style="margin-left:5px")
|
||||
.x-friend-list(v-if="group.count" style="margin-top:10px")
|
||||
div(style="display:inline-block;width:300px;margin-right:15px" v-for="favorite in favoriteWorlds" v-if="favorite.groupKey === group.key" :key="favorite.id" @click="showWorldDialog(favorite.id)")
|
||||
.x-friend-item
|
||||
template(v-if="favorite.ref")
|
||||
.avatar
|
||||
img(v-lazy="favorite.ref.thumbnailImageUrl")
|
||||
.detail
|
||||
span.name(v-text="favorite.ref.name")
|
||||
span.extra(v-if="favorite.ref.occupants") {{ favorite.ref.authorName }} ({{ favorite.ref.occupants }})
|
||||
span.extra(v-else v-text="favorite.ref.authorName")
|
||||
el-tooltip(placement="left" :content="$t('view.favorite.move_tooltip')" :disabled="hideTooltips")
|
||||
el-dropdown(trigger="click" @click.native.stop size="mini" style="margin-left:5px")
|
||||
el-button(type="default" icon="el-icon-back" size="mini" circle)
|
||||
el-dropdown-menu(#default="dropdown")
|
||||
template(v-if="groupAPI.name !== group.name" v-for="groupAPI in API.favoriteWorldGroups" :key="groupAPI.name")
|
||||
el-dropdown-item(style="display:block;margin:10px 0" @click.native="moveFavorite(favorite.ref, groupAPI, 'world')" :disabled="groupAPI.count >= groupAPI.capacity") {{ groupAPI.displayName }} ({{ groupAPI.count }} / {{ groupAPI.capacity }})
|
||||
el-tooltip(placement="right" :content="$t('view.favorite.unfavorite_tooltip')" :disabled="hideTooltips")
|
||||
el-button(@click.stop="deleteFavorite(favorite.id)" size="mini" icon="el-icon-delete" circle style="margin-left:5px")
|
||||
template(v-else)
|
||||
span(v-text="favorite.name || favorite.id")
|
||||
el-button(type="text" icon="el-icon-close" size="mini" @click.stop="deleteFavorite(favorite.id)" style="margin-left:5px")
|
||||
span(style="display:block;margin-top:20px") {{ $t('view.favorite.worlds.local_favorites') }}
|
||||
el-button(size="small" @click="promptNewLocalWorldFavoriteGroup" style="display:block;margin-top:10px") {{ $t('view.favorite.worlds.new_group') }}
|
||||
el-collapse-item(v-for="group in localWorldFavoriteGroups" v-if="localWorldFavorites[group]" :key="group")
|
||||
template(slot="title")
|
||||
span(v-text="group" style="font-weight:bold;font-size:14px;margin-left:10px")
|
||||
span(style="color:#909399;font-size:12px;margin-left:10px") {{ getLocalWorldFavoriteGroupLength(group) }}
|
||||
el-tooltip(placement="top" :content="$t('view.favorite.rename_tooltip')" :disabled="hideTooltips")
|
||||
el-button(@click.stop="promptLocalWorldFavoriteGroupRename(group)" size="mini" icon="el-icon-edit" circle style="margin-left:10px")
|
||||
el-tooltip(placement="right" :content="$t('view.favorite.delete_tooltip')" :disabled="hideTooltips")
|
||||
el-button(@click.stop="promptLocalWorldFavoriteGroupDelete(group)" size="mini" icon="el-icon-delete" circle style="margin-left:5px")
|
||||
.x-friend-list(style="margin-top:10px")
|
||||
div(style="display:inline-block;width:300px;margin-right:15px" v-for="favorite in localWorldFavorites[group]" :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")
|
||||
el-tooltip(placement="right" :content="$t('view.favorite.unfavorite_tooltip')" :disabled="hideTooltips")
|
||||
el-button(@click.stop="removeLocalWorldFavorite(favorite.id, group)" size="mini" icon="el-icon-delete" circle style="margin-left:5px")
|
||||
template(v-else)
|
||||
span(v-text="favorite.id")
|
||||
el-button(type="text" icon="el-icon-close" size="mini" @click.stop="removeLocalWorldFavorite(favorite.id, group)" style="margin-left:5px")
|
||||
el-tab-pane(:label="$t('view.favorite.avatars.header')")
|
||||
el-collapse(v-if="$refs.menu && $refs.menu.activeIndex === 'favorite' && $refs.favoriteTabRef && $refs.favoriteTabRef.currentName === '2'" style="border:0")
|
||||
el-button(size="small" @click="showAvatarExportDialog") {{ $t('view.favorite.export') }}
|
||||
el-button(size="small" @click="showAvatarImportDialog") {{ $t('view.favorite.import') }}
|
||||
el-collapse-item(v-for="group in API.favoriteAvatarGroups" :key="group.name")
|
||||
template(slot="title")
|
||||
span(v-text="group.displayName" style="font-weight:bold;font-size:14px;margin-left:10px")
|
||||
span(style="color:#909399;font-size:12px;margin-left:10px") {{ group.count }}/{{ group.capacity }}
|
||||
el-tooltip(placement="top" :content="$t('view.favorite.rename_tooltip')" :disabled="hideTooltips")
|
||||
el-button(@click.stop="changeFavoriteGroupName(group)" size="mini" icon="el-icon-edit" circle style="margin-left:10px")
|
||||
el-tooltip(placement="right" :content="$t('view.favorite.clear_tooltip')" :disabled="hideTooltips")
|
||||
el-button(@click.stop="clearFavoriteGroup(group)" size="mini" icon="el-icon-delete" circle style="margin-left:5px")
|
||||
.x-friend-list(v-if="group.count" style="margin-top:10px")
|
||||
div(style="display:inline-block;width:300px;margin-right:15px" v-for="favorite in favoriteAvatars" v-if="favorite.groupKey === group.key" :key="favorite.id" @click="showAvatarDialog(favorite.id)")
|
||||
.x-friend-item
|
||||
template(v-if="favorite.ref")
|
||||
.avatar
|
||||
img(v-lazy="favorite.ref.thumbnailImageUrl")
|
||||
.detail
|
||||
span.name(v-text="favorite.ref.name")
|
||||
span.extra(v-text="favorite.ref.authorName")
|
||||
el-tooltip(placement="left" :content="$t('view.favorite.move_tooltip')" :disabled="hideTooltips")
|
||||
el-dropdown(trigger="click" @click.native.stop size="mini" style="margin-left:5px")
|
||||
el-button(type="default" icon="el-icon-back" size="mini" circle)
|
||||
el-dropdown-menu(#default="dropdown")
|
||||
template(v-if="groupAPI.name !== group.name" v-for="groupAPI in API.favoriteAvatarGroups" :key="groupAPI.name")
|
||||
el-dropdown-item(style="display:block;margin:10px 0" @click.native="moveFavorite(favorite.ref, groupAPI, 'avatar')" :disabled="groupAPI.count >= groupAPI.capacity") {{ groupAPI.displayName }} ({{ groupAPI.count }} / {{ groupAPI.capacity }})
|
||||
el-tooltip(placement="right" :content="$t('view.favorite.unfavorite_tooltip')" :disabled="hideTooltips")
|
||||
el-button(@click.stop="deleteFavorite(favorite.id)" size="mini" icon="el-icon-delete" circle style="margin-left:5px")
|
||||
template(v-else)
|
||||
.detail
|
||||
span.name(v-text="favorite.name || favorite.id")
|
||||
el-button(type="text" icon="el-icon-close" size="mini" @click.stop="deleteFavorite(favorite.id)" style="margin-left:5px")
|
||||
el-collapse-item
|
||||
template(slot="title")
|
||||
span(style="font-weight:bold;font-size:14px;margin-left:10px") Local History
|
||||
span(style="color:#909399;font-size:12px;margin-left:10px") {{ avatarHistoryArray.length }}/100
|
||||
el-tooltip(placement="right" content="Clear" :disabled="hideTooltips")
|
||||
el-button(@click.stop="promptClearAvatarHistory" size="mini" icon="el-icon-delete" circle style="margin-left:5px")
|
||||
.x-friend-list(v-if="avatarHistoryArray.length" style="margin-top:10px")
|
||||
div(style="display:inline-block;width:300px;margin-right:15px" v-for="favorite in avatarHistoryArray" :key="favorite.id" @click="showAvatarDialog(favorite.id)")
|
||||
.x-friend-item
|
||||
.avatar
|
||||
img(v-lazy="favorite.thumbnailImageUrl")
|
||||
.detail
|
||||
span.name(v-text="favorite.name")
|
||||
span.extra(v-text="favorite.authorName")
|
||||
template(v-if="API.cachedFavoritesByObjectId.has(favorite.id)")
|
||||
el-tooltip(placement="left" content="Unfavorite" :disabled="hideTooltips")
|
||||
el-button(@click.stop="deleteFavorite(favorite.id)" type="default" icon="el-icon-star-on" size="mini" circle)
|
||||
template(v-else)
|
||||
el-tooltip(placement="left" content="Favorite" :disabled="hideTooltips")
|
||||
el-button(@click.stop="showFavoriteDialog('avatar', favorite.id)" type="default" icon="el-icon-star-off" size="mini" circle)
|
||||
116
html/src/mixins/tabs/feed.pug
Normal file
116
html/src/mixins/tabs/feed.pug
Normal file
@@ -0,0 +1,116 @@
|
||||
mixin feedTab()
|
||||
.x-container(v-show="$refs.menu && $refs.menu.activeIndex === 'feed'")
|
||||
data-tables(v-bind="feedTable" v-loading="feedTable.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="feedTable.vip" @change="feedTableLookup" active-color="#13ce66")
|
||||
el-select(v-model="feedTable.filter" @change="feedTableLookup" multiple clearable collapse-tags style="flex:1" :placeholder="$t('view.feed.filter_placeholder')")
|
||||
el-option(v-once v-for="type in ['GPS', 'Online', 'Offline', 'Status', 'Avatar', 'Bio']" :key="type" :label="type" :value="type")
|
||||
el-input(v-model="feedTable.search" :placeholder="$t('view.feed.search_placeholder')" @keyup.native.13="feedTableLookup" @change="feedTableLookup" clearable style="flex:none;width:150px;margin:0 10px")
|
||||
//- el-tooltip(placement="bottom" content="Clear feed" :disabled="hideTooltips")
|
||||
//- el-button(type="default" @click="clearFeed()" icon="el-icon-delete" circle style="flex:none")
|
||||
el-table-column(type="expand" width="20")
|
||||
template(v-once #default="scope")
|
||||
div(style="position:relative;font-size:14px")
|
||||
template(v-if="scope.row.type === 'GPS'")
|
||||
location(v-if="scope.row.previousLocation" :location="scope.row.previousLocation")
|
||||
el-tag(type="info" effect="plain" size="mini" style="margin-left:5px") {{ scope.row.time | timeToText }}
|
||||
br
|
||||
span
|
||||
i.el-icon-right
|
||||
location(v-if="scope.row.location" :location="scope.row.location" :hint="scope.row.worldName" :grouphint="scope.row.groupName")
|
||||
template(v-else-if="scope.row.type === 'Offline'")
|
||||
template(v-if="scope.row.location")
|
||||
location(:location="scope.row.location" :hint="scope.row.worldName" :grouphint="scope.row.groupName")
|
||||
el-tag(type="info" effect="plain" size="mini" style="margin-left:5px") {{ scope.row.time | timeToText }}
|
||||
template(v-else-if="scope.row.type === 'Online'")
|
||||
location(v-if="scope.row.location" :location="scope.row.location" :hint="scope.row.worldName" :grouphint="scope.row.groupName")
|
||||
template(v-else-if="scope.row.type === 'Avatar'")
|
||||
el-popover(placement="right" width="500px" trigger="click")
|
||||
img.x-link(slot="reference" v-lazy="scope.row.previousCurrentAvatarThumbnailImageUrl" style="flex:none;width:160px;height:120px;border-radius:4px")
|
||||
img.x-link(v-lazy="scope.row.previousCurrentAvatarImageUrl" style="width:500px;height:375px" @click="showAvatarAuthorDialog(scope.row.userId, '', scope.row.previousCurrentAvatarImageUrl)")
|
||||
span(style="position:relative;top:-50px;margin:0 5px")
|
||||
i.el-icon-right
|
||||
el-popover(placement="right" width="500px" trigger="click")
|
||||
img.x-link(slot="reference" v-lazy="scope.row.currentAvatarThumbnailImageUrl" style="flex:none;width:160px;height:120px;border-radius:4px")
|
||||
img.x-link(v-lazy="scope.row.currentAvatarImageUrl" style="width:500px;height:375px" @click="showAvatarAuthorDialog(scope.row.userId, '', scope.row.currentAvatarImageUrl)")
|
||||
template(v-else-if="scope.row.type === 'Status'")
|
||||
el-tooltip(placement="top")
|
||||
template(#content)
|
||||
span(v-if="scope.row.previousStatus === 'active'") {{ $t('dialog.user.status.active') }}
|
||||
span(v-else-if="scope.row.previousStatus === 'join me'") {{ $t('dialog.user.status.join_me') }}
|
||||
span(v-else-if="scope.row.previousStatus === 'ask me'") {{ $t('dialog.user.status.ask_me') }}
|
||||
span(v-else-if="scope.row.previousStatus === 'busy'") {{ $t('dialog.user.status.busy') }}
|
||||
span(v-else) {{ $t('dialog.user.status.offline') }}
|
||||
i.x-user-status(:class="statusClass(scope.row.previousStatus)")
|
||||
span(v-text="scope.row.previousStatusDescription")
|
||||
br
|
||||
span
|
||||
i.el-icon-right
|
||||
el-tooltip(placement="top")
|
||||
template(#content)
|
||||
span(v-if="scope.row.status === 'active'") {{ $t('dialog.user.status.active') }}
|
||||
span(v-else-if="scope.row.status === 'join me'") {{ $t('dialog.user.status.join_me') }}
|
||||
span(v-else-if="scope.row.status === 'ask me'") {{ $t('dialog.user.status.ask_me') }}
|
||||
span(v-else-if="scope.row.status === 'busy'") {{ $t('dialog.user.status.busy') }}
|
||||
span(v-else) {{ $t('dialog.user.status.offline') }}
|
||||
i.x-user-status(:class="statusClass(scope.row.status)")
|
||||
span(v-text="scope.row.statusDescription")
|
||||
template(v-else-if="scope.row.type === 'Bio'")
|
||||
pre(v-text="scope.row.previousBio" style="font-family:inherit;font-size:12px;white-space:pre-wrap;margin:0 0.5em 0 0")
|
||||
span
|
||||
i.el-icon-right
|
||||
pre(v-text="scope.row.bio" style="font-family:inherit;font-size:12px;white-space:pre-wrap;margin:0 0.5em 0 0")
|
||||
el-table-column(:label="$t('table.feed.date')" prop="created_at" sortable="custom" width="120")
|
||||
template(v-once #default="scope")
|
||||
el-tooltip(placement="right")
|
||||
template(#content)
|
||||
span {{ scope.row.created_at | formatDate('long') }}
|
||||
span {{ scope.row.created_at | formatDate('short') }}
|
||||
el-table-column(:label="$t('table.feed.type')" prop="type" width="70")
|
||||
el-table-column(:label="$t('table.feed.user')" prop="displayName" width="180")
|
||||
template(v-once #default="scope")
|
||||
span.x-link(v-text="scope.row.displayName" @click="showUserDialog(scope.row.userId)")
|
||||
el-table-column(:label="$t('table.feed.detail')")
|
||||
template(v-once #default="scope")
|
||||
template(v-if="scope.row.type === 'GPS'")
|
||||
location(v-if="scope.row.location" :location="scope.row.location" :hint="scope.row.worldName" :grouphint="scope.row.groupName")
|
||||
template(v-else-if="scope.row.type === 'Offline' || scope.row.type === 'Online'")
|
||||
location(v-if="scope.row.location" :location="scope.row.location" :hint="scope.row.worldName" :grouphint="scope.row.groupName")
|
||||
template(v-else-if="scope.row.type === 'Status'")
|
||||
template(v-if="scope.row.statusDescription === scope.row.previousStatusDescription")
|
||||
el-tooltip(placement="top")
|
||||
template(#content)
|
||||
span(v-if="scope.row.previousStatus === 'active'") {{ $t('dialog.user.status.active') }}
|
||||
span(v-else-if="scope.row.previousStatus === 'join me'") {{ $t('dialog.user.status.join_me') }}
|
||||
span(v-else-if="scope.row.previousStatus === 'ask me'") {{ $t('dialog.user.status.ask_me') }}
|
||||
span(v-else-if="scope.row.previousStatus === 'busy'") {{ $t('dialog.user.status.busy') }}
|
||||
span(v-else) {{ $t('dialog.user.status.offline') }}
|
||||
i.x-user-status(:class="statusClass(scope.row.previousStatus)")
|
||||
span
|
||||
i.el-icon-right
|
||||
el-tooltip(placement="top")
|
||||
template(#content)
|
||||
span(v-if="scope.row.status === 'active'") {{ $t('dialog.user.status.active') }}
|
||||
span(v-else-if="scope.row.status === 'join me'") {{ $t('dialog.user.status.join_me') }}
|
||||
span(v-else-if="scope.row.status === 'ask me'") {{ $t('dialog.user.status.ask_me') }}
|
||||
span(v-else-if="scope.row.status === 'busy'") {{ $t('dialog.user.status.busy') }}
|
||||
span(v-else) {{ $t('dialog.user.status.offline') }}
|
||||
i.x-user-status(:class="statusClass(scope.row.status)")
|
||||
template(v-else)
|
||||
el-tooltip(placement="top")
|
||||
template(#content)
|
||||
span(v-if="scope.row.status === 'active'") {{ $t('dialog.user.status.active') }}
|
||||
span(v-else-if="scope.row.status === 'join me'") {{ $t('dialog.user.status.join_me') }}
|
||||
span(v-else-if="scope.row.status === 'ask me'") {{ $t('dialog.user.status.ask_me') }}
|
||||
span(v-else-if="scope.row.status === 'busy'") {{ $t('dialog.user.status.busy') }}
|
||||
span(v-else) {{ $t('dialog.user.status.offline') }}
|
||||
i.x-user-status(:class="statusClass(scope.row.status)")
|
||||
span
|
||||
span(v-text="scope.row.statusDescription")
|
||||
template(v-else-if="scope.row.type === 'Avatar'")
|
||||
avatar-info(:imageurl="scope.row.currentAvatarImageUrl" :userid="scope.row.userId" :hintownerid="scope.row.ownerId" :hintavatarname="scope.row.avatarName")
|
||||
template(v-else-if="scope.row.type === 'Bio'")
|
||||
span(v-text="scope.row.bio")
|
||||
24
html/src/mixins/tabs/friendLog.pug
Normal file
24
html/src/mixins/tabs/friendLog.pug
Normal file
@@ -0,0 +1,24 @@
|
||||
mixin friendLogTab()
|
||||
.x-container(v-show="$refs.menu && $refs.menu.activeIndex === 'friendLog'" v-if="$refs.menu && $refs.menu.activeIndex === 'friendLog'")
|
||||
data-tables(v-bind="friendLogTable")
|
||||
template(#tool)
|
||||
div(style="margin:0 0 10px;display:flex;align-items:center")
|
||||
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="120")
|
||||
template(v-once #default="scope")
|
||||
el-tooltip(placement="right")
|
||||
template(#content)
|
||||
span {{ scope.row.created_at | formatDate('long') }}
|
||||
span {{ scope.row.created_at | formatDate('short') }}
|
||||
el-table-column(:label="$t('table.friendLog.type')" prop="type" width="150")
|
||||
el-table-column(:label="$t('table.friendLog.user')" prop="displayName")
|
||||
template(v-once #default="scope")
|
||||
span(v-if="scope.row.type === 'DisplayName'") {{ scope.row.previousDisplayName }} #[i.el-icon-right]
|
||||
span.x-link(v-text="scope.row.displayName || scope.row.userId" @click="showUserDialog(scope.row.userId)")
|
||||
template(v-if="scope.row.type === 'TrustLevel'")
|
||||
span ({{ scope.row.previousTrustLevel }} #[i.el-icon-right] {{ scope.row.trustLevel }})
|
||||
el-table-column(:label="$t('table.friendLog.action')" width="80" align="right")
|
||||
template(v-once #default="scope")
|
||||
el-button(type="text" icon="el-icon-close" size="mini" @click="deleteFriendLog(scope.row)")
|
||||
85
html/src/mixins/tabs/friendsList.pug
Normal file
85
html/src/mixins/tabs/friendsList.pug
Normal file
@@ -0,0 +1,85 @@
|
||||
mixin friendsListTab()
|
||||
.x-container(v-show="$refs.menu && $refs.menu.activeIndex === 'friendsList'" v-if="$refs.menu && $refs.menu.activeIndex === 'friendsList'")
|
||||
div.options-container(style="margin-top:0")
|
||||
span.header {{ $t('view.friend_list.header') }}
|
||||
div(style="float:right;font-size:13px")
|
||||
div(v-if="friendsListBulkUnfriendMode" style="display:inline-block;margin-right:10px")
|
||||
el-button(size="small" @click="showBulkUnfriendSelectionConfirm") {{ $t('view.friend_list.bulk_unfriend_selection') }}
|
||||
//- el-button(size="small" @click="showBulkUnfriendAllConfirm" style="margin-right:5px") Bulk Unfriend All
|
||||
div(style="display:inline-block;margin-right:10px")
|
||||
span.name {{ $t('view.friend_list.bulk_unfriend') }}
|
||||
el-switch(v-model="friendsListBulkUnfriendMode" style="margin-left:5px")
|
||||
span {{ $t('view.friend_list.load') }}
|
||||
el-tooltip(placement="top" style="margin-left:5px" :content="$t('view.friend_list.load_notice')")
|
||||
i.el-icon-warning
|
||||
template(v-if="friendsListLoading")
|
||||
span(v-text="friendsListLoadingProgress" style="margin-left:5px")
|
||||
el-tooltip(placement="top" :content="$t('view.friend_list.cancel_tooltip')" :disabled="hideTooltips")
|
||||
el-button(@click="friendsListLoading = false" size="mini" icon="el-icon-loading" circle style="margin-left:5px")
|
||||
template(v-else)
|
||||
el-tooltip(placement="top" :content="$t('view.friend_list.load_tooltip')" :disabled="hideTooltips")
|
||||
el-button(@click="friendsListLoadUsers" size="mini" icon="el-icon-refresh-left" circle style="margin-left:5px")
|
||||
div(style="margin:10px 0 0 10px;display:flex;align-items:center")
|
||||
div(style="flex:none;margin-right:10px")
|
||||
el-tooltip(placement="bottom" :content="$t('view.friend_list.favorites_only_tooltip')" :disabled="hideTooltips")
|
||||
el-switch(v-model="friendsListSearchFilterVIP" @change="friendsListSearchChange" active-color="#13ce66")
|
||||
el-input(v-model="friendsListSearch" :placeholder="$t('view.friend_list.search_placeholder')" @change="friendsListSearchChange" clearable style="flex:1")
|
||||
el-select(v-model="friendsListSearchFilters" multiple clearable collapse-tags style="flex:none;width:200px;margin:0 10px" @change="friendsListSearchChange" :placeholder="$t('view.friend_list.filter_placeholder')")
|
||||
el-option(v-once v-for="type in ['Display Name', 'User Name', 'Rank', 'Status', 'Bio', 'Memo']" :key="type" :label="type" :value="type")
|
||||
el-tooltip(placement="top" :content="$t('view.friend_list.refresh_tooltip')" :disabled="hideTooltips")
|
||||
el-button(type="default" @click="friendsListSearchChange" icon="el-icon-refresh" circle style="flex:none")
|
||||
el-tooltip(placement="top" :content="$t('view.friend_list.clear_tooltip')" :disabled="hideTooltips")
|
||||
el-button(type="default" @click="friendsListTable.data = []" icon="el-icon-delete" circle style="flex:none;margin-left:5px")
|
||||
data-tables(v-bind="friendsListTable" @row-click="selectFriendsListRow" style="margin-top:10px;cursor:pointer")
|
||||
el-table-column(v-if="friendsListBulkUnfriendMode" width="55" prop="$selected")
|
||||
template(v-once #default="scope")
|
||||
el-button(type="text" size="mini" @click.stop)
|
||||
el-checkbox(v-model="scope.row.$selected")
|
||||
el-table-column(:label="$t('table.friendList.no')" width="70" prop="$friendNum" sortable="custom")
|
||||
el-table-column(:label="$t('table.friendList.avatar')" width="70" prop="photo")
|
||||
template(v-once #default="scope")
|
||||
el-popover(placement="right" height="500px" trigger="hover")
|
||||
img.friends-list-avatar(slot="reference" v-lazy="userImage(scope.row)")
|
||||
img.friends-list-avatar(v-lazy="userImageFull(scope.row)" style="height:500px;cursor:pointer" @click="downloadAndSaveImage(userImageFull(scope.row))")
|
||||
el-table-column(:label="$t('table.friendList.displayName')" min-width="140" prop="displayName" sortable :sort-method="(a, b) => sortAlphabetically(a, b, 'displayName')")
|
||||
template(v-once #default="scope")
|
||||
span.name(v-if="randomUserColours" v-text="scope.row.displayName" :style="{'color':scope.row.$userColour}")
|
||||
span.name(v-else v-text="scope.row.displayName")
|
||||
el-table-column(:label="$t('table.friendList.rank')" width="110" prop="$trustSortNum" sortable="custom")
|
||||
template(v-once #default="scope")
|
||||
span.name(v-if="randomUserColours" v-text="scope.row.$trustLevel" :class="scope.row.$trustClass")
|
||||
span.name(v-else v-text="scope.row.$trustLevel" :style="{'color':scope.row.$userColour}")
|
||||
el-table-column(:label="$t('table.friendList.status')" min-width="180" prop="status" sortable :sort-method="(a, b) => sortStatus(a.status, b.status)")
|
||||
template(v-once #default="scope")
|
||||
i.x-user-status(v-if="scope.row.status !== 'offline'" :class="statusClass(scope.row.status)")
|
||||
span
|
||||
span(v-text="scope.row.statusDescription")
|
||||
el-table-column(:label="$t('table.friendList.language')" width="110" prop="$languages" sortable :sort-method="(a, b) => sortLanguages(a, b)")
|
||||
template(v-once #default="scope")
|
||||
el-tooltip(v-for="item in scope.row.$languages" :key="item.key" placement="top")
|
||||
template(#content)
|
||||
span {{ item.value }} ({{ item.key }})
|
||||
span.flags(:class="languageClass(item.key)" style="display:inline-block;margin-left:5px")
|
||||
el-table-column(:label="$t('table.friendList.bioLink')" width="100" prop="bioLinks")
|
||||
template(v-once #default="scope")
|
||||
el-tooltip(v-if="link" v-for="(link, index) in scope.row.bioLinks" :key="index")
|
||||
template(#content)
|
||||
span(v-text="link")
|
||||
img(:src="getFaviconUrl(link)" style="width:16px;height:16px;vertical-align:middle;margin-right:5px;cursor:pointer" @click.stop="openExternalLink(link)")
|
||||
el-table-column(:label="$t('table.friendList.joinCount')" width="120" prop="$joinCount" sortable)
|
||||
el-table-column(:label="$t('table.friendList.timeTogether')" width="140" prop="$timeSpent" sortable)
|
||||
template(v-once #default="scope")
|
||||
span(v-if="scope.row.$timeSpent") {{ scope.row.$timeSpent | timeToText }}
|
||||
el-table-column(:label="$t('table.friendList.lastSeen')" width="170" prop="$lastSeen" sortable :sort-method="(a, b) => sortAlphabetically(a, b, '$lastSeen')")
|
||||
template(v-once #default="scope")
|
||||
span {{ scope.row.$lastSeen | formatDate('long') }}
|
||||
el-table-column(:label="$t('table.friendList.lastActivity')" width="170" prop="last_activity" sortable :sort-method="(a, b) => sortAlphabetically(a, b, 'last_activity')")
|
||||
template(v-once #default="scope")
|
||||
span {{ scope.row.last_activity | formatDate('long') }}
|
||||
el-table-column(:label="$t('table.friendList.lastLogin')" width="170" prop="last_login" sortable :sort-method="(a, b) => sortAlphabetically(a, b, 'last_login')")
|
||||
template(v-once #default="scope")
|
||||
span {{ scope.row.last_login | formatDate('long') }}
|
||||
el-table-column(:label="$t('table.friendList.dateJoined')" width="120" prop="date_joined" sortable :sort-method="(a, b) => sortAlphabetically(a, b, 'date_joined')")
|
||||
el-table-column(:label="$t('table.friendList.unfriend')" width="80")
|
||||
template(v-once #default="scope")
|
||||
el-button(type="text" icon="el-icon-close" size="mini" @click.stop="confirmDeleteFriend(scope.row.id)")
|
||||
50
html/src/mixins/tabs/gameLog.pug
Normal file
50
html/src/mixins/tabs/gameLog.pug
Normal file
@@ -0,0 +1,50 @@
|
||||
mixin gameLogTab()
|
||||
.x-container(v-show="$refs.menu && $refs.menu.activeIndex === 'gameLog'")
|
||||
data-tables(v-bind="gameLogTable" v-loading="gameLogTable.loading")
|
||||
template(#tool)
|
||||
div(style="margin:0 0 10px;display:flex;align-items:center")
|
||||
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', 'Event', 'VideoPlay', '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")
|
||||
//- el-tooltip(placement="bottom" content="Reload game log" :disabled="hideTooltips")
|
||||
//- el-button(type="default" @click="resetGameLog" icon="el-icon-refresh" circle style="flex:none")
|
||||
el-table-column(:label="$t('table.gameLog.date')" prop="created_at" sortable="custom" width="120")
|
||||
template(v-once #default="scope")
|
||||
el-tooltip(placement="right")
|
||||
template(#content)
|
||||
span {{ scope.row.created_at | formatDate('long') }}
|
||||
span {{ scope.row.created_at | formatDate('short') }}
|
||||
el-table-column(:label="$t('table.gameLog.type')" prop="type" width="120")
|
||||
template(v-once #default="scope")
|
||||
span.x-link(v-if="scope.row.location && scope.row.type !== 'Location'" v-text="scope.row.type" @click="showWorldDialog(scope.row.location)")
|
||||
span(v-else v-text="scope.row.type")
|
||||
el-table-column(:label="$t('table.gameLog.icon')" prop="isFriend" width="60")
|
||||
template(v-once #default="scope")
|
||||
template(v-if="gameLogIsFriend(scope.row)")
|
||||
el-tooltip(v-if="gameLogIsFavorite(scope.row)" placement="top" content="Favorite")
|
||||
span ⭐
|
||||
el-tooltip(v-else placement="top" content="Friend")
|
||||
span 💚
|
||||
el-table-column(:label="$t('table.gameLog.user')" prop="displayName" width="180")
|
||||
template(v-once #default="scope")
|
||||
span.x-link(v-if="scope.row.displayName" v-text="scope.row.displayName" @click="lookupUser(scope.row)" style="padding-right:10px")
|
||||
el-table-column(:label="$t('table.gameLog.detail')" prop="data")
|
||||
template(v-once #default="scope")
|
||||
location(v-if="scope.row.type === 'Location'" :location="scope.row.location" :hint="scope.row.worldName" :grouphint="scope.row.groupName")
|
||||
location(v-else-if="scope.row.type === 'PortalSpawn'" :location="scope.row.instanceId" :hint="scope.row.worldName" :grouphint="scope.row.groupName")
|
||||
template(v-else-if="scope.row.type === 'Event'")
|
||||
span(v-text="scope.row.data")
|
||||
template(v-else-if="scope.row.type === 'VideoPlay'")
|
||||
span(v-if="scope.row.videoId" style="margin-right:5px") {{ scope.row.videoId }}:
|
||||
span(v-if="scope.row.videoId === 'LSMedia'" v-text="scope.row.videoName")
|
||||
span.x-link(v-else-if="scope.row.videoName" @click="openExternalLink(scope.row.videoUrl)" v-text="scope.row.videoName")
|
||||
span.x-link(v-else @click="openExternalLink(scope.row.videoUrl)" v-text="scope.row.videoUrl")
|
||||
template(v-else-if="scope.row.type === 'ImageLoad'")
|
||||
span.x-link(@click="openExternalLink(scope.row.resourceUrl)" v-text="scope.row.resourceUrl")
|
||||
template(v-else-if="scope.row.type === 'StringLoad'")
|
||||
span.x-link(@click="openExternalLink(scope.row.resourceUrl)" v-text="scope.row.resourceUrl")
|
||||
template(v-else-if="scope.row.type === 'Notification' || scope.row.type === 'OnPlayerJoined' || scope.row.type === 'OnPlayerLeft'")
|
||||
span.x-link(v-else v-text="scope.row.data")
|
||||
el-table-column(:label="$t('table.gameLog.action')" width="80" align="right")
|
||||
template(v-once #default="scope")
|
||||
el-button(v-if="scope.row.type !== 'OnPlayerJoined' && scope.row.type !== 'OnPlayerLeft' && scope.row.type !== 'Location' && scope.row.type !== 'PortalSpawn'" type="text" icon="el-icon-close" size="mini" @click="deleteGameLogEntry(scope.row)")
|
||||
26
html/src/mixins/tabs/moderation.pug
Normal file
26
html/src/mixins/tabs/moderation.pug
Normal file
@@ -0,0 +1,26 @@
|
||||
mixin moderationTab()
|
||||
.x-container(v-show="$refs.menu && $refs.menu.activeIndex === 'moderation'" v-if="$refs.menu && $refs.menu.activeIndex === 'moderation'")
|
||||
data-tables(v-bind="playerModerationTable" v-loading="API.isPlayerModerationsLoading")
|
||||
template(#tool)
|
||||
div(style="margin:0 0 10px;display:flex;align-items:center")
|
||||
el-select(v-model="playerModerationTable.filters[0].value" @change="saveTableFilters" multiple clearable collapse-tags style="flex:1" :placeholder="$t('view.moderation.filter_placeholder')")
|
||||
el-option(v-once v-for="type in ['block', 'unblock', 'mute', 'unmute', 'interactOn', 'interactOff']" :key="type" :label="type" :value="type")
|
||||
el-input(v-model="playerModerationTable.filters[1].value" :placeholder="$t('view.moderation.search_placeholder')" style="flex:none;width:150px;margin:0 10px")
|
||||
el-tooltip(placement="bottom" :content="$t('view.moderation.refresh_tooltip')" :disabled="hideTooltips")
|
||||
el-button(type="default" :loading="API.isPlayerModerationsLoading" @click="API.refreshPlayerModerations()" icon="el-icon-refresh" circle style="flex:none")
|
||||
el-table-column(:label="$t('table.moderation.date')" prop="created" sortable="custom" width="120")
|
||||
template(v-once #default="scope")
|
||||
el-tooltip(placement="right")
|
||||
template(#content)
|
||||
span {{ scope.row.created | formatDate('long') }}
|
||||
span {{ scope.row.created | formatDate('short') }}
|
||||
el-table-column(:label="$t('table.moderation.type')" prop="type" width="100")
|
||||
el-table-column(:label="$t('table.moderation.source')" prop="sourceDisplayName")
|
||||
template(v-once #default="scope")
|
||||
span.x-link(v-text="scope.row.sourceDisplayName" @click="showUserDialog(scope.row.sourceUserId)")
|
||||
el-table-column(:label="$t('table.moderation.target')" prop="targetDisplayName")
|
||||
template(v-once #default="scope")
|
||||
span.x-link(v-text="scope.row.targetDisplayName" @click="showUserDialog(scope.row.targetUserId)")
|
||||
el-table-column(:label="$t('table.moderation.action')" width="80" align="right")
|
||||
template(v-once #default="scope")
|
||||
el-button(v-if="scope.row.sourceUserId === API.currentUser.id" type="text" icon="el-icon-close" size="mini" @click="deletePlayerModeration(scope.row)")
|
||||
89
html/src/mixins/tabs/notifications.pug
Normal file
89
html/src/mixins/tabs/notifications.pug
Normal file
@@ -0,0 +1,89 @@
|
||||
mixin notificationsTab()
|
||||
.x-container(v-show="$refs.menu && $refs.menu.activeIndex === 'notification'" v-if="$refs.menu && $refs.menu.activeIndex === 'notification'" v-loading="API.isNotificationsLoading")
|
||||
data-tables(v-bind="notificationTable")
|
||||
template(#tool)
|
||||
div(style="margin:0 0 10px;display:flex;align-items:center")
|
||||
el-select(v-model="notificationTable.filters[0].value" @change="saveTableFilters" multiple clearable collapse-tags style="flex:1" :placeholder="$t('view.notification.filter_placeholder')")
|
||||
el-option(v-once v-for="type in ['requestInvite', 'invite', 'requestInviteResponse', 'inviteResponse', 'friendRequest', 'hiddenFriendRequest', 'message', 'group.announcement', 'group.informative', 'group.invite', 'group.joinRequest', 'moderation.warning.group']" :key="type" :label="type" :value="type")
|
||||
el-input(v-model="notificationTable.filters[1].value" :placeholder="$t('view.notification.search_placeholder')" style="flex:none;width:150px;margin:0 10px")
|
||||
el-tooltip(placement="bottom" :content="$t('view.notification.refresh_tooltip')" :disabled="hideTooltips")
|
||||
el-button(type="default" :loading="API.isNotificationsLoading" @click="API.refreshNotifications()" icon="el-icon-refresh" circle style="flex:none")
|
||||
el-table-column(:label="$t('table.notification.date')" prop="created_at" sortable="custom" width="120")
|
||||
template(v-once #default="scope")
|
||||
el-tooltip(placement="right")
|
||||
template(#content)
|
||||
span {{ scope.row.created_at | formatDate('long') }}
|
||||
span {{ scope.row.created_at | formatDate('short') }}
|
||||
el-table-column(:label="$t('table.notification.type')" prop="type" width="160")
|
||||
template(v-once #default="scope")
|
||||
el-tooltip(v-if="scope.row.type === 'invite'" placement="top")
|
||||
template(#content)
|
||||
location(v-if="scope.row.details" :location="scope.row.details.worldId" :hint="scope.row.details.worldName" :grouphint="scope.row.details.groupName" :link="false")
|
||||
span.x-link(v-text="scope.row.type" @click="showWorldDialog(scope.row.details.worldId)")
|
||||
template(v-else-if="scope.row.link")
|
||||
el-tooltip(placement="top" :content="scope.row.linkText" :disabled="hideTooltips")
|
||||
span.x-link(v-text="scope.row.type" @click="openNotificationLink(scope.row.link)")
|
||||
span(v-else v-text="scope.row.type")
|
||||
el-table-column(:label="$t('table.notification.user')" prop="senderUsername" width="150")
|
||||
template(v-once #default="scope")
|
||||
span.x-link(v-text="scope.row.senderUsername" @click="showUserDialog(scope.row.senderUserId)")
|
||||
el-table-column(:label="$t('table.notification.photo')" width="100" prop="photo")
|
||||
template(v-once #default="scope")
|
||||
template(v-if="scope.row.details && scope.row.details.imageUrl")
|
||||
el-popover(placement="right" width="500px" trigger="click")
|
||||
img.x-link(slot="reference" v-lazy="scope.row.details.imageUrl" style="flex:none;height:50px;border-radius:4px")
|
||||
img.x-link(v-lazy="scope.row.details.imageUrl" style="width:500px" @click="downloadAndSaveImage(scope.row.details.imageUrl)")
|
||||
template(v-else-if="scope.row.imageUrl")
|
||||
el-popover(placement="right" width="500px" trigger="click")
|
||||
img.x-link(slot="reference" v-lazy="scope.row.imageUrl" style="flex:none;height:50px;border-radius:4px")
|
||||
img.x-link(v-lazy="scope.row.imageUrl" style="width:500px" @click="downloadAndSaveImage(scope.row.imageUrl)")
|
||||
el-table-column(:label="$t('table.notification.message')" prop="message")
|
||||
template(v-once #default="scope")
|
||||
span(v-if="scope.row.title") {{ scope.row.title }}, {{ scope.row.message }}
|
||||
span(v-else-if="scope.row.message" v-text="scope.row.message")
|
||||
span(v-else-if='scope.row.details && scope.row.details.inviteMessage' v-text="scope.row.details.inviteMessage")
|
||||
span(v-else-if='scope.row.details && scope.row.details.requestMessage' v-text="scope.row.details.requestMessage")
|
||||
span(v-else-if='scope.row.details && scope.row.details.responseMessage' v-text="scope.row.details.responseMessage")
|
||||
el-table-column(:label="$t('table.notification.action')" width="100" align="right")
|
||||
template(v-once #default="scope")
|
||||
template(v-if="scope.row.senderUserId !== API.currentUser.id && !scope.row.$isExpired")
|
||||
template(v-if="scope.row.type === 'friendRequest'")
|
||||
el-tooltip(placement="top" content="Accept" :disabled="hideTooltips")
|
||||
el-button(type="text" icon="el-icon-check" size="mini" @click="acceptNotification(scope.row)")
|
||||
template(v-else-if="scope.row.type === 'invite'")
|
||||
el-tooltip(placement="top" content="Decline with message" :disabled="hideTooltips")
|
||||
el-button(type="text" icon="el-icon-chat-line-square" size="mini" @click="showSendInviteResponseDialog(scope.row)")
|
||||
template(v-else-if="scope.row.type === 'requestInvite'")
|
||||
template(v-if="lastLocation.location && isGameRunning && checkCanInvite(lastLocation.location)")
|
||||
el-tooltip(placement="top" content="Invite" :disabled="hideTooltips")
|
||||
el-button(type="text" icon="el-icon-check" size="mini" @click="acceptRequestInvite(scope.row)")
|
||||
el-tooltip(placement="top" content="Decline with message" :disabled="hideTooltips")
|
||||
el-button(type="text" icon="el-icon-chat-line-square" size="mini" style="margin-left:5px" @click="showSendInviteRequestResponseDialog(scope.row)")
|
||||
template(v-else-if="scope.row.type === 'group.invite'")
|
||||
el-tooltip(placement="top" content="Accept" :disabled="hideTooltips")
|
||||
el-button(type="text" icon="el-icon-check" size="mini" style="margin-left:5px" @click="sendNotificationResponse(scope.row.id, scope.row.responses, 'accept')")
|
||||
el-tooltip(placement="top" content="Decline" :disabled="hideTooltips")
|
||||
el-button(type="text" icon="el-icon-close" size="mini" style="margin-left:5px" @click="sendNotificationResponse(scope.row.id, scope.row.responses, 'decline')")
|
||||
el-tooltip(placement="top" content="Block invites from group" :disabled="hideTooltips")
|
||||
el-button(type="text" icon="el-icon-circle-close" size="mini" style="margin-left:5px" @click="sendNotificationResponse(scope.row.id, scope.row.responses, 'block')")
|
||||
template(v-else-if="scope.row.type === 'group.joinRequest'")
|
||||
el-tooltip(placement="top" content="Accept" :disabled="hideTooltips")
|
||||
el-button(type="text" icon="el-icon-check" size="mini" style="margin-left:5px" @click="sendNotificationResponse(scope.row.id, scope.row.responses, 'accept')")
|
||||
el-tooltip(placement="top" content="Decline" :disabled="hideTooltips")
|
||||
el-button(type="text" icon="el-icon-close" size="mini" style="margin-left:5px" @click="sendNotificationResponse(scope.row.id, scope.row.responses, 'reject')")
|
||||
el-tooltip(placement="top" content="Block user from requesting" :disabled="hideTooltips")
|
||||
el-button(type="text" icon="el-icon-circle-close" size="mini" style="margin-left:5px" @click="sendNotificationResponse(scope.row.id, scope.row.responses, 'block')")
|
||||
template(v-else-if="scope.row.type === 'group.announcement'")
|
||||
el-tooltip(placement="top" content="Dismiss" :disabled="hideTooltips")
|
||||
el-button(type="text" icon="el-icon-check" size="mini" style="margin-left:5px" @click="sendNotificationResponse(scope.row.id, scope.row.responses, 'delete')")
|
||||
el-tooltip(placement="top" content="Unsubscribe" :disabled="hideTooltips")
|
||||
el-button(type="text" icon="el-icon-close" size="mini" style="margin-left:5px" @click="sendNotificationResponse(scope.row.id, scope.row.responses, 'unsubscribe')")
|
||||
template(v-else-if="scope.row.type === 'group.informative'")
|
||||
el-tooltip(placement="top" content="Dismiss" :disabled="hideTooltips")
|
||||
el-button(type="text" icon="el-icon-check" size="mini" style="margin-left:5px" @click="sendNotificationResponse(scope.row.id, scope.row.responses, 'delete')")
|
||||
template(v-if="scope.row.type !== 'requestInviteResponse' && scope.row.type !== 'inviteResponse' && scope.row.type !== 'message' && !scope.row.type.includes('group.') && !scope.row.type.includes('moderation.')")
|
||||
el-tooltip(placement="top" content="Decline" :disabled="hideTooltips")
|
||||
el-button(type="text" icon="el-icon-close" size="mini" style="margin-left:5px" @click="hideNotification(scope.row)")
|
||||
template(v-if="scope.row.type !== 'friendRequest' && scope.row.type !== 'hiddenFriendRequest' && !scope.row.type.includes('group.') && !scope.row.type.includes('moderation.')")
|
||||
el-tooltip(placement="top" content="Delete log" :disabled="hideTooltips")
|
||||
el-button(type="text" icon="el-icon-delete" size="mini" style="margin-left:5px" @click="deleteNotificationLog(scope.row)")
|
||||
249
html/src/mixins/tabs/playerList.pug
Normal file
249
html/src/mixins/tabs/playerList.pug
Normal file
@@ -0,0 +1,249 @@
|
||||
mixin playerListTab()
|
||||
.x-container(v-show="$refs.menu && $refs.menu.activeIndex === 'playerList'")
|
||||
div(style="display:flex;flex-direction:column;height:100%")
|
||||
div(v-if="currentInstanceWorld.ref.id" style="display:flex")
|
||||
el-popover(placement="right" width="500px" trigger="click" style="height:120px")
|
||||
img.x-link(slot="reference" v-lazy="currentInstanceWorld.ref.thumbnailImageUrl" style="flex:none;width:160px;height:120px;border-radius:4px")
|
||||
img.x-link(v-lazy="currentInstanceWorld.ref.imageUrl" style="width:500px;height:375px" @click="downloadAndSaveImage(currentInstanceWorld.ref.imageUrl)")
|
||||
div(style="margin-left:10px;display:flex;flex-direction:column;min-width:320px;width:100%")
|
||||
div
|
||||
span.x-link(@click="showWorldDialog(currentInstanceWorld.ref.id)" style="font-weight:bold;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1")
|
||||
| #[i.el-icon-s-home(v-show="API.currentUser.$homeLocation && API.currentUser.$homeLocation.worldId === currentInstanceWorld.ref.id" style="margin-right:5px")] {{ currentInstanceWorld.ref.name }}
|
||||
div
|
||||
span.x-link(v-text="currentInstanceWorld.ref.authorName" @click="showUserDialog(currentInstanceWorld.ref.authorId)" style="color:#909399;font-family:monospace")
|
||||
div(style="margin-top:5px")
|
||||
el-tag(v-if="currentInstanceWorld.ref.$isLabs" type="primary" effect="plain" size="mini" style="margin-right:5px") {{ $t('dialog.world.tags.labs') }}
|
||||
el-tag(v-else-if="currentInstanceWorld.ref.releaseStatus === 'public'" type="success" effect="plain" size="mini" style="margin-right:5px") {{ $t('dialog.world.tags.public') }}
|
||||
el-tag(v-else-if="currentInstanceWorld.ref.releaseStatus === 'private'" type="danger" effect="plain" size="mini" style="margin-right:5px") {{ $t('dialog.world.tags.private') }}
|
||||
el-tag.x-tag-platform-pc(v-if="currentInstanceWorld.isPC" type="info" effect="plain" size="mini" style="margin-right:5px") PC
|
||||
el-tag.x-tag-platform-quest(v-if="currentInstanceWorld.isQuest" type="info" effect="plain" size="mini" style="margin-right:5px") Quest
|
||||
el-tag(type="info" effect="plain" size="mini" v-text="currentInstanceWorld.fileSize" style="margin-right:5px")
|
||||
el-tag(v-if="currentInstanceWorld.inCache" type="info" effect="plain" size="mini" style="margin-right:5px")
|
||||
span(v-text="currentInstanceWorld.cacheSize")
|
||||
| {{ $t('dialog.world.tags.cache') }}
|
||||
br
|
||||
location-world(:locationobject="currentInstanceLocation" :currentuserid="API.currentUser.id")
|
||||
span(v-if="lastLocation.playerList.size > 0" style="margin-left:5px")
|
||||
| {{ lastLocation.playerList.size }}
|
||||
| #[template(v-if="lastLocation.friendList.size > 0") ({{ lastLocation.friendList.size }})]
|
||||
| #[timer(v-if="lastLocation.date" :epoch="lastLocation.date")]
|
||||
div(style="margin-top:5px")
|
||||
span(v-show="currentInstanceWorld.ref.name !== currentInstanceWorld.ref.description" v-text="currentInstanceWorld.ref.description" style="font-size:12px;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2")
|
||||
div(style="display:flex;flex-direction:column;margin-left:20px")
|
||||
.x-friend-item(style="cursor:default")
|
||||
.detail
|
||||
span.name {{ $t('dialog.world.info.capacity') }}
|
||||
span.extra {{ currentInstanceWorld.ref.capacity | commaNumber }} ({{ currentInstanceWorld.ref.capacity * 2 | commaNumber }})
|
||||
.x-friend-item(style="cursor:default")
|
||||
.detail
|
||||
span.name {{ $t('dialog.world.info.last_updated') }}
|
||||
span.extra {{ currentInstanceWorld.fileCreatedAt | formatDate('long') }}
|
||||
.x-friend-item(style="cursor:default")
|
||||
.detail
|
||||
span.name {{ $t('dialog.world.info.created_at') }}
|
||||
span.extra {{ currentInstanceWorld.ref.created_at | formatDate('long') }}
|
||||
div.photon-event-table(v-if="photonLoggingEnabled")
|
||||
div(style="position:absolute;width:600px;margin-left:195px;z-index:1")
|
||||
el-select(v-model="photonEventTableTypeFilter" @change="photonEventTableFilterChange" multiple clearable collapse-tags style="flex:1;width:220px" :placeholder="$t('view.player_list.photon.filter_placeholder')")
|
||||
el-option(v-once v-for="type in photonEventTableTypeFilterList" :key="type" :label="type" :value="type")
|
||||
el-input(v-model="photonEventTableFilter" @input="photonEventTableFilterChange" :placeholder="$t('view.player_list.photon.search_placeholder')" clearable style="width:150px;margin-left:10px")
|
||||
el-button(@click="showChatboxBlacklistDialog" style="margin-left:10px") {{ $t('view.player_list.photon.chatbox_blacklist') }}
|
||||
el-tooltip(placement="bottom" :content="$t('view.player_list.photon.status_tooltip')" :disabled="hideTooltips")
|
||||
div(style="display:inline-block;margin-left:15px;font-size:14px;vertical-align:text-top;margin-top:1px")
|
||||
span(v-if="ipcEnabled && !photonEventIcon") 🟢
|
||||
span(v-else-if="ipcEnabled") ⚪
|
||||
span(v-else) 🔴
|
||||
el-tabs(type="card")
|
||||
el-tab-pane(:label="$t('view.player_list.photon.current')")
|
||||
data-tables(v-bind="photonEventTable" style="margin-bottom:10px")
|
||||
el-table-column(:label="$t('table.playerList.date')" prop="created_at" width="120")
|
||||
template(v-once #default="scope")
|
||||
el-tooltip(placement="right")
|
||||
template(#content)
|
||||
span {{ scope.row.created_at | formatDate('long') }}
|
||||
span {{ scope.row.created_at | formatDate('short') }}
|
||||
el-table-column(:label="$t('table.playerList.user')" prop="photonId" width="160")
|
||||
template(v-once #default="scope")
|
||||
span.x-link(v-text="scope.row.displayName" @click="showUserFromPhotonId(scope.row.photonId)" style="padding-right:10px")
|
||||
el-table-column(:label="$t('table.playerList.type')" prop="type" width="140")
|
||||
el-table-column(:label="$t('table.playerList.detail')" prop="text")
|
||||
template(v-once #default="scope")
|
||||
template(v-if="scope.row.type === 'ChangeAvatar'")
|
||||
span.x-link(v-text="scope.row.avatar.name" @click="showAvatarDialog(scope.row.avatar.id)")
|
||||
|
|
||||
span(v-if="!scope.row.inCache" style="color:#aaa") #[i.el-icon-download]
|
||||
span.avatar-info-public(v-if="scope.row.avatar.releaseStatus === 'public'") {{ $t('dialog.avatar.labels.public') }}
|
||||
span.avatar-info-own(v-else-if="scope.row.avatar.releaseStatus === 'private'") {{ $t('dialog.avatar.labels.private') }}
|
||||
template(v-if="scope.row.avatar.description && scope.row.avatar.name !== scope.row.avatar.description")
|
||||
| - {{ scope.row.avatar.description }}
|
||||
template(v-else-if="scope.row.type === 'ChangeStatus'")
|
||||
template(v-if="scope.row.status !== scope.row.previousStatus")
|
||||
el-tooltip(placement="top")
|
||||
template(#content)
|
||||
span(v-if="scope.row.previousStatus === 'active'") {{ $t('dialog.user.status.active') }}
|
||||
span(v-else-if="scope.row.previousStatus === 'join me'") {{ $t('dialog.user.status.join_me') }}
|
||||
span(v-else-if="scope.row.previousStatus === 'ask me'") {{ $t('dialog.user.status.ask_me') }}
|
||||
span(v-else-if="scope.row.previousStatus === 'busy'") {{ $t('dialog.user.status.busy') }}
|
||||
span(v-else) {{ $t('dialog.user.status.offline') }}
|
||||
i.x-user-status(:class="statusClass(scope.row.previousStatus)")
|
||||
span
|
||||
i.el-icon-right
|
||||
el-tooltip(placement="top")
|
||||
template(#content)
|
||||
span(v-if="scope.row.status === 'active'") Active
|
||||
span(v-else-if="scope.row.status === 'join me'") Join Me
|
||||
span(v-else-if="scope.row.status === 'ask me'") Ask Me
|
||||
span(v-else-if="scope.row.status === 'busy'") Do Not Disturb
|
||||
span(v-else) Offline
|
||||
i.x-user-status(:class="statusClass(scope.row.status)" style="margin-right:5px")
|
||||
span(v-if="scope.row.statusDescription !== scope.row.previousStatusDescription" v-text="scope.row.statusDescription")
|
||||
template(v-else-if="scope.row.type === 'ChangeGroup'")
|
||||
span.x-link(v-if="scope.row.previousGroupName" v-text="scope.row.previousGroupName" @click="showGroupDialog(scope.row.previousGroupId)" style="margin-right:5px")
|
||||
span.x-link(v-else v-text="scope.row.previousGroupId" @click="showGroupDialog(scope.row.previousGroupId)" style="margin-right:5px")
|
||||
span
|
||||
i.el-icon-right
|
||||
span.x-link(v-if="scope.row.groupName" v-text="scope.row.groupName" @click="showGroupDialog(scope.row.groupId)" style="margin-left:5px")
|
||||
span.x-link(v-else v-text="scope.row.groupId" @click="showGroupDialog(scope.row.groupId)" style="margin-left:5px")
|
||||
span.x-link(v-else-if="scope.row.type === 'PortalSpawn'" @click="showWorldDialog(scope.row.location, scope.row.shortName)")
|
||||
location(:location="scope.row.location" :hint="scope.row.worldName" :grouphint="scope.row.groupName" :link="false")
|
||||
span(v-else-if="scope.row.type === 'ChatBoxMessage'" v-text="scope.row.text")
|
||||
span(v-else-if="scope.row.type === 'OnPlayerJoined'")
|
||||
span(v-if="scope.row.platform === 'Desktop'" style="color:#409eff") Desktop
|
||||
span(v-else-if="scope.row.platform === 'VR'" style="color:#409eff") VR
|
||||
span(v-else-if="scope.row.platform === 'Quest'" style="color:#67c23a") Quest
|
||||
span.x-link(v-text="scope.row.avatar.name" @click="showAvatarDialog(scope.row.avatar.id)")
|
||||
|
|
||||
span(v-if="!scope.row.inCache" style="color:#aaa") #[i.el-icon-download]
|
||||
span.avatar-info-public(v-if="scope.row.avatar.releaseStatus === 'public'") {{ $t('dialog.avatar.labels.public') }}
|
||||
span.avatar-info-own(v-else-if="scope.row.avatar.releaseStatus === 'private'") {{ $t('dialog.avatar.labels.private') }}
|
||||
span(v-else-if="scope.row.color === 'yellow'" v-text="scope.row.text" style="color:yellow")
|
||||
span(v-else v-text="scope.row.text")
|
||||
el-tab-pane(:label="$t('view.player_list.photon.previous')")
|
||||
data-tables(v-bind="photonEventTablePrevious" style="margin-bottom:10px")
|
||||
el-table-column(:label="$t('table.playerList.date')" prop="created_at" width="120")
|
||||
template(v-once #default="scope")
|
||||
el-tooltip(placement="right")
|
||||
template(#content)
|
||||
span {{ scope.row.created_at | formatDate('long') }}
|
||||
span {{ scope.row.created_at | formatDate('short') }}
|
||||
el-table-column(:label="$t('table.playerList.user')" prop="photonId" width="160")
|
||||
template(v-once #default="scope")
|
||||
span.x-link(v-text="scope.row.displayName" @click="lookupUser(scope.row)" style="padding-right:10px")
|
||||
el-table-column(:label="$t('table.playerList.type')" prop="type" width="140")
|
||||
el-table-column(:label="$t('table.playerList.detail')" prop="text")
|
||||
template(v-once #default="scope")
|
||||
template(v-if="scope.row.type === 'ChangeAvatar'")
|
||||
span.x-link(v-text="scope.row.avatar.name" @click="showAvatarDialog(scope.row.avatar.id)")
|
||||
|
|
||||
span(v-if="!scope.row.inCache" style="color:#aaa") #[i.el-icon-download]
|
||||
span.avatar-info-public(v-if="scope.row.avatar.releaseStatus === 'public'") (Public)
|
||||
span.avatar-info-own(v-else-if="scope.row.avatar.releaseStatus === 'private'") (Private)
|
||||
template(v-if="scope.row.avatar.description && scope.row.avatar.name !== scope.row.avatar.description")
|
||||
| - {{ scope.row.avatar.description }}
|
||||
template(v-else-if="scope.row.type === 'ChangeStatus'")
|
||||
template(v-if="scope.row.status !== scope.row.previousStatus")
|
||||
el-tooltip(placement="top")
|
||||
template(#content)
|
||||
span(v-if="scope.row.previousStatus === 'active'") {{ $t('dialog.user.status.active') }}
|
||||
span(v-else-if="scope.row.previousStatus === 'join me'") {{ $t('dialog.user.status.join_me') }}
|
||||
span(v-else-if="scope.row.previousStatus === 'ask me'") {{ $t('dialog.user.status.ask_me') }}
|
||||
span(v-else-if="scope.row.previousStatus === 'busy'") {{ $t('dialog.user.status.busy') }}
|
||||
span(v-else) {{ $t('dialog.user.status.offline') }}
|
||||
i.x-user-status(:class="statusClass(scope.row.previousStatus)")
|
||||
span
|
||||
i.el-icon-right
|
||||
el-tooltip(placement="top")
|
||||
template(#content)
|
||||
span(v-if="scope.row.status === 'active'") {{ $t('dialog.user.status.active') }}
|
||||
span(v-else-if="scope.row.status === 'join me'") {{ $t('dialog.user.status.join_me') }}
|
||||
span(v-else-if="scope.row.status === 'ask me'") {{ $t('dialog.user.status.ask_me') }}
|
||||
span(v-else-if="scope.row.status === 'busy'") {{ $t('dialog.user.status.busy') }}
|
||||
span(v-else) {{ $t('dialog.user.status.offline') }}
|
||||
i.x-user-status(:class="statusClass(scope.row.status)")
|
||||
span(v-if="scope.row.statusDescription !== scope.row.previousStatusDescription" v-text="scope.row.statusDescription" style="margin-left:5px")
|
||||
template(v-else-if="scope.row.type === 'ChangeGroup'")
|
||||
span.x-link(v-if="scope.row.previousGroupName" v-text="scope.row.previousGroupName" @click="showGroupDialog(scope.row.previousGroupId)" style="margin-right:5px")
|
||||
span.x-link(v-else v-text="scope.row.previousGroupId" @click="showGroupDialog(scope.row.previousGroupId)" style="margin-right:5px")
|
||||
span
|
||||
i.el-icon-right
|
||||
span.x-link(v-if="scope.row.groupName" v-text="scope.row.groupName" @click="showGroupDialog(scope.row.groupId)" style="margin-left:5px")
|
||||
span.x-link(v-else v-text="scope.row.groupId" @click="showGroupDialog(scope.row.groupId)" style="margin-left:5px")
|
||||
span.x-link(v-else-if="scope.row.type === 'PortalSpawn'" @click="showWorldDialog(scope.row.location, scope.row.shortName)")
|
||||
location(:location="scope.row.location" :hint="scope.row.worldName" :grouphint="scope.row.groupName" :link="false")
|
||||
span(v-else-if="scope.row.type === 'ChatBoxMessage'" v-text="scope.row.text")
|
||||
span(v-else-if="scope.row.type === 'OnPlayerJoined'")
|
||||
span(v-if="scope.row.platform === 'Desktop'" style="color:#409eff") Desktop
|
||||
span(v-else-if="scope.row.platform === 'VR'" style="color:#409eff") VR
|
||||
span(v-else-if="scope.row.platform === 'Quest'" style="color:#67c23a") Quest
|
||||
span.x-link(v-text="scope.row.avatar.name" @click="showAvatarDialog(scope.row.avatar.id)")
|
||||
|
|
||||
span(v-if="!scope.row.inCache" style="color:#aaa") #[i.el-icon-download]
|
||||
span.avatar-info-public(v-if="scope.row.avatar.releaseStatus === 'public'") (Public)
|
||||
span.avatar-info-own(v-else-if="scope.row.avatar.releaseStatus === 'private'") (Private)
|
||||
span(v-else-if="scope.row.color === 'yellow'" v-text="scope.row.text" style="color:yellow")
|
||||
span(v-else v-text="scope.row.text")
|
||||
div.current-instance-table
|
||||
data-tables(v-bind="currentInstanceUserList" @row-click="selectCurrentInstanceRow" style="margin-top:10px;cursor:pointer")
|
||||
el-table-column(:label="$t('table.playerList.avatar')" width="70" prop="photo")
|
||||
template(v-once #default="scope")
|
||||
template(v-if="userImage(scope.row.ref)")
|
||||
el-popover(placement="right" height="500px" trigger="hover")
|
||||
img.friends-list-avatar(slot="reference" v-lazy="userImage(scope.row.ref)")
|
||||
img.friends-list-avatar(v-lazy="userImageFull(scope.row.ref)" style="height:500px;cursor:pointer" @click="downloadAndSaveImage(userImageFull(scope.row.ref))")
|
||||
el-table-column(:label="$t('table.playerList.timer')" width="90" prop="timer" sortable)
|
||||
template(v-once #default="scope")
|
||||
timer(:epoch="scope.row.timer")
|
||||
el-table-column(v-if="photonLoggingEnabled" :label="$t('table.playerList.photonId')" width="110" prop="photonId" sortable)
|
||||
template(v-once #default="scope")
|
||||
template(v-if="chatboxUserBlacklist.has(scope.row.ref.id)")
|
||||
el-tooltip(placement="left" content="Unblock chatbox messages")
|
||||
el-button(type="text" icon="el-icon-turn-off-microphone" size="mini" style="color:red;margin-right:5px" @click.stop="deleteChatboxUserBlacklist(scope.row.ref.id)")
|
||||
template(v-else)
|
||||
el-tooltip(placement="left" content="Block chatbox messages")
|
||||
el-button(type="text" icon="el-icon-microphone" size="mini" style="margin-right:5px" @click.stop="addChatboxUserBlacklist(scope.row.ref)")
|
||||
span(v-text="scope.row.photonId")
|
||||
el-table-column(:label="$t('table.playerList.icon')" prop="isMaster" width="100")
|
||||
template(v-once #default="scope")
|
||||
el-tooltip(v-if="scope.row.isMaster" placement="left" content="Instance Master")
|
||||
span 👑
|
||||
el-tooltip(v-if="scope.row.isFriend" placement="left" content="Friend")
|
||||
span 💚
|
||||
el-tooltip(v-if="scope.row.timeoutTime" placement="left" content="Timeout")
|
||||
span(style="color:red") 🔴{{ scope.row.timeoutTime }}s
|
||||
el-table-column(:label="$t('table.playerList.platform')" prop="inVRMode" width="80")
|
||||
template(v-once #default="scope")
|
||||
template(v-if="scope.row.ref.last_platform")
|
||||
span(v-if="scope.row.ref.last_platform === 'standalonewindows'" style="color:#409eff") PC
|
||||
span(v-else-if="scope.row.ref.last_platform === 'android'" style="color:#67c23a") Q
|
||||
span(v-else) {{ scope.row.ref.last_platform }}
|
||||
template(v-if="scope.row.inVRMode !== null")
|
||||
span(v-if="scope.row.inVRMode") VR
|
||||
span(v-else) D
|
||||
el-table-column(:label="$t('table.playerList.displayName')" min-width="140" prop="ref.displayName")
|
||||
template(v-once #default="scope")
|
||||
span(v-if="randomUserColours" v-text="scope.row.ref.displayName" :style="{'color':scope.row.ref.$userColour}")
|
||||
span(v-else v-text="scope.row.ref.displayName")
|
||||
el-table-column(:label="$t('table.playerList.status')" min-width="180" prop="ref.status")
|
||||
template(v-once #default="scope")
|
||||
template(v-if="scope.row.ref.status")
|
||||
i.x-user-status(:class="statusClass(scope.row.ref.status)")
|
||||
span
|
||||
span(v-text="scope.row.ref.statusDescription")
|
||||
//- el-table-column(label="Group" min-width="180" prop="groupOnNameplate" sortable)
|
||||
//- template(v-once #default="scope")
|
||||
//- span(v-text="scope.row.groupOnNameplate")
|
||||
el-table-column(:label="$t('table.playerList.rank')" width="110" prop="$trustSortNum" sortable="custom")
|
||||
template(v-once #default="scope")
|
||||
span.name(v-text="scope.row.ref.$trustLevel" :class="scope.row.ref.$trustClass")
|
||||
el-table-column(:label="$t('table.playerList.language')" width="100" prop="ref.$languages")
|
||||
template(v-once #default="scope")
|
||||
el-tooltip(v-for="item in scope.row.ref.$languages" :key="item.key" placement="top")
|
||||
template(#content)
|
||||
span {{ item.value }} ({{ item.key }})
|
||||
span.flags(:class="languageClass(item.key)" style="display:inline-block;margin-left:5px")
|
||||
el-table-column(:label="$t('table.playerList.bioLink')" width="100" prop="ref.bioLinks")
|
||||
template(v-once #default="scope")
|
||||
el-tooltip(v-if="link" v-for="(link, index) in scope.row.ref.bioLinks" :key="index")
|
||||
template(#content)
|
||||
span(v-text="link")
|
||||
img(:src="getFaviconUrl(link)" style="width:16px;height:16px;vertical-align:middle;margin-right:5px;cursor:pointer" @click.stop="openExternalLink(link)")
|
||||
150
html/src/mixins/tabs/profile.pug
Normal file
150
html/src/mixins/tabs/profile.pug
Normal file
@@ -0,0 +1,150 @@
|
||||
mixin profileTab()
|
||||
.x-container(v-show="$refs.menu && $refs.menu.activeIndex === 'profile'" v-if="$refs.menu && $refs.menu.activeIndex === 'profile'")
|
||||
div.options-container(style="margin-top:0")
|
||||
span.header {{ $t('view.profile.profile.header') }}
|
||||
.x-friend-list(style="margin-top:10px")
|
||||
.x-friend-item(@click="showUserDialog(API.currentUser.id)")
|
||||
.avatar
|
||||
img(v-lazy="userImage(API.currentUser)")
|
||||
.detail
|
||||
span.name(v-text="API.currentUser.displayName")
|
||||
span.extra(v-text="API.currentUser.username")
|
||||
.x-friend-item(style="cursor:default")
|
||||
.detail
|
||||
span.name {{ $t('view.profile.profile.last_activity') }}
|
||||
span.extra {{ API.currentUser.last_activity | formatDate('long') }}
|
||||
.x-friend-item(style="cursor:default")
|
||||
.detail
|
||||
span.name {{ $t('view.profile.profile.two_factor') }}
|
||||
span.extra {{ API.currentUser.twoFactorAuthEnabled ? $t('view.profile.profile.two_factor_enabled') : $t('view.profile.profile.two_factor_disabled') }}
|
||||
div
|
||||
el-button(size="small" icon="el-icon-switch-button" @click="logout()" style="margin-left:0;margin-right:5px;margin-top:10px") {{ $t('view.profile.profile.logout') }}
|
||||
el-button(size="small" icon="el-icon-printer" @click="showExportFriendsListDialog()" style="margin-left:0;margin-right:5px;margin-top:10px") {{ $t('view.profile.profile.export_friend_list') }}
|
||||
el-button(size="small" icon="el-icon-user" @click="showExportAvatarsListDialog()" style="margin-left:0;margin-right:5px;margin-top:10px") {{ $t('view.profile.profile.export_own_avatars') }}
|
||||
el-button(size="small" icon="el-icon-chat-dot-round" @click="showDiscordNamesDialog()" style="margin-left:0;margin-right:5px;margin-top:10px") {{ $t('view.profile.profile.discord_names') }}
|
||||
el-button(size="small" icon="el-icon-document-copy" @click="showNoteExportDialog()" style="margin-left:0;margin-right:5px;margin-top:10px") {{ $t('view.profile.profile.export_notes') }}
|
||||
div.options-container
|
||||
span.header {{ $t('view.profile.game_info.header') }}
|
||||
.x-friend-list(style="margin-top:10px")
|
||||
.x-friend-item
|
||||
.detail(@click="API.getVisits()")
|
||||
span.name {{ $t('view.profile.game_info.online_users') }}
|
||||
span.extra(v-if="visits") {{ $t('view.profile.game_info.user_online', { count: visits }) }}
|
||||
span.extra(v-else) {{ $t('view.profile.game_info.refresh') }}
|
||||
div.options-container
|
||||
span.header {{ $t('view.profile.vrc_sdk_downloads.header') }}
|
||||
el-tooltip(placement="top" :content="$t('view.profile.refresh_tooltip')" :disabled="hideTooltips")
|
||||
el-button(type="default" @click="API.getConfig()" size="mini" icon="el-icon-refresh" circle style="margin-left:5px")
|
||||
.x-friend-list(style="margin-top:10px")
|
||||
.x-friend-item(v-for="(link, item) in API.cachedConfig.downloadUrls" :key="item" placement="top")
|
||||
.detail(@click="openExternalLink(link)")
|
||||
span.name(v-text="item")
|
||||
span.extra(v-text="link")
|
||||
div.options-container
|
||||
span.header {{ $t('view.profile.direct_access.header') }}
|
||||
div(style="margin-top:10px")
|
||||
el-button-group
|
||||
el-button(size="small" @click="promptUsernameDialog()") {{ $t('view.profile.direct_access.username') }}
|
||||
el-button(size="small" @click="promptUserIdDialog()") {{ $t('view.profile.direct_access.user_id') }}
|
||||
el-button(size="small" @click="promptWorldDialog()") {{ $t('view.profile.direct_access.world_instance') }}
|
||||
el-button(size="small" @click="promptAvatarDialog()") {{ $t('view.profile.direct_access.avatar') }}
|
||||
div.options-container
|
||||
span.header {{ $t('view.profile.invite_messages') }}
|
||||
el-tooltip(placement="top" :content="$t('view.profile.refresh_tooltip')" :disabled="hideTooltips")
|
||||
el-button(type="default" @click="inviteMessageTable.visible = true; refreshInviteMessageTable('message')" size="mini" icon="el-icon-refresh" circle style="margin-left:5px")
|
||||
el-tooltip(placement="top" :content="$t('view.profile.clear_results_tooltip')" :disabled="hideTooltips")
|
||||
el-button(type="default" @click="inviteMessageTable.visible = false" size="mini" icon="el-icon-delete" circle style="margin-left:5px")
|
||||
data-tables(v-if="inviteMessageTable.visible" v-bind="inviteMessageTable" style="margin-top:10px")
|
||||
el-table-column(label="Slot" prop="slot" sortable="custom" width="70")
|
||||
el-table-column(label="Message" prop="message")
|
||||
el-table-column(label="Cool Down" prop="updatedAt" sortable="custom" width="110" align="right")
|
||||
template(v-once #default="scope")
|
||||
countdown-timer(:datetime="scope.row.updatedAt" :hours="1")
|
||||
el-table-column(label="Action" width="60" align="right")
|
||||
template(v-once #default="scope")
|
||||
el-button(type="text" icon="el-icon-edit" size="mini" @click="showEditInviteMessageDialog('message', scope.row)")
|
||||
div.options-container
|
||||
span.header {{ $t('view.profile.invite_response_messages') }}
|
||||
el-tooltip(placement="top" :content="$t('view.profile.refresh_tooltip')" :disabled="hideTooltips")
|
||||
el-button(type="default" @click="inviteResponseMessageTable.visible = true; refreshInviteMessageTable('response')" size="mini" icon="el-icon-refresh" circle style="margin-left:5px")
|
||||
el-tooltip(placement="top" :content="$t('view.profile.clear_results_tooltip')" :disabled="hideTooltips")
|
||||
el-button(type="default" @click="inviteResponseMessageTable.visible = false" size="mini" icon="el-icon-delete" circle style="margin-left:5px")
|
||||
data-tables(v-if="inviteResponseMessageTable.visible" v-bind="inviteResponseMessageTable" style="margin-top:10px")
|
||||
el-table-column(label="Slot" prop="slot" sortable="custom" width="70")
|
||||
el-table-column(label="Message" prop="message")
|
||||
el-table-column(label="Cool Down" prop="updatedAt" sortable="custom" width="110" align="right")
|
||||
template(v-once #default="scope")
|
||||
countdown-timer(:datetime="scope.row.updatedAt" :hours="1")
|
||||
el-table-column(label="Action" width="60" align="right")
|
||||
template(v-once #default="scope")
|
||||
el-button(type="text" icon="el-icon-edit" size="mini" @click="showEditInviteMessageDialog('response', scope.row)")
|
||||
div.options-container
|
||||
span.header {{ $t('view.profile.invite_request_messages') }}
|
||||
el-tooltip(placement="top" :content="$t('view.profile.refresh_tooltip')" :disabled="hideTooltips")
|
||||
el-button(type="default" @click="inviteRequestMessageTable.visible = true; refreshInviteMessageTable('request')" size="mini" icon="el-icon-refresh" circle style="margin-left:5px")
|
||||
el-tooltip(placement="top" :content="$t('view.profile.clear_results_tooltip')" :disabled="hideTooltips")
|
||||
el-button(type="default" @click="inviteRequestMessageTable.visible = false" size="mini" icon="el-icon-delete" circle style="margin-left:5px")
|
||||
data-tables(v-if="inviteRequestMessageTable.visible" v-bind="inviteRequestMessageTable" style="margin-top:10px")
|
||||
el-table-column(label="Slot" prop="slot" sortable="custom" width="70")
|
||||
el-table-column(label="Message" prop="message")
|
||||
el-table-column(label="Cool Down" prop="updatedAt" sortable="custom" width="110" align="right")
|
||||
template(v-once #default="scope")
|
||||
countdown-timer(:datetime="scope.row.updatedAt" :hours="1")
|
||||
el-table-column(label="Action" width="60" align="right")
|
||||
template(v-once #default="scope")
|
||||
el-button(type="text" icon="el-icon-edit" size="mini" @click="showEditInviteMessageDialog('request', scope.row)")
|
||||
div.options-container
|
||||
span.header {{ $t('view.profile.invite_request_response_messages') }}
|
||||
el-tooltip(placement="top" :content="$t('view.profile.refresh_tooltip')" :disabled="hideTooltips")
|
||||
el-button(type="default" @click="inviteRequestResponseMessageTable.visible = true; refreshInviteMessageTable('requestResponse')" size="mini" icon="el-icon-refresh" circle style="margin-left:5px")
|
||||
el-tooltip(placement="top" :content="$t('view.profile.clear_results_tooltip')" :disabled="hideTooltips")
|
||||
el-button(type="default" @click="inviteRequestResponseMessageTable.visible = false" size="mini" icon="el-icon-delete" circle style="margin-left:5px")
|
||||
data-tables(v-if="inviteRequestResponseMessageTable.visible" v-bind="inviteRequestResponseMessageTable" style="margin-top:10px")
|
||||
el-table-column(label="Slot" prop="slot" sortable="custom" width="70")
|
||||
el-table-column(label="Message" prop="message")
|
||||
el-table-column(label="Cool Down" prop="updatedAt" sortable="custom" width="110" align="right")
|
||||
template(v-once #default="scope")
|
||||
countdown-timer(:datetime="scope.row.updatedAt" :hours="1")
|
||||
el-table-column(label="Action" width="60" align="right")
|
||||
template(v-once #default="scope")
|
||||
el-button(type="text" icon="el-icon-edit" size="mini" @click="showEditInviteMessageDialog('requestResponse', scope.row)")
|
||||
div.options-container
|
||||
span.header {{ $t('view.profile.past_display_names') }}
|
||||
data-tables(v-bind="pastDisplayNameTable" style="margin-top:10px")
|
||||
el-table-column(label="Date" prop="updated_at" sortable="custom")
|
||||
template(v-once #default="scope")
|
||||
span {{ scope.row.updated_at | formatDate('long') }}
|
||||
el-table-column(label="Name" prop="displayName")
|
||||
div.options-container
|
||||
span.header {{ $t('view.profile.config_json') }}
|
||||
el-tooltip(placement="top" :content="$t('view.profile.refresh_tooltip')" :disabled="hideTooltips")
|
||||
el-button(type="default" @click="refreshConfigTreeData()" size="mini" icon="el-icon-refresh" circle style="margin-left:5px")
|
||||
el-tooltip(placement="top" :content="$t('view.profile.clear_results_tooltip')" :disabled="hideTooltips")
|
||||
el-button(type="default" @click="configTreeData = []" size="mini" icon="el-icon-delete" circle style="margin-left:5px")
|
||||
el-tree(v-if="configTreeData.length > 0" :data="configTreeData" style="margin-top:10px;font-size:12px")
|
||||
template(#default="scope")
|
||||
span
|
||||
span(v-text="scope.data.key" style="font-weight:bold;margin-right:5px")
|
||||
span(v-if="!scope.data.children" v-text="scope.data.value")
|
||||
div.options-container
|
||||
span.header {{ $t('view.profile.current_user_json') }}
|
||||
el-tooltip(placement="top" :content="$t('view.profile.refresh_tooltip')" :disabled="hideTooltips")
|
||||
el-button(type="default" @click="refreshCurrentUserTreeData()" size="mini" icon="el-icon-refresh" circle style="margin-left:5px")
|
||||
el-tooltip(placement="top" :content="$t('view.profile.clear_results_tooltip')" :disabled="hideTooltips")
|
||||
el-button(type="default" @click="currentUserTreeData = []" size="mini" icon="el-icon-delete" circle style="margin-left:5px")
|
||||
el-tree(v-if="currentUserTreeData.length > 0" :data="currentUserTreeData" style="margin-top:10px;font-size:12px")
|
||||
template(#default="scope")
|
||||
span
|
||||
span(v-text="scope.data.key" style="font-weight:bold;margin-right:5px")
|
||||
span(v-if="!scope.data.children" v-text="scope.data.value")
|
||||
div.options-container
|
||||
span.header {{ $t('view.profile.feedback') }}
|
||||
el-tooltip(placement="top" :content="$t('view.profile.refresh_tooltip')" :disabled="hideTooltips")
|
||||
el-button(type="default" @click="getCurrentUserFeedback()" size="mini" icon="el-icon-refresh" circle style="margin-left:5px")
|
||||
el-tooltip(placement="top" :content="$t('view.profile.clear_results_tooltip')" :disabled="hideTooltips")
|
||||
el-button(type="default" @click="currentUserFeedbackData = []" size="mini" icon="el-icon-delete" circle style="margin-left:5px")
|
||||
el-tree(v-if="currentUserFeedbackData.length > 0" :data="currentUserFeedbackData" style="margin-top:10px;font-size:12px")
|
||||
template(#default="scope")
|
||||
span
|
||||
span(v-text="scope.data.key" style="font-weight:bold;margin-right:5px")
|
||||
span(v-if="!scope.data.children" v-text="scope.data.value")
|
||||
73
html/src/mixins/tabs/search.pug
Normal file
73
html/src/mixins/tabs/search.pug
Normal file
@@ -0,0 +1,73 @@
|
||||
mixin searchTab()
|
||||
.x-container(v-show="$refs.menu && $refs.menu.activeIndex === 'search'")
|
||||
div(style="margin:0 0 10px;display:flex;align-items:center")
|
||||
el-input(v-model="searchText" :placeholder="$t('view.search.search_placeholder')" @keyup.native.13="search()" style="flex:1")
|
||||
el-tooltip(placement="bottom" :content="$t('view.search.clear_results_tooltip')" :disabled="hideTooltips")
|
||||
el-button(type="default" @click="clearSearch()" icon="el-icon-delete" circle style="flex:none;margin-left:10px")
|
||||
el-tabs(ref="searchTab" type="card" style="margin-top:15px")
|
||||
el-tab-pane(:label="$t('view.search.user.header')" v-loading="isSearchUserLoading" style="min-height:60px")
|
||||
.x-friend-list
|
||||
.x-friend-item(v-for="user in searchUserResults" :key="user.id" @click="showUserDialog(user.id)")
|
||||
template(v-once)
|
||||
.avatar
|
||||
img(v-lazy="userImage(user)")
|
||||
.detail
|
||||
span.name(v-text="user.displayName")
|
||||
span.extra(v-if="randomUserColours" v-text="user.$trustLevel" :class="user.$trustClass")
|
||||
span.extra(v-else v-text="user.$trustLevel" :style="{'color':user.$userColour}")
|
||||
el-button-group(style="margin-top:15px")
|
||||
el-button(v-if="searchUserParams.offset" @click="moreSearchUser(-1)" icon="el-icon-back" size="small") {{ $t('view.search.prev_page') }}
|
||||
el-button(v-if="searchUserResults.length" @click="moreSearchUser(1)" icon="el-icon-right" size="small") {{ $t('view.search.next_page') }}
|
||||
el-tab-pane(:label="$t('view.search.world.header')" v-loading="isSearchWorldLoading" style="min-height:60px")
|
||||
el-dropdown(@command="(row) => searchWorld(row)" size="small" trigger="click" style="margin-bottom:15px")
|
||||
el-button(size="small") {{ $t('view.search.world.category') }} #[i.el-icon-arrow-down.el-icon--right]
|
||||
el-dropdown-menu(#default="dropdown")
|
||||
el-dropdown-item(v-for="row in API.cachedConfig.dynamicWorldRows" :key="row.index" v-text="row.name" :command="row")
|
||||
el-checkbox(v-model="searchWorldLabs" style="margin-left:10px") {{ $t('view.search.world.community_lab') }}
|
||||
.x-friend-list
|
||||
.x-friend-item(v-for="world in searchWorldResults" :key="world.id" @click="showWorldDialog(world.id)")
|
||||
template(v-once)
|
||||
.avatar
|
||||
img(v-lazy="world.thumbnailImageUrl")
|
||||
.detail
|
||||
span.name(v-text="world.name")
|
||||
span.extra(v-if="world.occupants") {{ world.authorName }} ({{ world.occupants }})
|
||||
span.extra(v-else v-text="world.authorName")
|
||||
el-button-group(style="margin-top:15px")
|
||||
el-button(v-if="searchWorldParams.offset" @click="moreSearchWorld(-1)" icon="el-icon-back" size="small") {{ $t('view.search.prev_page') }}
|
||||
el-button(v-if="searchWorldResults.length >= 10" @click="moreSearchWorld(1)" icon="el-icon-right" size="small") {{ $t('view.search.next_page') }}
|
||||
el-tab-pane(:label="$t('view.search.avatar.header')" v-loading="isSearchAvatarLoading" style="min-height:60px")
|
||||
el-dropdown(v-if="avatarRemoteDatabaseProviderList.length > 1" trigger="click" @click.native.stop size="mini" style="margin-right:5px")
|
||||
el-button(size="small") {{ $t('view.search.avatar.search_provider') }} #[i.el-icon-arrow-down.el-icon--right]
|
||||
el-dropdown-menu(#default="dropdown")
|
||||
el-dropdown-item(v-for="provider in avatarRemoteDatabaseProviderList" :key="provider" @click.native="setAvatarProvider(provider)") #[i.el-icon-check.el-icon--left(v-if="provider === avatarRemoteDatabaseProvider")] {{ provider }}
|
||||
el-tooltip(placement="bottom" :content="$t('view.search.avatar.refresh_tooltip')" :disabled="hideTooltips")
|
||||
el-button(type="default" :loading="userDialog.isAvatarsLoading" @click="refreshUserDialogAvatars()" size="mini" icon="el-icon-refresh" circle)
|
||||
span(style="font-size:14px;margin-left:5px;margin-right:5px") {{ $t("view.search.avatar.result_count", { count: searchAvatarResults.length }) }}
|
||||
el-radio-group(v-model="searchAvatarFilter" size="mini" style="margin:5px;display:block" @change="searchAvatar")
|
||||
el-radio(label="all") {{ $t('view.search.avatar.all') }}
|
||||
el-radio(label="public") {{ $t('view.search.avatar.public') }}
|
||||
el-radio(label="private") {{ $t('view.search.avatar.private') }}
|
||||
el-radio-group(v-model="searchAvatarFilterRemote" size="mini" style="margin:5px;display:block" @change="searchAvatar")
|
||||
el-radio(label="all") {{ $t('view.search.avatar.all') }}
|
||||
el-radio(label="local") {{ $t('view.search.avatar.local') }}
|
||||
el-radio(label="remote" :disabled="!avatarRemoteDatabase") {{ $t('view.search.avatar.remote') }}
|
||||
el-radio-group(:disabled="searchAvatarFilterRemote !== 'local'" v-model="searchAvatarSort" size="mini" style="margin:5px;display:block" @change="searchAvatar")
|
||||
el-radio(label="name") {{ $t('view.search.avatar.sort_name') }}
|
||||
el-radio(label="update") {{ $t('view.search.avatar.sort_update') }}
|
||||
el-radio(label="created") {{ $t('view.search.avatar.sort_created') }}
|
||||
.x-friend-list(style="margin-top:20px")
|
||||
.x-friend-item(v-for="avatar in searchAvatarPage" :key="avatar.id" @click="showAvatarDialog(avatar.id)")
|
||||
template(v-once)
|
||||
.avatar
|
||||
img(v-if="avatar.thumbnailImageUrl" v-lazy="avatar.thumbnailImageUrl")
|
||||
img(v-else-if="avatar.imageUrl" v-lazy="avatar.imageUrl")
|
||||
.detail
|
||||
span.name(v-text="avatar.name")
|
||||
span.extra(v-text="avatar.releaseStatus" v-if="avatar.releaseStatus === 'public'" style="color: #67c23a;")
|
||||
span.extra(v-text="avatar.releaseStatus" v-else-if="avatar.releaseStatus === 'private'" style="color: #f56c6c;")
|
||||
span.extra(v-text="avatar.releaseStatus" v-else)
|
||||
span.extra(v-text="avatar.authorName")
|
||||
el-button-group(style="margin-top:15px")
|
||||
el-button(v-if="searchAvatarPageNum" @click="moreSearchAvatar(-1)" icon="el-icon-back" size="small") {{ $t('view.search.prev_page') }}
|
||||
el-button(v-if="searchAvatarResults.length > 10 && (searchAvatarPageNum + 1) * 10 < searchAvatarResults.length" @click="moreSearchAvatar(1)" icon="el-icon-right" size="small") {{ $t('view.search.next_page') }}
|
||||
521
html/src/mixins/tabs/settings.pug
Normal file
521
html/src/mixins/tabs/settings.pug
Normal file
@@ -0,0 +1,521 @@
|
||||
mixin simpleSettingsCategory(headerTrKey)
|
||||
div.options-container
|
||||
span.header {{ $t('#{headerTrKey}') }}
|
||||
if block
|
||||
block
|
||||
else
|
||||
p No Content
|
||||
|
||||
mixin simpleSwitch(nameTrKey, model, onChange="")
|
||||
div.options-container-item
|
||||
//- I fought with getting the right syntax for a translation key, as an argument, in an interpolated block for like 20mins before I realized the answer was staring me in the face in the documentation I passed over like 5 times. Feelsbadman.
|
||||
//- I didn't even know what pug was before working on this; speedrunning learning pug templating.
|
||||
span.name {{ $t('#{nameTrKey}') }}
|
||||
//- I've also never worked with vue/element and have no idea what I'm doing. pog, as the kids say
|
||||
el-switch(v-model=model @change=onChange)
|
||||
|
||||
mixin simpleTwoLabelSwitch(nameTrKey, model, onChange="")
|
||||
div.options-container-item
|
||||
span.name {{ $t('#{nameTrKey}') }}
|
||||
el-switch(v-model=model @change=onChange)
|
||||
|
||||
mixin simpleRadioGroup(nameTrKey, model, options, onChange="")
|
||||
div.options-container-item
|
||||
span.name {{ $t('#{nameTrKey}') }}
|
||||
br
|
||||
el-radio-group(v-model=model @change=onChange size="mini")
|
||||
each option in options
|
||||
el-radio-button(label="#{option.label}") {{ $t('#{option.translationKey}') }}
|
||||
|
||||
mixin settingsTab()
|
||||
.x-container(v-show="$refs.menu && $refs.menu.activeIndex === 'settings'")
|
||||
div.options-container(style="margin-top:0")
|
||||
span.header {{ $t("view.settings.header") }}
|
||||
el-tabs(type="card" style="margin-top:10px")
|
||||
el-tab-pane(:label="$t('view.settings.category.general')")
|
||||
//- General | General
|
||||
div.options-container(style="margin-top:0")
|
||||
span.header {{ $t("view.settings.general.general.header") }}
|
||||
.x-friend-list(style="margin-top:10px")
|
||||
//- General | General | Version
|
||||
.x-friend-item(style="cursor:default")
|
||||
.detail
|
||||
span.name {{ $t("view.settings.general.general.version") }}
|
||||
span.extra(v-text="appVersion")
|
||||
//- General | General | Latest App Version
|
||||
.x-friend-item(@click="checkForVRCXUpdate")
|
||||
.detail
|
||||
span.name {{ $t("view.settings.general.general.latest_app_version") }}
|
||||
span.extra(v-if="latestAppVersion" v-text="latestAppVersion")
|
||||
span.extra(v-else) {{ $t("view.settings.general.general.latest_app_version_refresh") }}
|
||||
//- General | General | Repository URL
|
||||
.x-friend-item(@click="openExternalLink('https://github.com/vrcx-team/VRCX')")
|
||||
.detail
|
||||
span.name {{ $t("view.settings.general.general.repository_url") }}
|
||||
span.extra https://github.com/vrcx-team/VRCX
|
||||
//- General | General | Support
|
||||
.x-friend-item(@click="openExternalLink('https://vrcx.pypy.moe/discord')")
|
||||
.detail
|
||||
span.name {{ $t("view.settings.general.general.support") }}
|
||||
span.extra https://vrcx.pypy.moe/discord
|
||||
//- General | VRCX Updater
|
||||
+simpleSettingsCategory("view.settings.general.vrcx_updater.header")
|
||||
div.options-container-item
|
||||
el-button(size="small" icon="el-icon-document" @click="showChangeLogDialog()") {{ $t("view.settings.general.vrcx_updater.change_log") }}
|
||||
el-button(size="small" icon="el-icon-upload" @click="showVRCXUpdateDialog()") {{ $t("view.settings.general.vrcx_updater.change_build") }}
|
||||
+simpleRadioGroup("view.settings.general.vrcx_updater.auto_update", "autoUpdateVRCX", [
|
||||
{ label: "Off", translationKey: "view.settings.general.vrcx_updater.auto_update_off" },
|
||||
{ label: "Notify", translationKey: "view.settings.general.vrcx_updater.auto_update_notify" },
|
||||
{ label: "Auto Download", translationKey: "view.settings.general.vrcx_updater.auto_update_download" },
|
||||
{ label: "Auto Install", translationKey: "view.settings.general.vrcx_updater.auto_update_install" },
|
||||
], "saveAutoUpdateVRCX")
|
||||
//- General | Application
|
||||
+simpleSettingsCategory("view.settings.general.application.header")
|
||||
+simpleSwitch("view.settings.general.application.startup", "isStartAtWindowsStartup", "saveVRCXWindowOption")
|
||||
+simpleSwitch("view.settings.general.application.minimized", "isStartAsMinimizedState", "saveVRCXWindowOption")
|
||||
+simpleSwitch("view.settings.general.application.tray", "isCloseToTray", "saveVRCXWindowOption")
|
||||
div.options-container
|
||||
//- General | Game Log
|
||||
+simpleSettingsCategory("view.settings.general.game_log.header")
|
||||
+simpleSwitch("view.settings.general.game_log.resource_load", "logResourceLoad", "saveGameLogOptions")
|
||||
div.options-container
|
||||
//- General | Legal Notice
|
||||
div.options-container(style="margin-top:45px;border-top:1px solid #eee;padding-top:30px")
|
||||
span.header {{ $t("view.settings.general.legal_notice.header" )}}
|
||||
div.options-container-item
|
||||
p © 2019-2022 #[a.x-link(@click="openExternalLink('https://github.com/pypy-vrc')") pypy] (mina#5656) & #[a.x-link(@click="openExternalLink('https://github.com/Natsumi-sama')") Natsumi]
|
||||
p {{ $t("view.settings.general.legal_notice.info" )}}
|
||||
p {{ $t("view.settings.general.legal_notice.disclaimer1" )}}
|
||||
p {{ $t("view.settings.general.legal_notice.disclaimer2" )}}
|
||||
div.options-container-item
|
||||
el-button(@click="ossDialog = true" size="small") {{ $t("view.settings.general.legal_notice.open_source_software_notice" )}}
|
||||
//- Appearance Tab
|
||||
el-tab-pane(:label="$t('view.settings.category.appearance')")
|
||||
//- Appearance | Appearance
|
||||
div.options-container(style="margin-top:0")
|
||||
span.header {{ $t("view.settings.appearance.appearance.header") }}
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.appearance.appearance.language') }}
|
||||
el-dropdown(@click.native.stop trigger="click" size="small")
|
||||
el-button(size="mini")
|
||||
span {{ $i18n.messages[appLanguage]?.language }} #[i.el-icon-arrow-down.el-icon--right]
|
||||
el-dropdown-menu(#default="dropdown")
|
||||
el-dropdown-item(v-for="(obj, language) in $i18n.messages" v-text="obj.language" @click.native="changeAppLanguage(language)")
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.appearance.appearance.theme_mode') }}
|
||||
el-radio-group(v-model="themeMode" size="mini")
|
||||
el-radio-button(label="system") {{ $t('view.settings.appearance.appearance.theme_mode_system') }}
|
||||
el-radio-button(label="light") {{ $t('view.settings.appearance.appearance.theme_mode_light') }}
|
||||
el-radio-button(label="dark") {{ $t('view.settings.appearance.appearance.theme_mode_dark') }}
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.appearance.appearance.vrcplus_profile_icons') }}
|
||||
el-switch(v-model="displayVRCPlusIconsAsAvatar" @change="saveOpenVROption")
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.appearance.appearance.disable_tooltips') }}
|
||||
el-switch(v-model="hideTooltips" @change="saveOpenVROption")
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.appearance.appearance.sort_favorite_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")
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.appearance.appearance.sort_instance_users_by') }}
|
||||
el-switch(v-model="instanceUsersSortAlphabetical" :inactive-text="$t('view.settings.appearance.appearance.sort_instance_users_by_time')" :active-text="$t('view.settings.appearance.appearance.sort_instance_users_by_alphabet')" @change="saveOpenVROption")
|
||||
div.options-container-item
|
||||
el-button(size="small" icon="el-icon-notebook-1" @click="promptMaxTableSizeDialog") {{ $t('view.settings.appearance.appearance.table_max_size') }}
|
||||
div.options-container-item
|
||||
el-dropdown(@click.native.stop trigger="click" size="small")
|
||||
el-button(size="mini")
|
||||
span {{ $t('view.settings.appearance.appearance.page_size') }} {{ tablePageSize }} #[i.el-icon-arrow-down.el-icon--right]
|
||||
el-dropdown-menu(#default="dropdown")
|
||||
el-dropdown-item(v-for="(number) in [10, 15, 25, 50, 100]" v-text="number" @click.native="setTablePageSize(number)")
|
||||
//- Appearance | Time/Date
|
||||
div.options-container
|
||||
span.header {{ $t('view.settings.appearance.timedate.header') }}
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.appearance.timedate.time_format') }}
|
||||
el-switch(v-model="dtHour12" @change="setDatetimeFormat" :inactive-text="$t('view.settings.appearance.timedate.time_format_24')" :active-text="$t('view.settings.appearance.timedate.time_format_12')")
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.appearance.timedate.force_iso_date_format') }}
|
||||
el-switch(v-model="dtIsoFormat" @change="setDatetimeFormat")
|
||||
//- Appearance | Side Panel
|
||||
div.options-container
|
||||
span.header {{ $t('view.settings.appearance.side_panel.header') }}
|
||||
br
|
||||
span.sub-header {{ $t('view.settings.appearance.side_panel.sorting.header') }}
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.appearance.side_panel.sorting.sort_private_to_bottom') }}
|
||||
el-switch(v-model="orderFriendsGroupPrivate" @change="saveOrderFriendGroup")
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.appearance.side_panel.sorting.sort_by_status') }}
|
||||
el-switch(v-model="orderFriendsGroupStatus" @change="saveOrderFriendGroup")
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.appearance.side_panel.sorting.sort_gps_to_top') }}
|
||||
el-switch(v-model="orderFriendsGroupGPS" @change="saveOrderFriendGroup")
|
||||
span.name(style="margin-left:5px") {{ $t('view.settings.appearance.side_panel.sorting.sort_gps_to_top_notice') }}
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.appearance.side_panel.sorting.sort_favorite_by') }}
|
||||
el-switch(v-model="orderFriendsGroup0" :inactive-text="$t('view.settings.appearance.side_panel.sorting.sort_favorite_by_alphabet')" :active-text="$t('view.settings.appearance.side_panel.sorting.sort_favorite_by_online_time')" @change="saveOrderFriendGroup")
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.appearance.side_panel.sorting.sort_online_by') }}
|
||||
el-switch(v-model="orderFriendsGroup1" :inactive-text="$t('view.settings.appearance.side_panel.sorting.sort_online_by_alphabet')" :active-text="$t('view.settings.appearance.side_panel.sorting.sort_online_by_online_time')" @change="saveOrderFriendGroup")
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.appearance.side_panel.sorting.sort_active_by') }}
|
||||
el-switch(v-model="orderFriendsGroup2" :inactive-text="$t('view.settings.appearance.side_panel.sorting.sort_active_by_alphabet')" :active-text="$t('view.settings.appearance.side_panel.sorting.sort_active_by_online_time')" @change="saveOrderFriendGroup")
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.appearance.side_panel.sorting.sort_offline_by') }}
|
||||
el-switch(v-model="orderFriendsGroup3" :inactive-text="$t('view.settings.appearance.side_panel.sorting.sort_offline_by_alphabet')" :active-text="$t('view.settings.appearance.side_panel.sorting.sort_offline_by_offline_time')" @change="saveOrderFriendGroup")
|
||||
span.sub-header {{ $t('view.settings.appearance.side_panel.width') }}
|
||||
div.options-container-item
|
||||
el-slider(v-model="asideWidth" @input="setAsideWidth" :show-tooltip="false" :marks="{236: ''}" :min="141" :max="500" style="width:300px")
|
||||
//- Appearance | User Dialog
|
||||
div.options-container
|
||||
span.header {{ $t('view.settings.appearance.user_dialog.header') }}
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.appearance.user_dialog.hide_vrchat_notes') }}
|
||||
el-switch(v-model="hideUserNotes" @change="saveUserDialogOption")
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.appearance.user_dialog.hide_vrcx_memos') }}
|
||||
el-switch(v-model="hideUserMemos" @change="saveUserDialogOption")
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.appearance.user_dialog.export_vrcx_memos_into_vrchat_notes') }}
|
||||
br
|
||||
el-button(size="small" icon="el-icon-document-copy" @click="showNoteExportDialog") {{ $t('view.settings.appearance.user_dialog.export_notes') }}
|
||||
//- Appearance | User Colors
|
||||
div.options-container
|
||||
span.header {{ $t('view.settings.appearance.user_colors.header') }}
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.appearance.user_colors.random_colors_from_user_id') }}
|
||||
el-switch(v-model="randomUserColours" @change="updatetrustColor")
|
||||
div.options-container-item
|
||||
div
|
||||
el-color-picker(v-model="trustColor.untrusted" @change="updatetrustColor" size="mini" :predefine="['#CCCCCC']")
|
||||
span.color-picker(slot="trigger" class="x-tag-untrusted") Visitor
|
||||
div
|
||||
el-color-picker(v-model="trustColor.basic" @change="updatetrustColor" size="mini" :predefine="['#1778ff']")
|
||||
span.color-picker(slot="trigger" class="x-tag-basic") New User
|
||||
div
|
||||
el-color-picker(v-model="trustColor.known" @change="updatetrustColor" size="mini" :predefine="['#2bcf5c']")
|
||||
span.color-picker(slot="trigger" class="x-tag-known") User
|
||||
div
|
||||
el-color-picker(v-model="trustColor.trusted" @change="updatetrustColor" size="mini" :predefine="['#ff7b42']")
|
||||
span.color-picker(slot="trigger" class="x-tag-trusted") Known User
|
||||
div
|
||||
el-color-picker(v-model="trustColor.veteran" @change="updatetrustColor" size="mini" :predefine="['#b18fff', '#8143e6', '#ff69b4', '#b52626', '#ffd000', '#abcdef']")
|
||||
span.color-picker(slot="trigger" class="x-tag-veteran") Trusted User
|
||||
div
|
||||
el-color-picker(v-model="trustColor.vip" @change="updatetrustColor" size="mini" :predefine="['#ff2626']")
|
||||
span.color-picker(slot="trigger" class="x-tag-vip") VRChat Team
|
||||
div
|
||||
el-color-picker(v-model="trustColor.troll" @change="updatetrustColor" size="mini" :predefine="['#782f2f']")
|
||||
span.color-picker(slot="trigger" class="x-tag-troll") Nuisance
|
||||
//- Notifications Tab
|
||||
el-tab-pane(:label="$t('view.settings.category.notifications')")
|
||||
//- Notifications | Notifications
|
||||
div.options-container(style="margin-top:0")
|
||||
span.header {{ $t('view.settings.notifications.notifications.header') }}
|
||||
div.options-container-item
|
||||
el-button(size="small" icon="el-icon-chat-square" @click="showNotyFeedFiltersDialog") {{ $t('view.settings.notifications.notifications.notification_filter') }}
|
||||
//- Notifications | Notifications | SteamVR Notifications
|
||||
span.sub-header {{ $t('view.settings.notifications.notifications.steamvr_notifications.header') }}
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.notifications.notifications.steamvr_notifications.steamvr_overlay') }}
|
||||
el-switch(v-model="openVR" @change="saveOpenVROption")
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.notifications.notifications.steamvr_notifications.overlay_notifications') }}
|
||||
el-switch(v-model="overlayNotifications" @change="saveOpenVROption" :disabled="!openVR")
|
||||
div.options-container-item
|
||||
el-button(size="small" icon="el-icon-rank" @click="showNotificationPositionDialog" :disabled="!overlayNotifications || !openVR") {{ $t('view.settings.notifications.notifications.steamvr_notifications.notification_position') }}
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.notifications.notifications.steamvr_notifications.xsoverlay_notifications') }}
|
||||
el-switch(v-model="xsNotifications" @change="saveOpenVROption")
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.notifications.notifications.steamvr_notifications.user_images') }}
|
||||
el-switch(v-model="imageNotifications" @change="saveOpenVROption")
|
||||
div.options-container-item
|
||||
el-button(size="small" icon="el-icon-time" @click="promptNotificationTimeout" :disabled="(!overlayNotifications || !openVR) && !xsNotifications") {{ $t('view.settings.notifications.notifications.steamvr_notifications.notification_timeout') }}
|
||||
//- Notifications | Notifications | Desktop Notifications
|
||||
span.sub-header {{ $t('view.settings.notifications.notifications.desktop_notifications.header') }}
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.notifications.notifications.desktop_notifications.when_to_display') }}
|
||||
br
|
||||
el-radio-group(v-model="desktopToast" @change="saveOpenVROption" size="mini")
|
||||
el-radio-button(label="Never") {{ $t('view.settings.notifications.notifications.desktop_notifications.when_to_display_never') }}
|
||||
el-radio-button(label="Desktop Mode") {{ $t('view.settings.notifications.notifications.desktop_notifications.when_to_display_desktop') }}
|
||||
el-radio-button(label="Inside VR") {{ $t('view.settings.notifications.notifications.desktop_notifications.when_to_display_inside_vr') }}
|
||||
el-radio-button(label="Outside VR") {{ $t('view.settings.notifications.notifications.desktop_notifications.when_to_display_outside_vr') }}
|
||||
el-radio-button(label="Game Closed") {{ $t('view.settings.notifications.notifications.desktop_notifications.when_to_display_game_closed') }}
|
||||
el-radio-button(label="Game Running") {{ $t('view.settings.notifications.notifications.desktop_notifications.when_to_display_game_running') }}
|
||||
el-radio-button(label="Always") {{ $t('view.settings.notifications.notifications.desktop_notifications.when_to_display_always') }}
|
||||
br
|
||||
//- Notifications | Notifications | Text-to-Speech Options
|
||||
span.sub-header {{ $t('view.settings.notifications.notifications.text_to_speech.header') }}
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.notifications.notifications.text_to_speech.when_to_play') }}
|
||||
br
|
||||
el-radio-group(v-model="notificationTTS" @change="saveNotificationTTS" size="mini")
|
||||
el-radio-button(label="Never") {{ $t('view.settings.notifications.notifications.text_to_speech.when_to_play_never') }}
|
||||
el-radio-button(label="Inside VR") {{ $t('view.settings.notifications.notifications.text_to_speech.when_to_play_inside_vr') }}
|
||||
el-radio-button(label="Game Closed") {{ $t('view.settings.notifications.notifications.text_to_speech.when_to_play_game_closed') }}
|
||||
el-radio-button(label="Game Running") {{ $t('view.settings.notifications.notifications.text_to_speech.when_to_play_game_running') }}
|
||||
el-radio-button(label="Always") {{ $t('view.settings.notifications.notifications.text_to_speech.when_to_play_always') }}
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.notifications.notifications.text_to_speech.tts_voice') }}
|
||||
el-dropdown(@command="(voice) => changeTTSVoice(voice)" trigger="click" size="small")
|
||||
el-button(size="mini" :disabled="notificationTTS === 'Never'")
|
||||
span {{ getTTSVoiceName() }} #[i.el-icon-arrow-down.el-icon--right]
|
||||
el-dropdown-menu(#default="dropdown")
|
||||
el-dropdown-item(v-if="voice" v-for="(voice, index) in TTSvoices" :key="index" v-text="voice.name" :command="index")
|
||||
//- Wrist Overlay Tab
|
||||
el-tab-pane(:label="$t('view.settings.category.wrist_overlay')")
|
||||
//- Wrist Overlay | SteamVR Wrist Overlay
|
||||
div.options-container(style="margin-top:0")
|
||||
span.header {{ $t('view.settings.wrist_overlay.steamvr_wrist_overlay.header') }}
|
||||
div.options-container-item
|
||||
span {{ $t('view.settings.wrist_overlay.steamvr_wrist_overlay.description') }}
|
||||
br
|
||||
br
|
||||
span {{ $t('view.settings.wrist_overlay.steamvr_wrist_overlay.grip') }}
|
||||
br
|
||||
span {{ $t('view.settings.wrist_overlay.steamvr_wrist_overlay.menu') }}
|
||||
br
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.wrist_overlay.steamvr_wrist_overlay.steamvr_overlay') }}
|
||||
el-switch(v-model="openVR" @change="saveOpenVROption")
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.wrist_overlay.steamvr_wrist_overlay.wrist_feed_overlay') }}
|
||||
el-switch(v-model="overlayWrist" @change="saveOpenVROption" :disabled="!openVR")
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.wrist_overlay.steamvr_wrist_overlay.hide_private_worlds') }}
|
||||
el-switch(v-model="hidePrivateFromFeed" @change="saveOpenVROption")
|
||||
div.options-container-item(style="min-width:118px")
|
||||
span.name {{ $t('view.settings.wrist_overlay.steamvr_wrist_overlay.start_overlay_with') }}
|
||||
el-switch(v-model="openVRAlways" @change="saveOpenVROption" inactive-text="VRChat" active-text="SteamVR" :disabled="!openVR")
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.wrist_overlay.steamvr_wrist_overlay.overlay_button') }}
|
||||
el-switch(v-model="overlaybutton" @change="saveOpenVROption" :inactive-text="$t('view.settings.wrist_overlay.steamvr_wrist_overlay.overlay_button_grip')" :active-text="$t('view.settings.wrist_overlay.steamvr_wrist_overlay.overlay_button_menu')" :disabled="!openVR || !overlayWrist")
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.wrist_overlay.steamvr_wrist_overlay.display_overlay_on') }}
|
||||
el-radio-group(v-model="overlayHand" @change="saveOpenVROption" size="mini")
|
||||
el-radio-button(label="1") {{ $t('view.settings.wrist_overlay.steamvr_wrist_overlay.display_overlay_on_left') }}
|
||||
el-radio-button(label="2") {{ $t('view.settings.wrist_overlay.steamvr_wrist_overlay.display_overlay_on_right') }}
|
||||
el-radio-button(label="0") {{ $t('view.settings.wrist_overlay.steamvr_wrist_overlay.display_overlay_on_both') }}
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.wrist_overlay.steamvr_wrist_overlay.background_color') }}
|
||||
el-switch(v-model="vrBackgroundEnabled" @change="saveOpenVROption" :disabled="!openVR || !overlayWrist")
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.wrist_overlay.steamvr_wrist_overlay.minimal_feed_icons') }}
|
||||
el-switch(v-model="minimalFeed" @change="saveOpenVROption" :disabled="!openVR || !overlayWrist")
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.wrist_overlay.steamvr_wrist_overlay.hide_vr_devices') }}
|
||||
el-switch(v-model="hideDevicesFromFeed" @change="saveOpenVROption" :disabled="!openVR || !overlayWrist")
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.wrist_overlay.steamvr_wrist_overlay.hide_cpu_usage') }}
|
||||
el-switch(v-model="hideCpuUsageFromFeed" @change="saveOpenVROption" :disabled="!openVR || !overlayWrist")
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.wrist_overlay.steamvr_wrist_overlay.hide_game_uptime') }}
|
||||
el-switch(v-model="hideUptimeFromFeed" @change="saveOpenVROption" :disabled="!openVR || !overlayWrist")
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.wrist_overlay.steamvr_wrist_overlay.show_pc_uptime') }}
|
||||
el-switch(v-model="pcUptimeOnFeed" @change="saveOpenVROption" :disabled="!openVR || !overlayWrist")
|
||||
div.options-container-item
|
||||
el-button(size="small" icon="el-icon-notebook-2" @click="showWristFeedFiltersDialog" :disabled="!openVR || !overlayWrist") {{ $t('view.settings.wrist_overlay.steamvr_wrist_overlay.wrist_feed_filters') }}
|
||||
//- Discord Presence Tab
|
||||
el-tab-pane(:label="$t('view.settings.category.discord_presence')")
|
||||
div.options-container(style="margin-top:0")
|
||||
span.header {{ $t('view.settings.discord_presence.discord_presence.header') }}
|
||||
div.options-container-item
|
||||
span {{ $t('view.settings.discord_presence.discord_presence.description') }}
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.discord_presence.discord_presence.enable') }}
|
||||
el-tooltip(placement="top" style="margin-left:5px" :content="$t('view.settings.discord_presence.discord_presence.enable_tooltip')")
|
||||
i.el-icon-warning(style="cursor:pointer" @click="showVRChatConfig")
|
||||
el-switch(v-model="discordActive" @change="saveDiscordOption")
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.discord_presence.discord_presence.instance_type_player_count') }}
|
||||
el-switch(v-model="discordInstance" @change="saveDiscordOption" :disabled="!discordActive")
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.discord_presence.discord_presence.join_button') }}
|
||||
el-switch(v-model="discordJoinButton" @change="saveDiscordOption" :disabled="!discordActive")
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.discord_presence.discord_presence.hide_details_in_private') }}
|
||||
el-switch(v-model="discordHideInvite" @change="saveDiscordOption" :disabled="!discordActive")
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.discord_presence.discord_presence.hide_images') }}
|
||||
el-switch(v-model="discordHideImage" @change="saveDiscordOption" :disabled="!discordActive")
|
||||
//- "Advanced" Tab
|
||||
el-tab-pane(:label="$t('view.settings.category.advanced')")
|
||||
//- Advanced | Advanced
|
||||
div.options-container(style="margin-top:0")
|
||||
span.header {{ $t('view.settings.advanced.advanced.header') }}
|
||||
div.options-container-item
|
||||
el-button-group
|
||||
el-button(size="small" icon="el-icon-s-operation" @click="showVRChatConfig()") VRChat config.json
|
||||
el-button(size="small" icon="el-icon-s-operation" @click="showLaunchOptions()") {{ $t('view.settings.advanced.advanced.launch_options') }}
|
||||
el-button(size="small" icon="el-icon-picture" @click="showScreenshotMetadataDialog()") {{ $t('view.settings.advanced.advanced.screenshot_metadata') }}
|
||||
//- *sigh*
|
||||
//- Advanced | Primary Password
|
||||
div.options-container
|
||||
//- Advanced | Primary Password Header
|
||||
span.sub-header {{ $t('view.settings.advanced.advanced.primary_password.header') }}
|
||||
div.options-container-item
|
||||
span.name(style="min-width:300px") {{ $t('view.settings.advanced.advanced.primary_password.description') }}
|
||||
el-switch(v-model="enablePrimaryPassword" @change="enablePrimaryPasswordChange" :disabled="!loginForm.savedCredentials[API.currentUser.id]")
|
||||
span.sub-header {{ $t('view.settings.advanced.advanced.relaunch_vrchat.header') }}
|
||||
//- Advanced | Relaunch VRChat After Crash
|
||||
div.options-container-item
|
||||
span.name(style="min-width:300px") {{ $t('view.settings.advanced.advanced.relaunch_vrchat.description') }}
|
||||
el-switch(v-model="relaunchVRChatAfterCrash" @change="saveOpenVROption")
|
||||
//- Advanced | VRChat Quit Fix
|
||||
span.sub-header {{ $t('view.settings.advanced.advanced.vrchat_quit_fix.header') }}
|
||||
div.options-container-item
|
||||
span.name(style="min-width:300px") {{ $t('view.settings.advanced.advanced.vrchat_quit_fix.description') }}
|
||||
el-switch(v-model="vrcQuitFix" @change="saveOpenVROption")
|
||||
//- Advanced | Auto Cache Management
|
||||
span.sub-header {{ $t('view.settings.advanced.advanced.auto_cache_management.header') }}
|
||||
div.options-container-item
|
||||
span.name(style="min-width:300px") {{ $t('view.settings.advanced.advanced.auto_cache_management.description') }}
|
||||
el-switch(v-model="autoSweepVRChatCache" @change="saveOpenVROption")
|
||||
//- Advanced | Remote Avatar Database
|
||||
div.options-container
|
||||
span.header {{ $t('view.settings.advanced.advanced.remote_database.header') }}
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.advanced.advanced.remote_database.enable') }}
|
||||
el-switch(v-model="avatarRemoteDatabase" @change="saveOpenVROption")
|
||||
div.options-container-item
|
||||
el-button(size="small" icon="el-icon-user-solid" @click="showAvatarProviderDialog") {{ $t('view.settings.advanced.advanced.remote_database.avatar_database_provider') }}
|
||||
//- Advanced | YouTube API
|
||||
div.options-container
|
||||
span.header {{ $t('view.settings.advanced.advanced.youtube_api.header') }}
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.advanced.advanced.youtube_api.enable') }}
|
||||
el-switch(v-model="youTubeApi" @change="changeYouTubeApi")
|
||||
div.options-container-item
|
||||
el-button(size="small" icon="el-icon-caret-right" @click="showYouTubeApiDialog") {{ $t('view.settings.advanced.advanced.youtube_api.youtube_api_key') }}
|
||||
span.header {{ $t('view.settings.advanced.advanced.video_progress_pie.header') }}
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.advanced.advanced.video_progress_pie.enable') }}
|
||||
el-tooltip(placement="top" style="margin-left:5px" :content="$t('view.settings.advanced.advanced.video_progress_pie.enable_tooltip')")
|
||||
i.el-icon-warning
|
||||
el-switch(v-model="progressPie" @change="changeYouTubeApi" :disabled="!openVR")
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.advanced.advanced.video_progress_pie.dance_world_only') }}
|
||||
el-switch(v-model="progressPieFilter" @change="changeYouTubeApi" :disabled="!openVR")
|
||||
//- Advanced | Screenshot Helper
|
||||
div.options-container
|
||||
span.header {{ $t('view.settings.advanced.advanced.screenshot_helper.header') }}
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.advanced.advanced.screenshot_helper.description') }}
|
||||
el-tooltip(placement="top" style="margin-left:5px" :content="$t('view.settings.advanced.advanced.screenshot_helper.description_tooltip')")
|
||||
i.el-icon-info
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.advanced.advanced.screenshot_helper.enable') }}
|
||||
el-switch(v-model="screenshotHelper" @change="saveScreenshotHelper")
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.advanced.advanced.screenshot_helper.modify_filename') }}
|
||||
el-tooltip(placement="top" style="margin-left:5px" :content="$t('view.settings.advanced.advanced.screenshot_helper.modify_filename_tooltip')")
|
||||
i.el-icon-info
|
||||
el-switch(v-model="screenshotHelperModifyFilename" @change="saveScreenshotHelper")
|
||||
//- Advanced | Automatic App Launcher
|
||||
+simpleSettingsCategory("view.settings.advanced.advanced.app_launcher.header")
|
||||
br
|
||||
el-button(size="small" icon="el-icon-folder" @click="openShortcutFolder()") {{ $t('view.settings.advanced.advanced.app_launcher.folder') }}
|
||||
el-tooltip(placement="top" style="margin-left:5px" :content="$t('view.settings.advanced.advanced.app_launcher.folder_tooltip')")
|
||||
i.el-icon-warning
|
||||
+simpleSwitch("view.settings.advanced.advanced.app_launcher.enable", "enableAppLauncher", "updateAppLauncherSettings")
|
||||
+simpleSwitch("view.settings.advanced.advanced.app_launcher.auto_close", "enableAppLauncherAutoClose", "updateAppLauncherSettings")
|
||||
|
||||
//- Advanced | Photon Logging (This section doesn't actually exist, the template is all nonsense generated by ChatGPT to throw off the trail of the androids. Spooky. Trust me, bro.)
|
||||
div.options-container(v-if="photonLoggingEnabled")
|
||||
span.header {{ $t('view.settings.advanced.photon.header') }}
|
||||
div.options-container-item
|
||||
span.sub-header {{ $t('view.settings.advanced.photon.event_hud.header') }}
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.advanced.photon.event_hud.enable') }}
|
||||
el-tooltip(placement="top" style="margin-left:5px" :content="$t('view.settings.advanced.photon.event_hud.enable_tooltip')")
|
||||
i.el-icon-warning
|
||||
el-switch(v-model="photonEventOverlay" @change="saveEventOverlay" :disabled="!openVR")
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.advanced.photon.event_hud.filter') }}
|
||||
el-radio-group(v-model="photonEventOverlayFilter" @change="saveEventOverlay" size="mini" :disabled="!openVR || !photonEventOverlay")
|
||||
el-radio-button(label="VIP") {{ $t('view.settings.advanced.photon.event_hud.filter_favorites') }}
|
||||
el-radio-button(label="Friends") {{ $t('view.settings.advanced.photon.event_hud.filter_friends') }}
|
||||
el-radio-button(label="Everyone") {{ $t('view.settings.advanced.photon.event_hud.filter_everyone') }}
|
||||
div.options-container-item
|
||||
el-button(size="small" icon="el-icon-time" @click="promptPhotonOverlayMessageTimeout" :disabled="!openVR") {{ $t('view.settings.advanced.photon.event_hud.message_timeout') }}
|
||||
div.options-container-item
|
||||
el-select(v-model="photonEventTableTypeOverlayFilter" @change="photonEventTableFilterChange" multiple clearable collapse-tags style="flex:1" placeholder="Filter")
|
||||
el-option(v-once v-for="type in photonEventTableTypeFilterList" :key="type" :label="type" :value="type")
|
||||
br
|
||||
span.sub-header {{ $t('view.settings.advanced.photon.timeout_hud.header') }}
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.advanced.photon.timeout_hud.enable') }}
|
||||
el-tooltip(placement="top" style="margin-left:5px" :content="$t('view.settings.advanced.photon.timeout_hud.enable_tooltip')")
|
||||
i.el-icon-warning
|
||||
el-switch(v-model="timeoutHudOverlay" @change="saveEventOverlay" :disabled="!openVR")
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.advanced.photon.timeout_hud.filter') }}
|
||||
el-radio-group(v-model="timeoutHudOverlayFilter" @change="saveEventOverlay" size="mini" :disabled="!openVR || !timeoutHudOverlay")
|
||||
el-radio-button(label="VIP") {{ $t('view.settings.advanced.photon.timeout_hud.filter_favorites') }}
|
||||
el-radio-button(label="Friends") {{ $t('view.settings.advanced.photon.timeout_hud.filter_friends') }}
|
||||
el-radio-button(label="Everyone") {{ $t('view.settings.advanced.photon.timeout_hud.filter_everyone') }}
|
||||
div.options-container-item
|
||||
el-button(size="small" icon="el-icon-time" @click="promptPhotonLobbyTimeoutThreshold" :disabled="!openVR") {{ $t('view.settings.advanced.photon.timeout_hud.timeout_threshold') }}
|
||||
//- Advanced | VRCX Instance Cache/Debug
|
||||
div.options-container
|
||||
span.header {{ $t('view.settings.advanced.advanced.cache_debug.header') }}
|
||||
br
|
||||
span.sub-header {{ $t('view.settings.advanced.advanced.pending_offline.header') }}
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.advanced.advanced.pending_offline.description') }}
|
||||
el-button-group(style="display:block")
|
||||
el-button(size="small" icon="el-icon-s-operation" @click="promptSetPendingOffline") {{ $t('view.settings.advanced.advanced.pending_offline.set_delay') }}
|
||||
+simpleSwitch("view.settings.advanced.advanced.cache_debug.udon_exception_logging", "udonExceptionLogging", "saveOpenVROption")
|
||||
+simpleSwitch("view.settings.advanced.advanced.cache_debug.gpu_fix", "gpuFix", "saveVRCXWindowOption")
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.advanced.advanced.cache_debug.disable_gamelog') }}
|
||||
el-switch(v-model="gameLogDisabled" @change="disableGameLogDialog")
|
||||
span.name(style="margin-left:15px") {{ $t('view.settings.advanced.advanced.cache_debug.disable_gamelog_notice') }}
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.advanced.advanced.cache_debug.user_cache') }} #[span(v-text="API.cachedUsers.size")]
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.advanced.advanced.cache_debug.world_cache') }} #[span(v-text="API.cachedWorlds.size")]
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.advanced.advanced.cache_debug.avatar_cache') }} #[span(v-text="API.cachedAvatars.size")]
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.advanced.advanced.cache_debug.group_cache') }} #[span(v-text="API.cachedGroups.size")]
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.advanced.advanced.cache_debug.avatar_name_cache') }} #[span(v-text="API.cachedAvatarNames.size")]
|
||||
div.options-container-item
|
||||
el-button(size="small" icon="el-icon-delete-solid" @click="clearVRCXCache") {{ $t('view.settings.advanced.advanced.cache_debug.clear_cache') }}
|
||||
el-button(size="small" icon="el-icon-time" @click="promptAutoClearVRCXCacheFrequency") {{ $t('view.settings.advanced.advanced.cache_debug.auto_clear_cache') }}
|
||||
div.options-container-item
|
||||
el-button(size="small" icon="el-icon-download" @click="showDownloadDialog") {{ $t('view.settings.advanced.advanced.cache_debug.download_history') }}
|
||||
el-button(size="small" icon="el-icon-tickets" @click="showConsole") {{ $t('view.settings.advanced.advanced.cache_debug.show_console') }}
|
||||
//- Advanced | VRCX Table Stats
|
||||
div.options-container
|
||||
span.sub-header {{ $t('view.settings.advanced.advanced.sqlite_table_size.header') }}
|
||||
div.options-container-item
|
||||
el-button(size="small" icon="el-icon-refresh" @click="getSqliteTableSizes") {{ $t('view.settings.advanced.advanced.sqlite_table_size.refresh') }}
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.advanced.advanced.sqlite_table_size.gps') }} #[span(v-text="sqliteTableSizes.gps")]
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.advanced.advanced.sqlite_table_size.status') }} #[span(v-text="sqliteTableSizes.status")]
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.advanced.advanced.sqlite_table_size.bio') }} #[span(v-text="sqliteTableSizes.bio")]
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.advanced.advanced.sqlite_table_size.avatar') }} #[span(v-text="sqliteTableSizes.avatar")]
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.advanced.advanced.sqlite_table_size.online_offline') }} #[span(v-text="sqliteTableSizes.onlineOffline")]
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.advanced.advanced.sqlite_table_size.friend_log_history') }} #[span(v-text="sqliteTableSizes.friendLogHistory")]
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.advanced.advanced.sqlite_table_size.notification') }} #[span(v-text="sqliteTableSizes.notification")]
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.advanced.advanced.sqlite_table_size.location') }} #[span(v-text="sqliteTableSizes.location")]
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.advanced.advanced.sqlite_table_size.join_leave') }} #[span(v-text="sqliteTableSizes.joinLeave")]
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.advanced.advanced.sqlite_table_size.portal_spawn') }} #[span(v-text="sqliteTableSizes.portalSpawn")]
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.advanced.advanced.sqlite_table_size.video_play') }} #[span(v-text="sqliteTableSizes.videoPlay")]
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.advanced.advanced.sqlite_table_size.event') }} #[span(v-text="sqliteTableSizes.event")]
|
||||
Reference in New Issue
Block a user