* Windows installer, Linux AppImage and .deb
The release now also publishes:
- sotto-windows-x64-setup.exe (Inno Setup): per-user install without
administrator rights, Start menu entry, uninstaller (which also removes
the start-at-login entry), updates in place and keeps the user's data;
- sotto-linux-x86_64.AppImage (appimagetool and its runtime at pinned
versions, checked by SHA-256);
- sotto-linux-amd64.deb (/opt/sotto, a menu entry and icon, dependencies
worked out from the binaries).
Linux builds move to Ubuntu 22.04, so they run on Ubuntu 22.04+ and
Debian 12+ (a 24.04 build needs glibc 2.38). CI builds all three for
every pull request and installs the .deb. Inside an AppImage, "Start
Sotto when I log in" now starts the AppImage file itself.
The app, the web downloads page and the header links download from the
latest GitHub release, so nothing has to be copied to the server.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PCmtpGum21deTqmznzR49e
* Website for sottocall.com
A static, tracker-free page: what Sotto is, how it works, downloads (from
the latest GitHub release: APK, Windows installer, AppImage, .deb, browser),
privacy in plain words with links to the policy and terms. No cookies, no
scripts, nothing from other sites; light and dark; checked at phone and
desktop widths. website/README.md has the Nginx setup.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PCmtpGum21deTqmznzR49e
* Bandwidth adaptation and audio-only fallback
Each side watches its own upload (send loss reported by the other side,
round trip, and WebRTC's bandwidth estimate) and steps its video down:
full, reduced (500 kbit/s), low (150 kbit/s), then paused, so a weak
connection keeps the voice. It steps down quickly and back up slowly.
The other side is told (end-to-end encrypted call.video message) and
shows "Video paused: weak connection" instead of a frozen picture.
Level changes are queued: the browser rejects encoding parameters read
before an earlier change finished (found by the new adapt.mjs e2e test,
which drives the levels through a test hook in SOTTO_TEST_HOOKS builds).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PCmtpGum21deTqmznzR49e
* Polish the app's look, especially on phones
A calmer, more professional theme: neutral surfaces with white (or deep
grey) cards, consistent rounded corners, taller buttons, outlined fields
and a clearer navigation bar. Shared pieces (notice card, empty state,
section label, coloured initials) keep the screens consistent.
- Header: initials with a status dot; "Online · practice" under the
name on phones, and an icon-only download button.
- Home: notices put their action below the text instead of squeezing it
beside it; full-width video and voice call buttons.
- Contacts and History: empty states, grouped lists, coloured avatars
and call icons. Settings: each section is a labelled card.
- Onboarding: a headline and three short points; Start comes before the
browser notice, and the profile step goes straight to the form.
- The download menu named the old .zip and .tar.gz files although it
links to the Windows installer and the AppImage.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PCmtpGum21deTqmznzR49e
* CI: fix the Linux build's apt conflict on ubuntu-22.04
The 22.04 runner image ships libunwind-14-dev, which conflicts with the
libunwind-dev that libgstreamer1.0-dev depends on, so apt refused to
install the build dependencies. Remove it first (CI and release).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PCmtpGum21deTqmznzR49e
* Call link page: clearer design, a home button, app downloads, and calls without a camera
The page opened from someone's call or contact link gets the app's new
look: who you are calling in a card with large video and voice buttons,
"No account · No install · Nothing kept", and a header with the Sotto
logo (back to the start page), the app downloads and the server status.
A device without a usable camera (a desktop with no webcam, or a camera
that is blocked or busy) no longer fails the whole call: it joins with
the microphone alone and still receives the other side's video. When
even the microphone can't be opened, the message says why in plain
words (none found, blocked, or in use) instead of the browser's error.
New e2e test nocamera.mjs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PCmtpGum21deTqmznzR49e
* Short call and contact links
Call and contact links now carry only the person's signing key (their
relay address), so they shrink from about 310 to about 75 characters:
https://call.sottocall.com/?call=<43 characters> dials right away
https://call.sottocall.com/#c=<43 characters> shows who first
Whoever opens one asks that person's app, through the relay, for their
card, name and organisation. The request holds only the requester's
public card; the reply is an ordinary sealed envelope, accepted only when
it is signed by the key in the link, so it is as trustworthy as the full
links. Only the professional's app answers (rate limited); the person
must be online, as for a call. Full links are still accepted everywhere.
The contact link now always shows the current name.
Documented in docs/PROTOCOL.md §5.9; unit tests for the link format and
the lookup (including a reply signed by the wrong key).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PCmtpGum21deTqmznzR49e
* Guest page: the same header as the call link page
The guest waiting room gets the visitor header: the Sotto logo as a
home button, the app downloads, the server status, and "Call with <name>"
beside the logo on wider screens. The header is hidden during the call,
so its logo can't take the guest out of the call, and the device check
no longer repeats the logo.
Also keeps the call link page's texts separate for screen readers: the
card merged them into one label, which hid "Call <name>" (found by the
WebKit e2e test).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PCmtpGum21deTqmznzR49e
* Version 0.1.7
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PCmtpGum21deTqmznzR49e
---------
Co-authored-by: Claude <noreply@anthropic.com>