Skip to content

Chapter 3 — Conversations & Messaging

This chapter covers the Messages area of the app: the conversation list, one-to-one chat, delivery tracking, attachments, voice notes, reactions, and message retry behavior.

3.1 The Messages screen

The Messages screen is the app's home. On phones it is a single list; on wide screens (tablets, desktop) it becomes a two-pane layout with the conversation list on the left and the open chat on the right, and on very wide screens a third Thread detail panel appears.

Mesh status banner

At the top of the list a live banner summarizes the mesh:

  • "Mesh online · N people reachable", with a breakdown of how many are direct and how many are reachable through a relay.
  • "Mesh quiet · finding your team" when nobody is currently reachable.

Tapping the banner opens a detail sheet with the counts (Reachable / Direct links / Through a relay) and a short explainer of how the mesh works.

  • Filter pills: All, People, Groups.
  • The search icon opens a search bar ("Search conversations…") that filters by name.

Quarantine notice

If any messages are being held in quarantine, an amber Quarantine row with a count appears above the list. Tapping it opens the Quarantine screen (see Chapter 7).

Conversation rows

Each 1:1 conversation row shows:

  • The person's avatar with a reach ring (green = direct, amber = via relay, grey = finding a route). Rows for currently unreachable peers are dimmed.
  • Their name, with a check mark if the peer is trusted.
  • The last message preview. For your own last message a small status icon precedes it (delivered, sent, retrying, failed, etc.).
  • A timestamp and either an unread-count badge or a live reach meter.

Group conversations use a square avatar and show the member count.

Starting a conversation

Tap the compose icon (New message) to open the people picker. People are grouped by how reachable they are right now:

  • DIRECT · INSTANT — direct, strong links.
  • THROUGH A RELAY — reachable with a short delay ("1 relay away" / "N relays away").
  • FINDING A ROUTE — not currently reachable; shows when they were last heard.

From the same screen, New group creates a group (see Chapter 4).

3.2 The chat view

The chat header shows the person's name, their trust status (TRUSTED pill), and a live link-quality line:

  • "Connected directly · strong link"
  • "Through 1 relay · a short delay" (or "Through N relays")
  • "Finding a route…"

The info button in the header opens the Connection detail sheet — a route diagram, signal strength, which radio the conversation is being carried over, round-trip time, and when the peer was last heard. It also offers Block/Unblock for the peer (see Chapter 7).

Inside the conversation:

  • Date separators mark each day.
  • Route-change banners appear when the path to the peer changes mid-conversation — e.g. "Now relaying over LoRa" when the direct WiFi link drops, or "Back on WiFi" when it recovers. This keeps operators aware of link quality without any radio jargon.

3.3 Delivery tracking

The delivery track (1:1 messages)

Every outgoing 1:1 message carries a three-stage track: Sent → Relayed → Delivered.

Track state Meaning
Sent The message has been handed to the mesh.
Held on relay The recipient is offline; the message is stored on a relay and will be delivered when they return. An amber "Held safe on the mesh — delivers the moment ‹name› is back online" card reinforces this.
Delivered · HH:MM Cryptographic delivery proof received from the recipient's device.
Retrying… A Priority/Critical message is being retried.
Not delivered The message failed (see delivery modes below for what happens next).

Delivery confirmation is end-to-end: Delivered means the recipient's device cryptographically acknowledged receipt, not merely that a server accepted the message (there is no server).

Message status values

Administrators integrating with the API or reading logs will encounter the underlying status values:

sending, sent, path_requested, queued, retrying, delivered, unconfirmed, failed, failed_permanent, cancelled.

  • unconfirmed is a soft timeout: the delivery window elapsed without proof. The message may still arrive, and a late delivery proof will still flip it to delivered.
  • Delivery timeout windows are computed per-route: baseline 30 s plus 15 s per hop, multiplied ×4 on LoRa links (×1.5 on WiFi), or 5× the measured average round-trip time, capped at 10 minutes. Unknown routes use 180 s.

3.4 Delivery modes

Open the + button in the composer and choose under HOW IT SENDS:

Mode Behavior
Standard (default) Delivers as soon as there's a path. If the recipient is unreachable, the send fails immediately — but see automatic recovery below.
Priority "Held on a relay if they're offline." Queued and retried automatically every 60 seconds, up to 10 attempts, then marked permanently failed.
Critical "Keeps retrying until it's delivered." Retried every 60 seconds indefinitely until delivered or you cancel. Critical messages are visually marked with a red accent bar, and show a CANCEL action while queued or retrying.

The selected mode applies to subsequent sends in that conversation and resets to Standard when you switch conversations.

Automatic recovery of failed messages

When a peer who has failed Standard messages comes back on the air (their device announces itself), Stolo automatically re-queues that peer's failed Standard messages from the last 24 hours (up to 10 per announce) using Priority-style retries. Operators do not need to manually resend after a coverage gap.

3.5 Attachments

Attachments are available in 1:1 conversations (not groups). Tap + in the composer:

Option Behavior
Photo "Auto-sized to the link — LoRa-safe." Images are automatically recompressed based on the path to the recipient: LoRa tier (160 px, ≤32 KB) for direct LoRa links, Medium (320 px, ≤256 KB) for multi-hop or unknown paths, High (1920 px, ≤8 MB) for direct WiFi/internet links. Before sending over LoRa, an estimated airtime is shown.
File Any file. If the path may include LoRa and the file exceeds 32 KB, a Large file warning shows the size and estimated airtime and asks for confirmation — large files may fail or congest a LoRa channel.
Voice note Recorded from the mic in the message bar (see below).
Location Coming soon.

Notes for administrators:

  • The maximum accepted inbound attachment size is 16 MB; oversized attachments are dropped by the receiving engine.
  • Received images are decoded within strict memory bounds, and incoming filenames are sanitized before being written to disk — hostile filenames cannot escape the app's media directory. Received files open with the operating system's default handler only when the user taps them.

3.6 Voice messages (push-to-talk)

With an empty message field, the composer shows a mic button: press and hold to record, release to send (slide away/release early to cancel; recordings under half a second are discarded). A red "Recording 0:07 — release to send" banner shows the duration while recording.

  • Audio is encoded as Opus (mono, 16 kHz) — compact enough to travel well over constrained links.
  • Playback is a compact bubble with play/pause, a progress bar, and the duration. Only one voice note plays at a time.
  • The first use prompts for microphone permission.

3.7 Reactions

Long-press any message in a 1:1 conversation to react with one of: 👍 ❤️ 😂 😮 😢 🙏. Tap an existing reaction chip to toggle your own reaction off. Reactions are exchanged as single, encrypted packets — they are lightweight enough to work well even over LoRa.

3.8 The Thread panel (wide layouts)

On wide screens, tapping a message opens the Thread panel showing full message details: exact time, status, measured round-trip time, and — for group messages — per-member delivery status.

3.9 Emergency SOS

Stolo includes an opt-in distress beacon. It is off by default so teams that only need encrypted messaging never see it; enable it under Settings → Safety → Emergency SOS.

Triggering

When enabled, an SOS · HOLD button appears on the home (Comms) screen. It requires a deliberate press-and-hold of about 1.5 seconds — a single tap can never fire the beacon, and releasing early or sliding off the button cancels the arm.

What SOS does

While active, Stolo broadcasts a distress message to every known peer on every radio, as a Critical-mode message (retried until delivered):

"SOS — ‹name› requires immediate assistance · ‹latitude, longitude›"

The broadcast repeats every 60 seconds, each cycle preceded by a network announce so relays refresh their route to you. A full-screen SOS ACTIVE overlay shows:

  • LOCATION — your coordinates (or "acquiring…" until a GPS fix exists).
  • RELAYED TO — the number of confirmed hand-offs to the mesh. This deliberately reads "no confirmation yet" until at least one confirmation exists — Stolo never implies help is coming when it isn't. Note this counts confirmed hand-offs from your device to the mesh, not confirmed delivery to each peer; per-peer delivery shows in the conversations themselves.
  • ELAPSED — time since activation.

Standing down

Tap Cancel broadcast to stand down. Stolo stops the beacon and sends every peer a Priority stand-down message: "SOS STAND-DOWN — ‹name› has cleared the emergency." The beacon stays active until you stand down; a cancel always wins, even if it lands mid-broadcast.