mirror of
https://gitlab.com/vyla-entertainment/home.git
synced 2026-11-13 13:47:21 -05:00
fixed UI issue
This commit is contained in:
196
main.js
196
main.js
@@ -113,55 +113,6 @@ function portInUse(port) {
|
||||
});
|
||||
}
|
||||
|
||||
function promptUser(event, payload, timeoutMs = 120000) {
|
||||
return new Promise((resolve) => {
|
||||
const token = require('crypto').randomBytes(24).toString('hex');
|
||||
const app = express();
|
||||
let server = null;
|
||||
let finished = false;
|
||||
let timer = null;
|
||||
|
||||
const finish = (result) => {
|
||||
if (finished) return;
|
||||
finished = true;
|
||||
clearTimeout(timer);
|
||||
if (server) server.close();
|
||||
resolve(result);
|
||||
};
|
||||
|
||||
timer = setTimeout(() => finish(null), timeoutMs);
|
||||
|
||||
app.use((req, res, next) => {
|
||||
const ip = req.socket.remoteAddress;
|
||||
if (ip !== '127.0.0.1' && ip !== '::1' && ip !== '::ffff:127.0.0.1') {
|
||||
return res.status(403).end();
|
||||
}
|
||||
res.header('Access-Control-Allow-Origin', '*');
|
||||
res.header('Access-Control-Allow-Methods', 'POST,OPTIONS');
|
||||
res.header('Access-Control-Allow-Headers', 'Content-Type');
|
||||
if (req.method === 'OPTIONS') return res.sendStatus(200);
|
||||
next();
|
||||
});
|
||||
|
||||
app.post('/prompt/answer', express.json({ limit: '64kb' }), (req, res) => {
|
||||
const body = req.body || {};
|
||||
if (body.token !== token) return res.status(403).end();
|
||||
res.sendStatus(200);
|
||||
finish({
|
||||
accept: body.accept === true,
|
||||
files: Array.isArray(body.files) ? body.files.map(String) : []
|
||||
});
|
||||
});
|
||||
|
||||
server = app.listen(4891, '127.0.0.1', () => {
|
||||
sendToTauri(event, { ...payload, token });
|
||||
});
|
||||
server.on('error', (err) => {
|
||||
debugLog(`Prompt server bind error: ${err.message}`);
|
||||
finish(null);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function start() {
|
||||
debugLog("Inside start() function");
|
||||
@@ -298,79 +249,9 @@ async function start() {
|
||||
sendToTauri('status', { message: 'First run detected. Preparing initial installation...' });
|
||||
await installBuild(release);
|
||||
} else if (hasUpdate) {
|
||||
debugLog("Update available. Prompting user...");
|
||||
sendToTauri('status', { message: `New update available (${release.version}).` });
|
||||
|
||||
const tempApp = express();
|
||||
let userDecision = null;
|
||||
updateDecisionHandler = (val) => { userDecision = val; };
|
||||
|
||||
tempApp.use((req, res, next) => {
|
||||
const clientIp = req.socket.remoteAddress;
|
||||
if (clientIp !== '127.0.0.1' && clientIp !== '::1' && clientIp !== '::ffff:127.0.0.1') {
|
||||
return res.status(403).end();
|
||||
}
|
||||
res.header('Access-Control-Allow-Origin', '*');
|
||||
res.header('Access-Control-Allow-Methods', 'GET,POST,OPTIONS');
|
||||
res.header('Access-Control-Allow-Headers', '*');
|
||||
if (req.method === 'OPTIONS') return res.sendStatus(200);
|
||||
next();
|
||||
});
|
||||
|
||||
tempApp.get('/update/info', (req, res) => {
|
||||
res.json({ available: true, current: localVersion, latest: release.version });
|
||||
});
|
||||
const handleYes = (req, res) => { debugLog("tempApp received YES"); userDecision = true; res.sendStatus(200); };
|
||||
const handleNo = (req, res) => { debugLog("tempApp received NO"); userDecision = false; res.sendStatus(200); };
|
||||
|
||||
tempApp.all('/update/yes', handleYes);
|
||||
tempApp.all('/update/install', handleYes);
|
||||
tempApp.all('/update/no', handleNo);
|
||||
tempApp.all('/update/skip', handleNo);
|
||||
tempApp.all('/update/:choice', (req, res) => {
|
||||
const c = String(req.params.choice || '').toLowerCase();
|
||||
if (c === 'yes' || c === 'install' || c === 'true') userDecision = true;
|
||||
if (c === 'no' || c === 'skip' || c === 'false') userDecision = false;
|
||||
res.sendStatus(200);
|
||||
});
|
||||
|
||||
const tempServer = await new Promise((resolve) => {
|
||||
const s = tempApp.listen(4891, '127.0.0.1', () => resolve(s));
|
||||
s.on('error', (err) => {
|
||||
debugLog(`Update server bind error: ${err.message}`);
|
||||
resolve(null);
|
||||
});
|
||||
});
|
||||
|
||||
if (!tempServer) {
|
||||
userDecision = false;
|
||||
} else {
|
||||
sendToTauri('update-available', { current: localVersion, latest: release.version });
|
||||
}
|
||||
|
||||
let waitLoops = 0;
|
||||
while (userDecision === null) {
|
||||
if (waitLoops > 24000) {
|
||||
debugLog("Update decision timed out after 10 minutes, defaulting to skip.");
|
||||
userDecision = false;
|
||||
break;
|
||||
}
|
||||
waitLoops++;
|
||||
await new Promise(r => setTimeout(r, 25));
|
||||
}
|
||||
|
||||
updateDecisionHandler = null;
|
||||
if (tempServer) {
|
||||
tempServer.close();
|
||||
}
|
||||
|
||||
if (userDecision) {
|
||||
debugLog("User accepted update.");
|
||||
await installBuild(release);
|
||||
} else {
|
||||
debugLog("User skipped update.");
|
||||
sendToTauri('status', { message: 'Update skipped. Continuing startup...' });
|
||||
}
|
||||
debugLog("Update available. Installing update...");
|
||||
sendToTauri('status', { message: `Updating to ${release.version}...` });
|
||||
await installBuild(release);
|
||||
} else {
|
||||
debugLog("Already on the latest version.");
|
||||
sendToTauri('status', { message: 'Up to date.' });
|
||||
@@ -406,32 +287,6 @@ async function start() {
|
||||
throw new Error('Could not download the app files. Check your internet connection and relaunch.');
|
||||
}
|
||||
|
||||
if (process.env.VYLA_TEST_UI === '1') {
|
||||
const fakeFiles = [
|
||||
{ path: 'frontend/server.js', status: 'modified', size: 1024 },
|
||||
{ path: 'frontend/public/app.js', status: 'modified', size: 2048 },
|
||||
{ path: 'player/server.js', status: 'modified', size: 512 },
|
||||
{ path: 'player/lib/new-file.js', status: 'added', size: 256 }
|
||||
];
|
||||
const filesAnswer = await promptUser('files-available', { files: fakeFiles });
|
||||
debugLog(`TEST files answer: ${JSON.stringify(filesAnswer)}`);
|
||||
if (filesAnswer && filesAnswer.accept) {
|
||||
for (let i = 1; i <= filesAnswer.files.length; i++) {
|
||||
sendToTauri('extract-progress', {
|
||||
file: filesAnswer.files[i - 1],
|
||||
done: i,
|
||||
total: filesAnswer.files.length,
|
||||
percent: Math.round((i / filesAnswer.files.length) * 100)
|
||||
});
|
||||
await new Promise((r) => setTimeout(r, 400));
|
||||
}
|
||||
}
|
||||
const sdkAnswer = await promptUser('sdk-available', { current: '1.19.0', latest: '1.20.0' });
|
||||
debugLog(`TEST sdk answer: ${JSON.stringify(sdkAnswer)}`);
|
||||
sendToTauri('status', { message: sdkAnswer && sdkAnswer.accept ? 'TEST: SDK accepted' : 'TEST: SDK skipped' });
|
||||
await new Promise((r) => setTimeout(r, 1500));
|
||||
}
|
||||
|
||||
sendToTauri('status', { message: 'Checking UI files and SDK...' });
|
||||
const [filesCheck, sdkCheck] = await Promise.all([
|
||||
withTimeout(fileUpdater.checkFiles().catch((e) => {
|
||||
@@ -445,39 +300,26 @@ async function start() {
|
||||
]);
|
||||
|
||||
if (filesCheck && filesCheck.changes.length > 0) {
|
||||
sendToTauri('status', { message: `${filesCheck.changes.length} file update(s) available.` });
|
||||
const answer = await promptUser('files-available', {
|
||||
files: filesCheck.changes.map((c) => ({ path: c.path, status: c.status, size: c.size }))
|
||||
});
|
||||
if (answer && answer.accept) {
|
||||
const allowed = new Set(answer.files);
|
||||
const selected = filesCheck.changes.filter((c) => allowed.has(c.path));
|
||||
if (selected.length > 0) {
|
||||
try {
|
||||
await fileUpdater.applyFiles(selected, filesCheck.seq, getReplacementsConfig(), (file, done, total) => {
|
||||
sendToTauri('extract-progress', { file, done, total, percent: Math.round((done / total) * 100) });
|
||||
});
|
||||
sendToTauri('status', { message: `Updated ${selected.length} file(s).` });
|
||||
} catch (e) {
|
||||
debugLog(`File update failed: ${e.message}`);
|
||||
sendToTauri('status', { message: `File update failed: ${e.message}` });
|
||||
}
|
||||
}
|
||||
sendToTauri('status', { message: `Updating ${filesCheck.changes.length} file(s)...` });
|
||||
try {
|
||||
await fileUpdater.applyFiles(filesCheck.changes, filesCheck.seq, getReplacementsConfig(), (file, done, total) => {
|
||||
sendToTauri('extract-progress', { file, done, total, percent: Math.round((done / total) * 100) });
|
||||
});
|
||||
sendToTauri('status', { message: `Updated ${filesCheck.changes.length} file(s).` });
|
||||
} catch (e) {
|
||||
debugLog(`File update failed: ${e.message}`);
|
||||
sendToTauri('status', { message: `File update failed: ${e.message}` });
|
||||
}
|
||||
}
|
||||
|
||||
if (sdkCheck && sdkCheck.outdated) {
|
||||
sendToTauri('status', { message: `SDK update available (${sdkCheck.latest}).` });
|
||||
const answer = await promptUser('sdk-available', { current: sdkCheck.current, latest: sdkCheck.latest });
|
||||
if (answer && answer.accept) {
|
||||
try {
|
||||
sendToTauri('status', { message: `Installing SDK ${sdkCheck.latest}...` });
|
||||
await fileUpdater.installSdk(sdkCheck);
|
||||
sendToTauri('status', { message: `SDK updated to ${sdkCheck.latest}.` });
|
||||
} catch (e) {
|
||||
debugLog(`SDK install failed: ${e.message}`);
|
||||
sendToTauri('status', { message: `SDK update failed: ${e.message}` });
|
||||
}
|
||||
sendToTauri('status', { message: `Updating SDK (${sdkCheck.latest})...` });
|
||||
try {
|
||||
await fileUpdater.installSdk(sdkCheck);
|
||||
sendToTauri('status', { message: `SDK updated to ${sdkCheck.latest}.` });
|
||||
} catch (e) {
|
||||
debugLog(`SDK install failed: ${e.message}`);
|
||||
sendToTauri('status', { message: `SDK update failed: ${e.message}` });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user