mirror of
https://gitlab.com/vyla-entertainment/home.git
synced 2026-11-14 22:27:20 -05:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8a333d6770 | |||
| 9c4d250640 | |||
| 03ed2f0e53 | |||
| 47c97fdf21 | |||
| e7204589a4 |
@@ -17,13 +17,14 @@ class CryptoUtils {
|
|||||||
|
|
||||||
let key;
|
let key;
|
||||||
try {
|
try {
|
||||||
|
const isMac = os.platform() === 'darwin';
|
||||||
const machineId = [
|
const machineId = [
|
||||||
os.hostname(),
|
isMac ? '' : os.hostname(),
|
||||||
os.platform(),
|
os.platform(),
|
||||||
os.arch(),
|
os.arch(),
|
||||||
os.cpus()[0] ? os.cpus()[0].model : '',
|
os.cpus()[0] ? os.cpus()[0].model : '',
|
||||||
process.env.COMPUTERNAME || '',
|
process.env.COMPUTERNAME || '',
|
||||||
process.env.USERNAME || ''
|
process.env.USERNAME || (isMac ? os.userInfo().username : '')
|
||||||
].join('|');
|
].join('|');
|
||||||
|
|
||||||
const hash = crypto.createHash('sha256');
|
const hash = crypto.createHash('sha256');
|
||||||
|
|||||||
3
main.js
3
main.js
@@ -459,5 +459,8 @@ process.on('SIGINT', () => {
|
|||||||
process.on('SIGTERM', () => {
|
process.on('SIGTERM', () => {
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
});
|
});
|
||||||
|
process.on('SIGHUP', () => {
|
||||||
|
process.exit(0);
|
||||||
|
});
|
||||||
|
|
||||||
start();
|
start();
|
||||||
|
|||||||
7
package-lock.json
generated
7
package-lock.json
generated
@@ -1,19 +1,18 @@
|
|||||||
{
|
{
|
||||||
"name": "vyla-home",
|
"name": "vyla-home",
|
||||||
"version": "1.1.49",
|
"version": "1.1.56",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "vyla-home",
|
"name": "vyla-home",
|
||||||
"version": "1.1.49",
|
"version": "1.1.56",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tauri-apps/api": "2.12.1",
|
"@tauri-apps/api": "2.12.1",
|
||||||
"@tauri-apps/plugin-opener": "2.7.0",
|
"@tauri-apps/plugin-opener": "2.7.0",
|
||||||
"@tauri-apps/plugin-process": "2.4.0",
|
"@tauri-apps/plugin-process": "2.4.0",
|
||||||
"@tauri-apps/plugin-updater": "^2",
|
|
||||||
"@tauri-apps/plugin-shell": "2.5.0",
|
"@tauri-apps/plugin-shell": "2.5.0",
|
||||||
"@vyla-entertainment/sdk": "^1.20.0",
|
"@vyla-entertainment/sdk": "latest",
|
||||||
"adm-zip": "^0.6.1",
|
"adm-zip": "^0.6.1",
|
||||||
"express": "^4.22.3"
|
"express": "^4.22.3"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "vyla-home",
|
"name": "vyla-home",
|
||||||
"version": "1.1.55",
|
"version": "1.1.56",
|
||||||
"description": "Vyla Home Desktop App Launcher",
|
"description": "Vyla Home Desktop App Launcher",
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
21
release.js
21
release.js
@@ -243,6 +243,20 @@ async function main() {
|
|||||||
console.log('Uploading update-payload.zip...');
|
console.log('Uploading update-payload.zip...');
|
||||||
const payloadUrl = await uploadFileToGitLabPackage(payloadPath, 'vyla-home', version, `update-payload-${timestamp}.zip`);
|
const payloadUrl = await uploadFileToGitLabPackage(payloadPath, 'vyla-home', version, `update-payload-${timestamp}.zip`);
|
||||||
|
|
||||||
|
const manifestData = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
|
||||||
|
for (const [name, c] of Object.entries(manifestData.components || {})) {
|
||||||
|
console.log(`Uploading ${c.file}...`);
|
||||||
|
c.url = await uploadFileToGitLabPackage(path.join(__dirname, 'release-assets', c.file), 'vyla-home', version, `${name}-${timestamp}.zip`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const signingKeyPem = process.env.VYLA_UPDATE_SIGNING_KEY;
|
||||||
|
if (!signingKeyPem) {
|
||||||
|
throw new Error('VYLA_UPDATE_SIGNING_KEY is required to sign the update manifest.');
|
||||||
|
}
|
||||||
|
delete manifestData.signature;
|
||||||
|
manifestData.signature = crypto.sign(null, Buffer.from(UpdateClient.canonicalManifest(manifestData)), signingKeyPem.replace(/\\n/g, '\n')).toString('base64');
|
||||||
|
fs.writeFileSync(manifestPath, JSON.stringify(manifestData, null, 2), 'utf8');
|
||||||
|
|
||||||
console.log('Uploading manifest.json...');
|
console.log('Uploading manifest.json...');
|
||||||
const manifestUrl = await uploadFileToGitLabPackage(manifestPath, 'vyla-home', version, `manifest-${timestamp}.json`);
|
const manifestUrl = await uploadFileToGitLabPackage(manifestPath, 'vyla-home', version, `manifest-${timestamp}.json`);
|
||||||
|
|
||||||
@@ -251,13 +265,6 @@ async function main() {
|
|||||||
{ name: 'manifest.json', url: manifestUrl, link_type: 'other' }
|
{ name: 'manifest.json', url: manifestUrl, link_type: 'other' }
|
||||||
];
|
];
|
||||||
|
|
||||||
const manifestData = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
|
|
||||||
for (const [name, c] of Object.entries(manifestData.components || {})) {
|
|
||||||
console.log(`Uploading ${c.file}...`);
|
|
||||||
const componentUrl = await uploadFileToGitLabPackage(path.join(__dirname, 'release-assets', c.file), 'vyla-home', version, `${name}-${timestamp}.zip`);
|
|
||||||
releaseLinks.push({ name: c.file, url: componentUrl, link_type: 'other' });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (installerPath && installerUploadName) {
|
if (installerPath && installerUploadName) {
|
||||||
console.log(`Uploading installer ${installerUploadName}...`);
|
console.log(`Uploading installer ${installerUploadName}...`);
|
||||||
const ext = path.extname(installerUploadName);
|
const ext = path.extname(installerUploadName);
|
||||||
|
|||||||
@@ -54,6 +54,9 @@ class ServiceManager {
|
|||||||
|
|
||||||
const env = {
|
const env = {
|
||||||
...process.env,
|
...process.env,
|
||||||
|
...(process.platform === 'darwin'
|
||||||
|
? { PATH: [process.env.PATH, '/opt/homebrew/bin', '/usr/local/bin', '/usr/bin', '/bin'].filter(Boolean).join(path.delimiter) }
|
||||||
|
: {}),
|
||||||
PORT: (this.envConfig[name] && this.envConfig[name].PORT) || defaultPorts[name] || process.env.PORT || 3000,
|
PORT: (this.envConfig[name] && this.envConfig[name].PORT) || defaultPorts[name] || process.env.PORT || 3000,
|
||||||
TOKEN_SECRET: tokenSecret,
|
TOKEN_SECRET: tokenSecret,
|
||||||
...(this.envConfig[name] || {}),
|
...(this.envConfig[name] || {}),
|
||||||
|
|||||||
3
src-tauri/Cargo.lock
generated
3
src-tauri/Cargo.lock
generated
@@ -4073,8 +4073,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vyla-home"
|
name = "vyla-home"
|
||||||
version = "1.1.55"
|
version = "1.1.56"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"libc",
|
||||||
"objc2 0.5.2",
|
"objc2 0.5.2",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "vyla-home"
|
name = "vyla-home"
|
||||||
version = "1.1.55"
|
version = "1.1.56"
|
||||||
description = "Vyla Home Desktop App Launcher"
|
description = "Vyla Home Desktop App Launcher"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
@@ -17,6 +17,9 @@ window-vibrancy = "0.8"
|
|||||||
[target.'cfg(target_os = "macos")'.dependencies]
|
[target.'cfg(target_os = "macos")'.dependencies]
|
||||||
objc2 = "0.5"
|
objc2 = "0.5"
|
||||||
|
|
||||||
|
[target.'cfg(unix)'.dependencies]
|
||||||
|
libc = "0.2"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
opt-level = 3
|
opt-level = 3
|
||||||
lto = true
|
lto = true
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
<true/>
|
<true/>
|
||||||
<key>NSAllowsArbitraryLoads</key>
|
<key>NSAllowsArbitraryLoads</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
<key>NSAllowsArbitraryLoadsInWebContent</key>
|
||||||
|
<true/>
|
||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
@@ -44,6 +44,8 @@ static WINDOW_COUNTER: std::sync::atomic::AtomicUsize = std::sync::atomic::Atomi
|
|||||||
|
|
||||||
static READY_URL: Mutex<Option<String>> = Mutex::new(None);
|
static READY_URL: Mutex<Option<String>> = Mutex::new(None);
|
||||||
|
|
||||||
|
static APP_LOADED: std::sync::atomic::AtomicBool = std::sync::atomic::AtomicBool::new(false);
|
||||||
|
|
||||||
fn js_log(app: &AppHandle, msg: &str) {
|
fn js_log(app: &AppHandle, msg: &str) {
|
||||||
debug_log(msg);
|
debug_log(msg);
|
||||||
if let Some(w) = app.get_webview_window("main") {
|
if let Some(w) = app.get_webview_window("main") {
|
||||||
@@ -94,6 +96,17 @@ fn kill_child_process(child: &mut Child) {
|
|||||||
.creation_flags(CREATE_NO_WINDOW)
|
.creation_flags(CREATE_NO_WINDOW)
|
||||||
.output();
|
.output();
|
||||||
}
|
}
|
||||||
|
#[cfg(unix)]
|
||||||
|
{
|
||||||
|
let pgid = child.id() as i32;
|
||||||
|
unsafe {
|
||||||
|
libc::killpg(pgid, libc::SIGTERM);
|
||||||
|
}
|
||||||
|
std::thread::sleep(std::time::Duration::from_millis(400));
|
||||||
|
unsafe {
|
||||||
|
libc::killpg(pgid, libc::SIGKILL);
|
||||||
|
}
|
||||||
|
}
|
||||||
let _ = child.kill();
|
let _ = child.kill();
|
||||||
let _ = child.wait();
|
let _ = child.wait();
|
||||||
}
|
}
|
||||||
@@ -580,7 +593,7 @@ fn open_new_window(app: AppHandle, url: String) -> Result<(), String> {
|
|||||||
|
|
||||||
fn handle_ready(w: &tauri::WebviewWindow, msg: &BackendMessage) {
|
fn handle_ready(w: &tauri::WebviewWindow, msg: &BackendMessage) {
|
||||||
let url_str = match msg.data.get("url").and_then(|u| u.as_str()) {
|
let url_str = match msg.data.get("url").and_then(|u| u.as_str()) {
|
||||||
Some(u) => u,
|
Some(u) => u.to_string(),
|
||||||
None => return,
|
None => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -592,19 +605,36 @@ fn handle_ready(w: &tauri::WebviewWindow, msg: &BackendMessage) {
|
|||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
{
|
{
|
||||||
use objc2::msg_send;
|
use objc2::msg_send;
|
||||||
use objc2::runtime::AnyObject;
|
use objc2::runtime::{AnyObject, Sel};
|
||||||
debug_log("Attempting with_webview on ready event");
|
use objc2::sel;
|
||||||
let result = w.with_webview(|webview| unsafe {
|
let _ = w.with_webview(|webview| unsafe {
|
||||||
debug_log("Inside with_webview closure");
|
|
||||||
let wk_webview = webview.inner() as *mut AnyObject;
|
let wk_webview = webview.inner() as *mut AnyObject;
|
||||||
let config: *mut AnyObject = msg_send![wk_webview, configuration];
|
let config: *mut AnyObject = msg_send![wk_webview, configuration];
|
||||||
let _: () = msg_send![config, setUpgradeKnownHostsToHTTPS: false];
|
let selector: Sel = sel!(setUpgradeKnownHostsToHTTPS:);
|
||||||
debug_log("setUpgradeKnownHostsToHTTPS set to false");
|
let supported: bool = msg_send![config, respondsToSelector: selector];
|
||||||
|
if supported {
|
||||||
|
let _: () = msg_send![config, setUpgradeKnownHostsToHTTPS: false];
|
||||||
|
}
|
||||||
});
|
});
|
||||||
debug_log(&format!("with_webview result: {:?}", result));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = w.navigate(url_parsed);
|
APP_LOADED.store(false, std::sync::atomic::Ordering::SeqCst);
|
||||||
|
let _ = w.navigate(url_parsed.clone());
|
||||||
|
|
||||||
|
let watcher = w.clone();
|
||||||
|
std::thread::spawn(move || {
|
||||||
|
for attempt in 1..=8 {
|
||||||
|
std::thread::sleep(std::time::Duration::from_secs(4));
|
||||||
|
if APP_LOADED.load(std::sync::atomic::Ordering::SeqCst) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
debug_log(&format!("App page not loaded yet, retry {}", attempt));
|
||||||
|
let target = serde_json::to_string(&url_str).unwrap_or_default();
|
||||||
|
let _ = watcher.eval(&format!("window.location.replace({});", target));
|
||||||
|
let _ = watcher.navigate(url_parsed.clone());
|
||||||
|
}
|
||||||
|
debug_log("App page never loaded after retries");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
@@ -663,6 +693,9 @@ fn main() {
|
|||||||
.initialization_script("window.__VYLA_WINDOW_LABEL = 'main';")
|
.initialization_script("window.__VYLA_WINDOW_LABEL = 'main';")
|
||||||
.on_page_load(move |wv, payload| {
|
.on_page_load(move |wv, payload| {
|
||||||
if matches!(payload.event(), tauri::webview::PageLoadEvent::Finished) {
|
if matches!(payload.event(), tauri::webview::PageLoadEvent::Finished) {
|
||||||
|
if payload.url().host_str() == Some("127.0.0.1") {
|
||||||
|
APP_LOADED.store(true, std::sync::atomic::Ordering::SeqCst);
|
||||||
|
}
|
||||||
if payload.url().host_str() != Some("127.0.0.1") {
|
if payload.url().host_str() != Some("127.0.0.1") {
|
||||||
let known = READY_URL.lock().ok().and_then(|g| g.clone());
|
let known = READY_URL.lock().ok().and_then(|g| g.clone());
|
||||||
if let Some(u) = known {
|
if let Some(u) = known {
|
||||||
@@ -726,6 +759,16 @@ fn main() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
{
|
||||||
|
use std::os::unix::fs::PermissionsExt;
|
||||||
|
if let Ok(meta) = std::fs::metadata(&node_bin) {
|
||||||
|
let mut perms = meta.permissions();
|
||||||
|
perms.set_mode(0o755);
|
||||||
|
let _ = std::fs::set_permissions(&node_bin, perms);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let vyla_files_str = clean_path(&vyla_files);
|
let vyla_files_str = clean_path(&vyla_files);
|
||||||
|
|
||||||
let mut cmd = Command::new(&node_bin);
|
let mut cmd = Command::new(&node_bin);
|
||||||
@@ -746,6 +789,12 @@ fn main() {
|
|||||||
cmd.creation_flags(CREATE_NO_WINDOW);
|
cmd.creation_flags(CREATE_NO_WINDOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
{
|
||||||
|
use std::os::unix::process::CommandExt;
|
||||||
|
cmd.process_group(0);
|
||||||
|
}
|
||||||
|
|
||||||
match cmd.spawn() {
|
match cmd.spawn() {
|
||||||
Ok(mut child) => {
|
Ok(mut child) => {
|
||||||
debug_log(&format!(
|
debug_log(&format!(
|
||||||
@@ -878,6 +927,16 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.run(tauri::generate_context!())
|
.build(tauri::generate_context!())
|
||||||
.expect("error while running tauri application");
|
.expect("error while building tauri application")
|
||||||
|
.run(|app, event| {
|
||||||
|
if let tauri::RunEvent::Exit = event {
|
||||||
|
let state: State<NodeServices> = app.state();
|
||||||
|
if let Ok(mut lock) = state.0.lock() {
|
||||||
|
if let Some(mut child) = lock.take() {
|
||||||
|
kill_child_process(&mut child);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://schema.tauri.app/config/2",
|
"$schema": "https://schema.tauri.app/config/2",
|
||||||
"productName": "Vyla Home",
|
"productName": "Vyla Home",
|
||||||
"version": "1.1.55",
|
"version": "1.1.56",
|
||||||
"identifier": "com.vyla.home",
|
"identifier": "com.vyla.home",
|
||||||
"build": {
|
"build": {
|
||||||
"frontendDist": "../ui"
|
"frontendDist": "../ui"
|
||||||
|
|||||||
@@ -380,10 +380,14 @@ class UpdateClient {
|
|||||||
const components = {};
|
const components = {};
|
||||||
for (const [name, c] of Object.entries(manifest.components)) {
|
for (const [name, c] of Object.entries(manifest.components)) {
|
||||||
const link = links.find((a) => a.name === c.file);
|
const link = links.find((a) => a.name === c.file);
|
||||||
if (!link) {
|
const direct = typeof c.url === 'string' &&
|
||||||
|
c.url.startsWith('https://gitlab.com/api/v4/projects/') &&
|
||||||
|
c.url.includes('/packages/generic/vyla-home/');
|
||||||
|
const url = direct ? c.url : (link && link.url);
|
||||||
|
if (!url) {
|
||||||
throw new Error(`Release is missing asset ${c.file}.`);
|
throw new Error(`Release is missing asset ${c.file}.`);
|
||||||
}
|
}
|
||||||
components[name] = { url: link.url, sha256: c.sha256, id: c.id, size: c.size };
|
components[name] = { url, sha256: c.sha256, id: c.id, size: c.size };
|
||||||
}
|
}
|
||||||
|
|
||||||
let installer = null;
|
let installer = null;
|
||||||
|
|||||||
Reference in New Issue
Block a user