Skip to content

Releases: thatSFguy/reticulum-mobile-app

android-v1.2.120

Choose a tag to compare

@github-actions github-actions released this 04 Sep 18:27

What's new in 1.2.120

• Relay Chat no longer says "Connected" over a connection that is gone. When the app switched or lost its transport — a network blip, or you picking a different node — the hub kept showing as connected while nothing you typed reached it: /who and every other command went out to a link the hub no longer had, and only Disconnect and Connect again fixed it. The room now says it is not connected, and offers Reconnect.

• The Nodes tab's filter, search and add buttons stay on screen at large system font sizes. At the biggest settings they were pushed off the right edge, which left the filter menu unreachable.

• The propagation node picker in Settings lists every node it knows, not just the ones seen in the last few minutes. On a busy mesh a node that announces hourly kept dropping out of the list, so a newly seen, closer node was never there to pick. Automatic was always choosing from the full set — this is the list catching up with it.

• Wide tables in the Nomad browser keep their shape. A table with more columns than fit the screen used to squeeze every column down to a couple of characters, wrapping headers one letter per line; it now keeps its real width and scrolls sideways.

• The Nomad browser header is two rows instead of four. The page age moved up beside the node name, and the node hash moved into the address box — where it belongs, since the hash and path together are the address you can share.

• Under the hood: a local NomadNet test node with a fixture page per renderer feature, reachable from a phone over the USB cable, so a page-rendering change can be checked before it ships instead of after. Nothing it does touches the public mesh.

Full Changelog: android-v1.2.119...android-v1.2.120

ios-v1.0.112

ios-v1.0.112 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 04 Sep 18:36

Unsigned iOS build — sideload via AltStore / Sideloadly / SideStore.

Download Reticulum-iOS-1.0.112-unsigned.ipa and re-sign with your free Apple ID using your sideloading tool of choice. Apps signed with a free Apple ID expire after 7 days; AltStore can auto-renew while it's running on your Mac.

This app is not published to the App Store — see the iOS section of the README for the rationale.

Full Changelog: android-v1.2.119...ios-v1.0.112

android-v1.2.119

Choose a tag to compare

@github-actions github-actions released this 03 Sep 16:09

What's new in 1.2.119

• The app is gentler about reconnecting to an internet transport node that turns it away. Some public nodes accept the connection and then immediately close it — a node that is full, restarting, or that has blocked your address. The app read that as "we were connected and then something broke" and kept retrying every minute, all day, forever. It now recognises a connection that was accepted but never usable, and backs off to one attempt every five minutes instead.

• If your address has been blocked by a node's operator, this is also the difference between quietly waiting and knocking 1,400 times a day — which is a good way to stay blocked. If a node has stopped working for you, Settings → the shuffle button next to the node address will move you to another one.

Full Changelog: android-v1.2.118...android-v1.2.119

android-v1.2.118

Choose a tag to compare

@github-actions github-actions released this 03 Sep 15:02

What's new in 1.2.118

• Relay Chat hubs no longer get stuck on "Connecting…". After the app had been in the background for a while, every hub in your list could come back showing a spinner that never resolved — with no Disconnect button to escape it, so the only fix was force-stopping the app. The connections were fine the whole time; the app had simply lost track of what it already had open.

• Connecting to a hub can now be cancelled. The spinner has a Cancel button beside it, and connecting no longer reports success until the hub has actually answered.

• Nomad: tables are real tables now. The header row, column alignment and links inside cells all work — before, the alignment row rendered as a row of dashes and a link in a cell was dead text.

• Nomad: indented sections are indented. Nesting was read from the page and then ignored, so every section rendered flat.

• Nomad: you can type a page address. A page nothing links to is reachable when an operator tells you its path.

• Nomad: a Forward button, so an accidental Back no longer costs a round trip over the mesh.

• Nomad: a page the node asks us not to keep now also clears the copy we already had. The browser could show fresh content beside an hours-old "Last pulled" time.

What's Changed

  • fix(resource): prove the body the sender hashed, and guard the hashmap by @thatSFguy in #50
  • ci: actually run the live interop tests against upstream RNS by @thatSFguy in #51
  • Nomad browser: micron table/indent/overflow fidelity, URL entry, Forward, and a conformance fixture by @thatSFguy in #60

Full Changelog: android-v1.2.117...android-v1.2.118

ios-v1.0.111

ios-v1.0.111 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 03 Sep 15:10

Unsigned iOS build — sideload via AltStore / Sideloadly / SideStore.

Download Reticulum-iOS-1.0.111-unsigned.ipa and re-sign with your free Apple ID using your sideloading tool of choice. Apps signed with a free Apple ID expire after 7 days; AltStore can auto-renew while it's running on your Mac.

This app is not published to the App Store — see the iOS section of the README for the rationale.

What's Changed

  • fix(resource): prove the body the sender hashed, and guard the hashmap by @thatSFguy in #50
  • ci: actually run the live interop tests against upstream RNS by @thatSFguy in #51
  • Nomad browser: micron table/indent/overflow fidelity, URL entry, Forward, and a conformance fixture by @thatSFguy in #60

Full Changelog: android-v1.2.117...ios-v1.0.111

android-v1.2.117

Choose a tag to compare

@github-actions github-actions released this 02 Sep 18:13

What's new in 1.2.117

• Tabs in the Nomad browser. The toolbar shows how many are open; tapping it opens a list where you can switch between them, close one, or start a new one. Up to 8.

• A new tab starts on the node list, so opening one is also how you get back to the node list.

• The browser no longer forgets where you were. Switching to another tab of the app and back used to throw away the open page and its whole Back history, while keeping the search box and filter — so it looked like it remembered, over an empty list. Coming back is now instant and does not re-fetch the page.

• A Nodes button goes straight back to the node list in one tap. Before, Back had to be pressed once for every page you had visited.

• Favourite, Share and Clear cache moved into the ⋮ menu to make room.

• "Anonymous" is now per tab, so turning it off in one tab cannot identify you on a node you opened anonymously in another.

• Closing a tab now closes its connection to that node instead of leaving it running in the background.

• Security: opening a web link someone sent you now asks first. It is the one tap that leaves the mesh, and the site — chosen by the sender, not you — sees your real IP address. The link shown in the prompt is also cleaned up so it cannot be dressed up to look like a different site.

• Security: tapping a Relay Chat link for a hub you have never connected to now asks first. Accepting is not a one-off — your app reconnects to that hub every time it starts until you remove it.

• Security: the browser's page cache is now bounded. It grew without any limit before, and a very large page could get stuck in it unreadable.

• A name taken from a link's own text can no longer contain hidden characters that reorder how a node's name is displayed in your lists.

Full Changelog: android-v1.2.116...android-v1.2.117

android-v1.2.116

Choose a tag to compare

@github-actions github-actions released this 02 Sep 11:56

What's new in 1.2.116

• Nodes you reach by tapping a link now show their real name. They were listed as "(via cross-node link)" — and stayed that way forever, because the placeholder was stored in the field that outranks the node's announced name. The real names were there the whole time, underneath. Existing entries are repaired on upgrade.

• A link's own wording now names the node it points to. A page that says "Amber Pages" next to an address gets you an entry called Amber Pages, not a row of hex, until that node announces its own name.

• Nodes you pass through on the way to a page are no longer added to Favourites. Adding a node by hand still favourites it; walking past one does not, which is why so many piled up.

• The same fix applies to a node added by scanning its QR code — it read "(QR scan)" instead of its name.

Full Changelog: ios-v1.0.108...android-v1.2.116

ios-v1.0.110

ios-v1.0.110 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 02 Sep 18:23

A tapped link no longer leaves the mesh, or joins a stranger's hub, without asking.

Both come out of a full security audit run against 5da60a9 (six surfaces; the report lives outside the repo). The theme is that everything added recently made content someone else authored tappable — message bodies, Relay Chat room links, page link labels — and iOS was the platform missing the guardrails.

  • A web link in a message opened straight into Safari. No prompt, on either the conversation or the rooms surface. This is the one tap that leaves the mesh, and the server on the other end was chosen by the sender: opening it hands them your real IP, ISP and rough location, tied to the identity they messaged. Android has asked first since the July audit; the asymmetry was even written into the shared code, and iOS simply never got the other half. Now both surfaces park the URL for a confirmation, from one shared modifier so the two cannot drift again.

  • A Relay Chat link joined a hub you had never connected to, permanently. One tap wrote the hub, marked the room joined, and opened a session — and because the room is stored as joined, the app reconnected to that hub at every launch afterwards, until you found the hub list and deleted it. A hub you have not connected to before now asks first, on both platforms. A hub already in your list does not re-ask. The bare rrc://<hash> form, which writes the same row, is gated the same way.

  • The page cache had no limit of any kind — no row cap, no size cap, and nothing that ever removed anything. Now a page above 256 KB is not cached (it still loads and renders), the cache keeps its 500 most recent pages, and an install that already grew is trimmed at startup.

  • A name taken from a link's own label skipped the sanitiser that announced names go through, so it could carry newlines into your node lists. Fixing that turned up the sanitiser's own gap: it stripped control characters but never bidirectional formatting characters, which means announced names had the same hole. An override reverses the display order of what follows it, so a name can be made to read as something it is not. Both are stripped now — the directional set only, because the joiner that holds multi-part emoji together is technically the same class of character and people put emoji in their names.

  • Link handling in message bodies now goes through the shared parser instead of a second, weaker copy that skipped the path checks every other surface applies.

Android was verified on-device against the live mesh: pages fetch and render, the cache takes the right branch, and startup eviction runs clean. The iOS build is compile-verified only.


Unsigned iOS build — sideload via AltStore / Sideloadly / SideStore.

Download Reticulum-iOS-1.0.110-unsigned.ipa and re-sign with your free Apple ID using your sideloading tool of choice. Apps signed with a free Apple ID expire after 7 days; AltStore can auto-renew while it's running on your Mac.

This app is not published to the App Store — see the iOS section of the README for the rationale.

Full Changelog: android-v1.2.116...ios-v1.0.110

ios-v1.0.109

ios-v1.0.109 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 02 Sep 12:06

Nodes reached by tapping a link show their real name.

Following a cross-node link called addManualDestination(hash, "(via cross-node link)"), and that function writes its label to userLabel — the user's private nickname. effectiveDisplayName is userLabel ?: displayName, so a user label outranks everything. The node's announce then arrived, the announce path filled displayName in with the real name exactly as it should, and the list went on showing the placeholder. Not until the announce landed — forever, because nothing ever cleared it.

Three parts:

  • addLinkedDestination — a separate entry point for a destination discovered by following something. It puts the name in displayName and never touches userLabel, so the first real announce replaces it. The same shortcut was in the QR-scan path and in three other link sites.
  • The hint is the link's own label. A micron link already carries the page author's words for the thing — "Amber Pages", "NomadForum" — so onLinkClick now carries (target, label) and the cross-node hop names the row with it. On iOS the label rides an extra query item on the internal link URL, which is the only channel between the renderer and the tap handler.
  • A repair migration (SQLDelight 12.sqm, Room v22→v23 on Android) clearing userLabel on rows carrying one of the four exact strings we wrote. Without it the fix would only help rows created from here on.

Also: nodes you merely pass through on the way to a page are no longer added to Favourites. Adding one by hand is an act of intent worth pinning; walking past one is not, and pinning those is what filled the lists. The new upsertLinkedStub inserts without favouriting and, on a row that already exists, changes nothing but hidden — so following a link to a node you have favourited does not un-favourite it.

Verified on Android against the live mesh: a search for "via" in the Nomad list returns only genuine names, and a cross-node hop lands on the node's announced name. The iOS build is compile-verified only.


Unsigned iOS build — sideload via AltStore / Sideloadly / SideStore.

Download Reticulum-iOS-1.0.109-unsigned.ipa and re-sign with your free Apple ID using your sideloading tool of choice. Apps signed with a free Apple ID expire after 7 days; AltStore can auto-renew while it's running on your Mac.

This app is not published to the App Store — see the iOS section of the README for the rationale.

Full Changelog: ios-v1.0.108...ios-v1.0.109

ios-v1.0.108

ios-v1.0.108 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 02 Sep 10:50

A room name that will not work is now refused where you type it, not discovered later.

RrcRoomName has been shared code since the Android 1.2.112 line; iOS never called it. Typing off topic into the join field produced a room the hub accepted and this client could not later share — a link's room segment is literal and a link in running text ends at the first space, so there is no way to write that room down. The only warning came at the point of sharing, long after the room existed.

Join is now disabled while a problem stands, with the reason under the field. The strings come from the shared problem(), so both platforms say the same thing.

Where the rule does not apply matters more than the rule. Typing a name in this field creates the room when the hub does not have it, which is the one place a local naming preference is legitimate. The browse sheet and shared room links reach rooms that already exist and are deliberately unfiltered: a room called off topic that somebody else made has to stay reachable from here, or a cosmetic preference becomes an interop bug — rooms that exist, that other clients are sitting in, silently unreachable on this one.

With this, the iOS Rooms parity list from 1.0.104 is empty: routing and linkifying (1.0.106), the share sheet (1.0.107), and name validation (this).


Unsigned iOS build — sideload via AltStore / Sideloadly / SideStore.

Download Reticulum-iOS-1.0.108-unsigned.ipa and re-sign with your free Apple ID using your sideloading tool of choice. Apps signed with a free Apple ID expire after 7 days; AltStore can auto-renew while it's running on your Mac.

This app is not published to the App Store — see the iOS section of the README for the rationale.

Full Changelog: ios-v1.0.107...ios-v1.0.108