Electron support for Linux (#1074)

* init

* SQLite changes

* Move html folder, edit build scripts

* AppApi interface

* Build flags

* AppApi inheritance

* Finishing touches

* Merge upstream changes

* Test CI

* Fix class inits

* Rename AppApi

* Merge upstream changes

* Fix SQLiteLegacy on Linux, Add Linux interop, build tools

* Linux specific localisation strings

* Make it run

* Bring back most of Linux functionality

* Clean up

* Fix TTS voices

* Fix UI var

* Changes

* Electron minimise to tray

* Remove separate toggle for WlxOverlay

* Fixes

* Touchups

* Move csproj

* Window zoom, Desktop Notifications, VR check on Linux

* Fix desktop notifications, VR check spam

* Fix building on Linux

* Clean up

* Fix WebApi headers

* Rewrite VRCX updater

* Clean up

* Linux updater

* Add Linux to build action

* init

* SQLite changes

* Move html folder, edit build scripts

* AppApi interface

* Build flags

* AppApi inheritance

* Finishing touches

* Merge upstream changes

* Test CI

* Fix class inits

* Rename AppApi

* Merge upstream changes

* Fix SQLiteLegacy on Linux, Add Linux interop, build tools

* Linux specific localisation strings

* Make it run

* Bring back most of Linux functionality

* Clean up

* Fix TTS voices

* Changes

* Electron minimise to tray

* Remove separate toggle for WlxOverlay

* Fixes

* Touchups

* Move csproj

* Window zoom, Desktop Notifications, VR check on Linux

* Fix desktop notifications, VR check spam

* Fix building on Linux

* Clean up

* Fix WebApi headers

* Rewrite VRCX updater

* Clean up

* Linux updater

* Add Linux to build action

* Test updater

* Rebase and handle merge conflicts

* Fix Linux updater

* Fix Linux app restart

* Fix friend order

* Handle AppImageInstaller, show an install message on Linux

* Updates to the AppImage installer

* Fix Linux updater, fix set version, check for .NET, copy wine prefix

* Handle random errors

* Rotate tall prints

* try fix Linux restart bug

* Final

---------

Co-authored-by: rs189 <35667100+rs189@users.noreply.github.com>
This commit is contained in:
Natsumi
2025-01-11 13:09:44 +13:00
committed by GitHub
parent a39eb9d5ed
commit 938fff63d0
223 changed files with 15841 additions and 9562 deletions

80
src/repository/config.js Normal file
View File

@@ -0,0 +1,80 @@
import sqliteService from '../service/sqlite.js';
import sharedRepository, { SharedRepository } from './shared.js';
import * as workerTimers from 'worker-timers';
var dirtyKeySet = new Set();
function transformKey(key) {
return `config:${String(key).toLowerCase()}`;
}
async function syncLoop() {
if (dirtyKeySet.size > 0) {
try {
await sqliteService.executeNonQuery('BEGIN');
try {
for (var key of dirtyKeySet) {
var value = await sharedRepository.getString(key);
if (value === null) {
await sqliteService.executeNonQuery(
'DELETE FROM configs WHERE `key` = @key',
{
'@key': key
}
);
} else {
await sqliteService.executeNonQuery(
'INSERT OR REPLACE INTO configs (`key`, `value`) VALUES (@key, @value)',
{
'@key': key,
'@value': value
}
);
}
}
dirtyKeySet.clear();
} finally {
await sqliteService.executeNonQuery('COMMIT');
}
} catch (err) {
console.error(err);
}
}
workerTimers.setTimeout(() => syncLoop(), 100);
}
class ConfigRepository extends SharedRepository {
async init() {
await sqliteService.executeNonQuery(
'CREATE TABLE IF NOT EXISTS configs (`key` TEXT PRIMARY KEY, `value` TEXT)'
);
await sqliteService.execute(
([key, value]) => sharedRepository.setString(key, value),
'SELECT `key`, `value` FROM configs'
);
syncLoop();
}
async remove(key) {
var _key = transformKey(key);
await sharedRepository.remove(_key);
dirtyKeySet.add(_key);
}
getString(key, defaultValue = null) {
var _key = transformKey(key);
return sharedRepository.getString(_key, defaultValue);
}
async setString(key, value) {
var _key = transformKey(key);
var _value = String(value);
await sharedRepository.setString(_key, _value);
dirtyKeySet.add(_key);
}
}
var self = new ConfigRepository();
window.configRepository = self;
export { self as default, ConfigRepository };

2731
src/repository/database.js Normal file

File diff suppressed because it is too large Load Diff

106
src/repository/shared.js Normal file
View File

@@ -0,0 +1,106 @@
// requires binding of SharedVariable
function transformKey(key) {
return String(key).toLowerCase();
}
class SharedRepository {
remove(key) {
var _key = transformKey(key);
return SharedVariable.Remove(_key);
}
async getString(key, defaultValue = null) {
var _key = transformKey(key);
var value = await SharedVariable.Get(_key);
if (value === null || value === undefined) {
return defaultValue;
}
return value;
}
async setString(key, value) {
var _key = transformKey(key);
var _value = String(value);
await SharedVariable.Set(_key, _value);
}
async getBool(key, defaultValue = null) {
var value = await this.getString(key, null);
if (value === null || value === undefined) {
return defaultValue;
}
return value === 'true';
}
async setBool(key, value) {
await this.setString(key, value ? 'true' : 'false');
}
async getInt(key, defaultValue = null) {
var value = await this.getString(key, null);
if (value === null || value === undefined) {
return defaultValue;
}
value = parseInt(value, 10);
if (isNaN(value) === true) {
return defaultValue;
}
return value;
}
async setInt(key, value) {
await this.setString(key, value);
}
async getFloat(key, defaultValue = null) {
var value = await this.getString(key, null);
if (value === null || value === undefined) {
return defaultValue;
}
value = parseFloat(value);
if (isNaN(value) === true) {
return defaultValue;
}
return value;
}
async setFloat(key, value) {
await this.setString(key, value);
}
async getObject(key, defaultValue = null) {
var value = await this.getString(key, null);
if (value === null || value === undefined) {
return defaultValue;
}
try {
value = JSON.parse(value);
} catch (err) {}
if (value !== Object(value)) {
return defaultValue;
}
return value;
}
async setObject(key, value) {
await this.setString(key, JSON.stringify(value));
}
async getArray(key, defaultValue = null) {
var value = await this.getObject(key, null);
if (Array.isArray(value) === false) {
return defaultValue;
}
return value;
}
async setArray(key, value) {
await this.setObject(key, value);
}
}
var self = new SharedRepository();
window.sharedRepository = self;
export { self as default, SharedRepository };