Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

Todas las versiones notables de NextSync se documentan aquí. El formato sigue [Keep a Changelog](https://keepachangelog.com/es/1.1.0/) y el versionado es **+0.0.2 por release, reiniciado en 0.1.4** (decisión del usuario, 22-Ago-2026; sustituye al +0.02 anterior).

## [0.2.24] - 2026-09-17

### Fixed

- Folders no longer stay Offline after connectivity returns when the recovery probe fired while the machine was offline: the probe is re-armed on network restore and synchronization resumes on its own, without a manual sync or an app restart (#207).

## [0.2.22] - 2026-09-17

### Fixed
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "nextsync"
version = "0.2.22"
version = "0.2.24"
edition = "2021"
rust-version = "1.83"
license = "GPL-3.0-or-later"
Expand Down
2 changes: 1 addition & 1 deletion PKGBUILD
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Maintainer: gnacho <https://github.com/gnacho>
pkgname=nextsync
pkgver=0.2.22
pkgver=0.2.24
pkgrel=1
pkgdesc='Nextcloud desktop synchronization client for GNOME (Rust rewrite)'
arch=('x86_64' 'aarch64')
Expand Down
4 changes: 2 additions & 2 deletions README.es.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
</p>
<p>
<a href="https://github.com/gnacho/nextsync/actions/workflows/ci.yml"><img src="https://github.com/gnacho/nextsync/actions/workflows/ci.yml/badge.svg" alt="Estado de CI"></a>
<img src="https://img.shields.io/badge/version-0.2.22-blue?style=flat-square" alt="Versión 0.2.22">
<img src="https://img.shields.io/badge/version-0.2.24-blue?style=flat-square" alt="Versión 0.2.24">
<img src="https://img.shields.io/badge/license-GPL--3.0%2B-informational?style=flat-square" alt="GNU GPL v3 o posterior">
</p>
</div>
Expand Down Expand Up @@ -84,7 +84,7 @@ Ambos motores se esconden detrás del mismo trait pequeño, así que un proveedo
Descarga el `.pkg.tar.zst` de la [última release](https://github.com/gnacho/nextsync/releases/latest) e instálalo:

```bash
sudo pacman -U nextsync-0.2.22-1-x86_64.pkg.tar.zst
sudo pacman -U nextsync-0.2.24-1-x86_64.pkg.tar.zst
```

El paquete depende de `gtk4` y `libadwaita`. Para cuentas Nextcloud instala `nextcloud-client` (aporta `nextcloudcmd`); para cuentas OpenCloud, el `opencloudcmd` oficial.
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
</p>
<p>
<a href="https://github.com/gnacho/nextsync/actions/workflows/ci.yml"><img src="https://github.com/gnacho/nextsync/actions/workflows/ci.yml/badge.svg" alt="CI status"></a>
<img src="https://img.shields.io/badge/version-0.2.22-blue?style=flat-square" alt="Version 0.2.22">
<img src="https://img.shields.io/badge/version-0.2.24-blue?style=flat-square" alt="Version 0.2.24">
<img src="https://img.shields.io/badge/license-GPL--3.0%2B-informational?style=flat-square" alt="GNU GPL v3 or later">
</p>
</div>
Expand Down Expand Up @@ -84,7 +84,7 @@ Both engines sit behind the same small trait, so a new provider is a command bui
Download the `.pkg.tar.zst` from the [latest release](https://github.com/gnacho/nextsync/releases/latest) and install it:

```bash
sudo pacman -U nextsync-0.2.22-1-x86_64.pkg.tar.zst
sudo pacman -U nextsync-0.2.24-1-x86_64.pkg.tar.zst
```

The package depends on `gtk4` and `libadwaita`. For Nextcloud accounts install `nextcloud-client` (it provides `nextcloudcmd`); for OpenCloud accounts, the official `opencloudcmd`.
Expand Down
1 change: 1 addition & 0 deletions data/io.github.gnacho.nextsync.metainfo.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
<icon type="stock">io.github.gnacho.nextsync</icon>
<content_rating type="oars-1.1"/>
<releases>
<release version="0.2.24" date="2026-09-17"/>
<release version="0.2.22" date="2026-09-17"/>
<release version="0.2.20" date="2026-09-08"/>
<release version="0.2.18" date="2026-09-08"/>
Expand Down
2 changes: 1 addition & 1 deletion landing/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ <h3 data-i18n="compare.ht">Lo que NextSync no hace (todavía)</h3>
<h2 class="reveal" data-i18n="install.title">Instalación fácil y rápida</h2>
<p class="lead reveal" data-i18n="install.lead">En Arch, CachyOS y derivadas hay paquete listo en cada release.</p>
<div class="card install-card reveal">
<pre class="code-block"><code id="installCmd">sudo pacman -U nextsync-0.2.22-1-x86_64.pkg.tar.zst</code></pre>
<pre class="code-block"><code id="installCmd">sudo pacman -U nextsync-0.2.24-1-x86_64.pkg.tar.zst</code></pre>
<button class="btn suggested" id="copyBtn" data-i18n="install.copy">Copiar comando</button>
<p class="small-print" data-i18n="install.note">Descarga el paquete <code>.pkg.tar.zst</code> más reciente desde <a href="https://github.com/gnacho/nextsync/releases" target="_blank" rel="noopener">GitHub Releases</a> y ajusta el nombre del fichero.</p>
</div>
Expand Down
53 changes: 53 additions & 0 deletions src/core/scheduler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1192,6 +1192,16 @@ impl SchedulerInner {
self.state
.set(AppState::Offline, t("Waiting for a network connection"));
} else if !was_online {
// Issue #207: the recovery probe is a one-shot timer; if it fired
// while the machine was offline, `start` aborted on !online and
// the timer died. Re-arm it now so the folder recovers by itself
// once the network is back, instead of sitting queued behind the
// server_unreachable gate until a manual sync. The probe guard
// (start_source) makes the re-arm a no-op if one is still pending.
if self.server_unreachable {
self.queue.add(Trigger::Retry);
self.schedule_server_probe();
}
if !self.queue.is_empty() || !self.manual_only() {
self.request(Trigger::NetworkRestored);
} else {
Expand Down Expand Up @@ -1777,6 +1787,49 @@ mod tests {
assert_eq!(scheduler.state().snapshot().state, AppState::IdleOk);
}

/// Issue #207: the recovery probe is a one-shot timer. If it fires while
/// the machine is offline, `start` aborts on !online and the timer is
/// gone for good. When the network comes back, the folder must still
/// recover on its own - the probe is re-armed and the queued retry runs -
/// without a manual sync or an app restart.
#[test]
fn network_restore_rearms_a_probe_that_died_while_offline() {
let (scheduler, source, runner) = make_scheduler(None);
scheduler.request(Trigger::Startup);
run_idle(&source);
finish(&runner, SyncOutcome::NetworkError);
assert!(scheduler.server_unreachable());
let probe_id = source.borrow().only_id();

// Connectivity drops before the probe fires; the probe fires anyway
// and its one-shot start() aborts on !online: the timer is dead.
scheduler.set_online(false);
fire_timer(&source, probe_id);
assert_eq!(
runner.0.borrow().start_calls,
1,
"an offline probe must not run the engine"
);
assert_eq!(
source.borrow().pending(),
0,
"the one-shot probe timer is gone"
);

// Connectivity returns: the folder recovers without a manual sync.
scheduler.set_online(true);
assert!(
source.borrow().pending() >= 1,
"the recovery probe is re-armed on network restore"
);
let rearmed_id = source.borrow().only_id();
fire_timer(&source, rearmed_id);
assert_eq!(runner.0.borrow().start_calls, 2);
finish(&runner, SyncOutcome::Success);
assert!(!scheduler.server_unreachable());
assert_eq!(scheduler.state().snapshot().state, AppState::IdleOk);
}

/// Issue #179: after the server recovers (Success clears the gate), a
/// fresh automatic trigger runs the engine again.
#[test]
Expand Down
9 changes: 4 additions & 5 deletions version.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
{
"schema_version": 1,
"version": "0.2.22",
"version": "0.2.24",
"mandatory": false,
"summary": "Detect a missing sync engine and stop reporting success when nothing can be synchronized.",
"summary": "Folders recover on their own after connectivity returns, even when the recovery probe fired while the machine was offline.",
"changelog": [
"When the sync binary (nextcloudcmd / opencloudcmd) is not installed, folders now show a clear 'sync engine is not installed' state instead of a generic failure - or worse, a misleading 'Synchronization completed' from the unchanged-ETag interval shortcut while nothing was actually synced.",
"A configured engine path that no longer exists resolves as missing too, so a stale override surfaces the same actionable state.",
"The missing-engine reason is written to the daily log and raises a desktop notification like other problem outcomes."
"After a period without connectivity, folders no longer stay Offline until a manual sync or an app restart: when the network comes back, the server recovery probe is re-armed automatically and synchronization resumes on its own.",
"Fixes the case where the one-shot recovery probe fired while the machine was offline, died silently, and the NetworkRestored trigger stayed parked behind the server-unreachable gate forever."
],
"released_at": "2026-09-17T00:00:00Z"
}
Loading