- Replace the sidebar-based MainChatView with MainTabView: a custom
bottom bar with Контакты / Звонки / Чаты / Настройки that looks the
same on iOS and macOS, and open chats via push navigation.
- Put the search field above the chat and contact lists (searchable on
iOS, an inline field on macOS) and add an aggregated call-history
screen backed by model.callHistoryMessages.
- Embed SettingsView as a tab, update verify.sh guards, and keep CI on
deterministic unit tests while the UI tests stay runnable manually.
- Lock only when the scene really backgrounds: transient inactive
states (system photo picker, app switcher) no longer swap in the
lock screen and break gallery selection on iOS.
- Cache biometric availability once per session off the main thread
instead of calling LAContext.canEvaluatePolicy in view bodies,
which froze the macOS lock screen, and auto-prompt biometrics on
iOS only.
- Keep UI tests as an opt-in target and guard both fixes in
verify.sh.
- Gate every layer behind AppLockView when the lock is enabled and
lock on launch and on backgrounding; the passcode lives only in the
Keychain (AppLockVault) and the enable state defaults to off.
- Add the lock section to Settings: enable/setup, change passcode and
disable all require the current passcode via a shared passcode
sheet; Face ID / Touch ID unlock prompts automatically and can be
toggled with passcode confirmation.
- Add NSFaceIDUsageDescription to both app targets, cover the passcode
policy with tests, guard the feature in verify.sh and document it in
SECURITY.md.
Server information (Monal-style):
- Add ServerInformation model and ServerInfoView reachable from
Settings,
showing server software (XEP-0092), disco#info identities and
features,
conference (MUC) services via disco#items, and STUN/TURN via XEP-0215.
- Add a curated XEP capability list with per-XEP success/error status
derived
from server/account disco features and connection flags.
- Detect PEP (0163) from account disco pubsub#* features, HTTP Upload
(0363)
from the main domain plus its components, and add Roster Versioning
(0237),
Pre-Authenticated Roster Subscription (0379), and SASL SCRAM Downgrade
Protection (0474, neutral because Martin does not expose SSDP).
Connection statistics:
- Add LumaConnectionStatsModule, an XmppStanzaFilter registered before
stream
management, to count sent / acknowledged / received stanzas.
- Track last login and SMACKS session timestamps, and read SASL
mechanisms
and Client State Indication from the raw stream features.
MAM / OMEMO handling:
- Prefer a plaintext <body> fallback when OMEMO decryption fails instead
of
showing "failed to decrypt".
- Keep the optimistic text of our own outgoing message when its echo
cannot
be decrypted back, instead of replacing it with a placeholder.
Emoji picker:
- Add EmojiCatalog and a cross-platform EmojiPickerView.
- Open the picker for reactions (replacing the static quick list) and
from
the composer's smiley button, inserting the chosen emoji into the
draft.