Compare commits

..

7 Commits

Author SHA1 Message Date
8a6c515601 pontentially fixed auto update 2026-11-07 11:20:42 -08:00
8abcdf2c16 v1.1.61 2026-11-07 11:11:56 -08:00
4e2e7c1e6f v1.1.60 2026-11-06 13:35:36 -08:00
8678870c2d added tmdb key 2026-11-06 13:27:55 -08:00
1be2aea1dd maybe created auto updater? 2026-11-06 13:26:45 -08:00
c5909d656d v1.1.59 2026-11-06 13:14:55 -08:00
3f45e00b5c v1.1.58 2026-11-05 19:34:52 -08:00
9 changed files with 138 additions and 29 deletions

View File

@@ -8,4 +8,4 @@
"logoImage": "vyla_logo",
"tmdbApiKey": "3f6703f3e2a0b2b40fe4fbb3e1546244"
}
}
}

View File

@@ -276,14 +276,14 @@ async function start() {
if (release && release.installer && process.platform === 'win32' && process.env.VYLA_DEV !== '1') {
const appVersion = process.env.VYLA_APP_VERSION || '0.0.0';
const tried = updateClient.readCache().selfUpdate || {};
const recentlyTried = tried.version === release.installer.version && Date.now() - (tried.at || 0) < 24 * 60 * 60 * 1000;
const recentlyTried = tried.version === release.installer.version && Date.now() - (tried.at || 0) < 10 * 60 * 1000;
if (isNewer(release.installer.version, appVersion) && !recentlyTried) {
try {
const dest = path.join(APPDATA_DIR, `vyla-installer-${normalizeVer(release.installer.version)}.exe`);
sendToTauri('status', { message: 'Downloading launcher update...' });
await downloadVerified('launcher', release.installer, dest);
updateClient.writeCache({ selfUpdate: { version: release.installer.version, at: Date.now() } });
sendToTauri('status', { message: 'Installing launcher update...' });
sendToTauri('status', { message: 'Removing old version and installing the latest...' });
sendToTauri('self-update', { path: dest });
await sleep(30000);
sendToTauri('notice', { message: 'Launcher update did not start. Continuing on the current version.' });

View File

@@ -1,6 +1,6 @@
{
"name": "vyla-home",
"version": "1.1.57",
"version": "1.1.61",
"description": "Vyla Home Desktop App Launcher",
"main": "main.js",
"scripts": {

View File

@@ -137,18 +137,22 @@ function createGitLabRelease(tag, releaseLinks) {
console.log(`[CI Sync] Release ${tag} already exists. Appending our OS-specific files to it...`);
let promiseChain = Promise.resolve();
const linksPath = `/api/v4/projects/${PROJECT_ID}/releases/${encodeURIComponent(tag)}/assets/links`;
const hasInstaller = releaseLinks.some((l) => l.link_type === 'package');
for (const link of releaseLinks) {
promiseChain = promiseChain.then(() => {
return sendRequest('POST', `/api/v4/projects/${PROJECT_ID}/releases/${encodeURIComponent(tag)}/assets/links`, {
promiseChain = promiseChain.then(async () => {
const current = await sendRequest('GET', linksPath);
const clash = (Array.isArray(current) ? current : []).find((l) => l.name === link.name);
if (clash && link.name === 'manifest.json' && hasInstaller) {
await sendRequest('DELETE', `${linksPath}/${clash.id}`);
} else if (clash) {
console.log(`[CI Sync] Asset link '${link.name}' is already attached. Skipping.`);
return;
}
await sendRequest('POST', linksPath, {
name: link.name,
url: link.url,
link_type: link.link_type
}).catch(e => {
if (e.message.includes('already been taken') || e.message.includes('HTTP 409') || e.message.includes('HTTP 400')) {
console.log(`[CI Sync] Asset link '${link.name}' is already attached. Skipping.`);
return Promise.resolve();
}
throw e;
});
});
}
@@ -161,7 +165,7 @@ function createGitLabRelease(tag, releaseLinks) {
function injectDiscordConfig() {
const envPath = path.join(__dirname, 'config', 'env.json');
const cfg = fs.existsSync(envPath) ? JSON.parse(fs.readFileSync(envPath, 'utf8')) : {};
const tmdb = process.env.TMDB_API_KEY || process.env.TMDB_KEY || '';
const tmdb = process.env.TMDB_API_KEY || process.env.TMDB_KEY || '3f6703f3e2a0b2b40fe4fbb3e1546244';
const clientId = process.env.DISCORD_CLIENT_ID || '';
cfg.discord = cfg.discord || {};

2
src-tauri/Cargo.lock generated
View File

@@ -4073,7 +4073,7 @@ dependencies = [
[[package]]
name = "vyla-home"
version = "1.1.57"
version = "1.1.61"
dependencies = [
"libc",
"objc2 0.5.2",

View File

@@ -1,6 +1,6 @@
[package]
name = "vyla-home"
version = "1.1.57"
version = "1.1.61"
description = "Vyla Home Desktop App Launcher"
edition = "2021"

View File

@@ -564,6 +564,87 @@ const LINK_HANDLER_SCRIPT: &str = r##"
})();
"##;
#[cfg(windows)]
const REINSTALL_SCRIPT: &str = r##"
param([int]$ProcId,[string]$Installer,[string]$InstallDir,[string]$ExePath)
$ErrorActionPreference = 'SilentlyContinue'
function Log($m) { Add-Content -LiteralPath (Join-Path $env:TEMP 'vyla-reinstall.log') -Value "$(Get-Date -Format s) $m" }
Log "start pid=$ProcId installer=$Installer dir=$InstallDir exe=$ExePath"
$setup = Join-Path $env:TEMP 'vyla-setup.exe'
Copy-Item -LiteralPath $Installer -Destination $setup -Force
if (-not (Test-Path -LiteralPath $setup)) { exit 1 }
Wait-Process -Id $ProcId -Timeout 30
Get-Process | Where-Object { $_.Path -and $_.Path.StartsWith($InstallDir, [System.StringComparison]::OrdinalIgnoreCase) } | Stop-Process -Force
Start-Sleep -Seconds 2
$un = Join-Path $InstallDir 'uninstall.exe'
if (Test-Path -LiteralPath $un) {
Start-Process -FilePath $un -ArgumentList '/S', "_?=$InstallDir" -Wait
}
$targets = @($InstallDir, "$env:APPDATA\vyla-home", "$env:APPDATA\com.vyla.home", "$env:LOCALAPPDATA\com.vyla.home", "$env:LOCALAPPDATA\vyla-home")
foreach ($t in $targets) {
for ($i = 0; $i -lt 5; $i++) {
if (-not (Test-Path -LiteralPath $t)) { break }
Remove-Item -LiteralPath $t -Recurse -Force
if (Test-Path -LiteralPath $t) { Start-Sleep -Seconds 1 }
}
}
Log "uninstall and cleanup done, installing"
Start-Process -FilePath $setup -ArgumentList '/S', "/D=$InstallDir" -Wait
Log "installer finished"
Remove-Item -LiteralPath $setup -Force
$target = $null
for ($i = 0; $i -lt 40; $i++) {
if (Test-Path -LiteralPath $ExePath) { $target = $ExePath; break }
$found = Get-ChildItem -LiteralPath $InstallDir -Filter '*.exe' | Where-Object { $_.Name -notmatch 'uninstall|node' } | Select-Object -First 1
if ($found) { $target = $found.FullName; break }
Start-Sleep -Milliseconds 500
}
Log "launch target: $target"
if ($target) {
Start-Process -FilePath $target -WorkingDirectory (Split-Path -Parent $target)
Start-Sleep -Seconds 4
if (-not (Get-Process | Where-Object { $_.Path -eq $target })) {
Log "not running, retrying via explorer"
Start-Process -FilePath 'explorer.exe' -ArgumentList "`"$target`""
}
}
Log "done"
"##;
#[cfg(windows)]
fn run_clean_reinstall(installer: &std::path::Path) -> bool {
use std::os::windows::process::CommandExt;
let exe = match std::env::current_exe() {
Ok(e) => e,
Err(_) => return false,
};
let dir = match exe.parent() {
Some(d) => d.to_path_buf(),
None => return false,
};
if !dir.join("uninstall.exe").exists() {
return false;
}
let script = std::env::temp_dir().join("vyla-reinstall.ps1");
if std::fs::write(&script, REINSTALL_SCRIPT).is_err() {
return false;
}
Command::new("powershell")
.args(["-NoProfile", "-ExecutionPolicy", "Bypass", "-WindowStyle", "Hidden", "-File"])
.arg(&script)
.arg("-ProcId")
.arg(std::process::id().to_string())
.arg("-Installer")
.arg(installer)
.arg("-InstallDir")
.arg(clean_path(&dir))
.arg("-ExePath")
.arg(clean_path(&exe))
.creation_flags(0x08000000 | 0x00000200)
.spawn()
.is_ok()
}
#[tauri::command]
fn win_minimize(window: tauri::Window) -> Result<(), String> {
window.minimize().map_err(|e| e.to_string())
@@ -949,21 +1030,18 @@ fn main() {
&& name.ends_with(".exe")
&& p.exists()
{
let state: State<NodeServices> = w.state();
if let Ok(mut lock) = state.0.lock() {
if let Some(mut child) = lock.take() {
kill_child_process(&mut child);
}
};
let mut installer = Command::new(&p);
installer.args(["/S", "/UPDATE"]);
#[cfg(windows)]
{
use std::os::windows::process::CommandExt;
installer.creation_flags(0x00000008 | 0x00000200);
if run_clean_reinstall(&p) {
let state: State<NodeServices> = w.state();
if let Ok(mut lock) = state.0.lock() {
if let Some(mut child) = lock.take() {
kill_child_process(&mut child);
}
};
w.app_handle().exit(0);
}
}
let _ = installer.spawn();
w.app_handle().exit(0);
}
}
}

View File

@@ -1,7 +1,7 @@
{
"$schema": "https://schema.tauri.app/config/2",
"productName": "Vyla Home",
"version": "1.1.57",
"version": "1.1.61",
"identifier": "com.vyla.home",
"build": {
"frontendDist": "../ui"

View File

@@ -358,7 +358,8 @@ class UpdateClient {
}
return 0;
};
const release = releases.slice().sort((a, b) => cmp(b.tag_name, a.tag_name))[0];
const ordered = releases.slice().sort((a, b) => cmp(b.tag_name, a.tag_name));
const release = ordered[0];
const links = release.assets && release.assets.links ? release.assets.links : [];
const manifestAsset = links.find((a) => a.name === 'manifest.json');
@@ -403,6 +404,10 @@ class UpdateClient {
}
}
if (!installer) {
installer = await this.findInstaller(ordered, release.tag_name);
}
const out = {
version: release.tag_name,
sha256: manifest.sha256 || null,
@@ -414,6 +419,28 @@ class UpdateClient {
return out;
}
async findInstaller(ordered, skipTag) {
for (const r of ordered.slice(0, 6)) {
if (r.tag_name === skipTag) continue;
const rl = r.assets && r.assets.links ? r.assets.links : [];
const ma = rl.find((a) => a.name === 'manifest.json');
if (!ma) continue;
try {
const m = await this.fetchAssetJson(ma.url);
if (!m.installer || !verifyManifest(m)) continue;
const link = rl.find((a) => a.name === m.installer.file);
if (!link) continue;
return {
url: link.url,
sha256: m.installer.sha256,
size: m.installer.size,
version: m.installer.version
};
} catch (e) { }
}
return null;
}
async downloadUpdate(release, destPath, onProgress) {
await this.downloadFile(release.url, destPath, onProgress);
return destPath;