3 Commits

Author SHA1 Message Date
debont80 ccee9b7d3b chore: bump version to 0.7.1 2026-07-09 15:50:14 -04:00
debont80 af9c285864 Merge pull request 'fix(sync): run watched sync when a scheduled --sync hits the running instance' (#12) from fix/scheduled-sync-running-instance into main
Reviewed-on: #12
2026-07-09 15:48:31 -04:00
debont80 87e16ca28e fix(sync): run watched sync when a scheduled --sync hits the running instance
The Windows daily-sync task launches `AeroFetch.exe --sync`, but the single-
instance lock routes that relaunch to the `second-instance` handler whenever
AeroFetch is already open. The handler only focused the window and looked for a
link -- it never checked `isSyncLaunch(argv)` -- so the sync never ran. The daily
auto-download of new watched-source uploads therefore did nothing for minimize-
to-tray / always-on users (and the relaunch stole window focus each day).

Add a `runWatchedSync` main->renderer push: on a `--sync` relaunch the handler
now nudges the renderer to run syncWatched() instead of focusing, so the daily
sync fires whether AeroFetch was closed or already running.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 15:45:35 -04:00
7 changed files with 29 additions and 5 deletions
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "aerofetch",
"version": "0.7.0",
"version": "0.7.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "aerofetch",
"version": "0.7.0",
"version": "0.7.1",
"license": "UNLICENSED",
"dependencies": {
"@electron-toolkit/utils": "^4.0.0",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "aerofetch",
"version": "0.7.0",
"version": "0.7.1",
"description": "A yt-dlp frontend for Windows",
"main": "./out/main/index.js",
"author": "AeroFetch",
+9
View File
@@ -260,6 +260,15 @@ if (isPrimaryInstance) {
// link it carried and hand it to the window we already have.
app.on('second-instance', (_e, argv) => {
if (!mainWindow) return
// A scheduled `--sync` relaunch (Task Scheduler) hit the already-running instance:
// run the watched-source sync in this window instead of no-opping. Without this the
// daily auto-download never fires while AeroFetch is open — e.g. minimize-to-tray
// users. Deliberately does NOT focus the window, so the daily sync stays unobtrusive
// (mirrors the fresh-launch `--sync` showInactive path in createWindow).
if (isSyncLaunch(argv)) {
mainWindow.webContents.send(IpcChannels.runWatchedSync)
return
}
focusWindow(mainWindow)
const incomingUrl = extractIncomingUrl(argv)
if (incomingUrl) mainWindow.webContents.send(IpcChannels.externalUrl, incomingUrl)
+8
View File
@@ -279,6 +279,14 @@ const api = {
return () => ipcRenderer.removeListener(IpcChannels.indexProgress, listener)
},
/** Subscribe to the "run watched-source sync now" nudge a scheduled `--sync` relaunch
* sends when it hits the already-running instance. Returns an unsubscribe function. */
onRunWatchedSync: (cb: () => void): (() => void) => {
const listener = (): void => cb()
ipcRenderer.on(IpcChannels.runWatchedSync, listener)
return () => ipcRenderer.removeListener(IpcChannels.runWatchedSync, listener)
},
// --- Built-in yt-dlp terminal (Phase N) ---
/** Run the bundled yt-dlp with raw args; output streams via onTerminalOutput. */
+1
View File
@@ -271,6 +271,7 @@ export const mockApi: Api = {
onSystemThemeUpdate: () => () => {},
openHighContrastSettings: async () => {},
onExternalUrl: () => () => {},
onRunWatchedSync: () => () => {},
// Media-manager sources — a seeded channel so the (Phase H) Library view has
// demo data in this browser-only preview.
listSources: async () => [
+5 -2
View File
@@ -485,13 +485,16 @@ if (!PREVIEW) {
.listSources()
.then((sources) => {
useSources.setState({ sources })
// If any source is watched, kick off a sync shortly after launch (covers the
// scheduled `--sync` launch and a normal launch alike).
// If any source is watched, kick off a sync shortly after launch (covers a fresh
// `--sync` launch and a normal launch alike).
if (sources.some((s) => s.watched)) {
setTimeout(() => useSources.getState().syncWatched(), 1500)
}
})
.catch(logError('startup listSources'))
// A scheduled `--sync` relaunch that hit the already-running instance nudges us here,
// so the daily sync fires even when AeroFetch was already open (e.g. tray mode).
window.api.onRunWatchedSync?.(() => useSources.getState().syncWatched())
window.api.onIndexProgress((p: IndexProgress) => {
useSources.setState({
indexing: {
+3
View File
@@ -105,6 +105,9 @@ export const IpcChannels = {
scheduledSyncSet: 'sources:scheduled-sync-set',
/** main → renderer push channel for live indexing progress */
indexProgress: 'sources:index-progress',
/** main → renderer: a scheduled `--sync` relaunch hit the running instance — run the
* watched-source sync here instead of no-opping (Phase J) */
runWatchedSync: 'sources:run-sync',
// --- Built-in yt-dlp terminal (Phase N) ---
terminalRun: 'terminal:run',
terminalCancel: 'terminal:cancel',