From 626d95a157fed4e7fcf9539f0053df67964816cc Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 28 Nov 2025 07:19:30 +0000 Subject: [PATCH] Fix Portable black screen, git locking bugs, and improve Login UI --- electron/main.ts | 144 +++++++++++++++++++------------- src/Settings.tsx | 29 ++++--- verification/settings_page.png | Bin 0 -> 87720 bytes verification/verify_settings.py | 31 +++++++ 4 files changed, 133 insertions(+), 71 deletions(-) create mode 100644 verification/settings_page.png create mode 100644 verification/verify_settings.py diff --git a/electron/main.ts b/electron/main.ts index afa1c01..ca16b0a 100644 --- a/electron/main.ts +++ b/electron/main.ts @@ -69,67 +69,78 @@ async function checkRepos() { let reposUpdated = false; - for (const repo of repos) { - try { - const git = simpleGit(repo.path) - - // Auto-detect remote URL if missing - if (!repo.githubUrl) { - const remotes = await git.getRemotes(true); - const origin = remotes.find(r => r.name === 'origin') || remotes[0]; - if (origin) { - repo.githubUrl = convertGitUrlToHttps(origin.refs.fetch); - reposUpdated = true; + // Prevent concurrent checks to avoid git lock issues + if ((global as any).isCheckingRepos) { + console.log('Skipping checkRepos: previous check still in progress'); + return; + } + (global as any).isCheckingRepos = true; + + try { + for (const repo of repos) { + try { + const git = simpleGit(repo.path) + + // Auto-detect remote URL if missing + if (!repo.githubUrl) { + const remotes = await git.getRemotes(true); + const origin = remotes.find(r => r.name === 'origin') || remotes[0]; + if (origin) { + repo.githubUrl = convertGitUrlToHttps(origin.refs.fetch); + reposUpdated = true; + } } - } - await git.fetch() - const status = await git.status() - - const updateData: any = { - id: repo.id, - status: 'clean', - commitsBehind: 0, - commitsAhead: 0, - githubUrl: repo.githubUrl - }; - - if (status.isClean() === false) { - updateData.status = 'dirty'; - } else if (status.ahead > 0 && status.behind > 0) { - updateData.status = 'diverged'; - updateData.commitsBehind = status.behind; - updateData.commitsAhead = status.ahead; - } else if (status.behind > 0) { - updateData.status = 'behind'; - updateData.commitsBehind = status.behind; - - if (repo.autoPull) { - await git.pull() - notifyUser(repo.name, `Pulled ${status.behind} new commits.`) - updateData.status = 'clean'; - updateData.commitsBehind = 0; - } else { - notifyUser(repo.name, `${status.behind} commits waiting.`, true) + await git.fetch() + const status = await git.status() + + const updateData: any = { + id: repo.id, + status: 'clean', + commitsBehind: 0, + commitsAhead: 0, + githubUrl: repo.githubUrl + }; + + if (status.isClean() === false) { + updateData.status = 'dirty'; + } else if (status.ahead > 0 && status.behind > 0) { + updateData.status = 'diverged'; + updateData.commitsBehind = status.behind; + updateData.commitsAhead = status.ahead; + } else if (status.behind > 0) { + updateData.status = 'behind'; + updateData.commitsBehind = status.behind; + + if (repo.autoPull) { + await git.pull() + notifyUser(repo.name, `Pulled ${status.behind} new commits.`) + updateData.status = 'clean'; + updateData.commitsBehind = 0; + } else { + notifyUser(repo.name, `${status.behind} commits waiting.`, true) + } + } else if (status.ahead > 0) { + updateData.status = 'ahead'; + updateData.commitsAhead = status.ahead; + } + + if (mainWindow && !mainWindow.isDestroyed()) mainWindow.webContents.send('repo-update', updateData) + + } catch (err: any) { + console.error(`Error checking ${repo.name}:`, err) + if (mainWindow && !mainWindow.isDestroyed()) { + mainWindow.webContents.send('repo-error', { id: repo.id, message: err.message || 'Unknown error' }) + mainWindow.webContents.send('repo-update', { id: repo.id, status: 'error' }) } - } else if (status.ahead > 0) { - updateData.status = 'ahead'; - updateData.commitsAhead = status.ahead; - } - - if (mainWindow && !mainWindow.isDestroyed()) mainWindow.webContents.send('repo-update', updateData) - - } catch (err: any) { - console.error(`Error checking ${repo.name}:`, err) - if (mainWindow && !mainWindow.isDestroyed()) { - mainWindow.webContents.send('repo-error', { id: repo.id, message: err.message || 'Unknown error' }) - mainWindow.webContents.send('repo-update', { id: repo.id, status: 'error' }) } } - } - if (reposUpdated) { - store.set('repos', repos); + if (reposUpdated) { + store.set('repos', repos); + } + } finally { + (global as any).isCheckingRepos = false; } } @@ -218,15 +229,18 @@ function createWindow(): void { sandbox: false, nodeIntegration: false, contextIsolation: true, - devTools: true + devTools: true, + webSecurity: app.isPackaged ? false : true, // Relax security for portable builds to avoid "Not allowed to load local resource" + allowRunningInsecureContent: true } }) // LOGGING DIAGNOSTICS - mainWindow.webContents.on('did-fail-load', (event, errorCode, errorDescription) => { - console.error('FAILED TO LOAD:', errorCode, errorDescription); + mainWindow.webContents.on('did-fail-load', (event, errorCode, errorDescription, validatedURL) => { + const msg = `FAILED TO LOAD: ${errorCode} - ${errorDescription} - URL: ${validatedURL}`; + console.error(msg); try { - writeFileSync(join(app.getPath('userData'), 'load-error.log'), `Error: ${errorCode} - ${errorDescription}`); + writeFileSync(join(app.getPath('userData'), 'load-error.log'), msg); } catch (e) {} }); @@ -255,7 +269,17 @@ function createWindow(): void { if (process.env.VITE_DEV_SERVER_URL) { mainWindow.loadURL(process.env.VITE_DEV_SERVER_URL) } else { - mainWindow.loadFile(join(DIST_PATH, 'index.html')) + // For portable builds, we need to be careful with paths. + // Explicitly resolve the index.html path. + const indexPath = join(DIST_PATH, 'index.html'); + + // Log for debugging + console.log('Loading index.html from:', indexPath); + + mainWindow.loadFile(indexPath).catch(e => { + console.error('Failed to load file:', e); + try { writeFileSync(join(app.getPath('userData'), 'load-exception.log'), String(e)); } catch {} + }); } mainWindow.webContents.setWindowOpenHandler(({ url }) => { diff --git a/src/Settings.tsx b/src/Settings.tsx index 2b9d5fd..98a328a 100644 --- a/src/Settings.tsx +++ b/src/Settings.tsx @@ -213,21 +213,28 @@ export const Settings = () => {
- Start automatically on login. + Automatically launch Git Watcher Pro when you sign in.
w+=5~iY!u1;G z=PLQf7>^J{J9#u&+g1GcoDzi3qS^V>5F$1PcQxpL?z-x;($H(Xb>*ENUi%gn`HL#m z3&r0RE1~`=9{_0p5>C&EZ1ycyE2IZH?Qd~j1(t%*VQ)=Brz->L5FUG{KitayZ
RVV+fLa<}a}gRBiAT9%RE^uK$O{S1~Ynms5J_+P@IL)ngy@w@O_`g|7q
z_m_hT{@W>1Bgprlvi|_iNc?~6u^l<&8Bm;l!wQGQ*SjBT2g(%v+=hlHL*hpW&XCa1
z_NQ&%&b}muMPl!(%AVrXR7NkLA?WOjR}ic<8Cj5ecd^anYwqL(A^CDp{*oo1{|H3i
z((EjL^y{vW@5|Pp;hgtI81mGN4X^LZQnc?A`2TcEDd>3>AV*7$S}SvH-j5NWA~}k)
z;=m=*6lfBMnopV}|4%SbbNRs3te)ys|J?c5?x9gUt*)kK__2Ie0hUehcWZ%Yw+5%FP@;pr#dT5QPw|l5EZB4^=a?r(|Z@;1eAE
zcgu8v!47`^Z9@#j{}1R
|^c6@P~M_DUsoHV5?Mc1$ZCmbOYtv0fFW
zrT5FOw{I@BGKhC4jgGrb&CT&~za(;XGY2&=$a54G`?ekUGNO7o`u-3c0~lBqX!IgU
z80iqYkV;y{G+;^HEJ3KiauQP4zg1?A