Revolt Frontend

Welcome to the developer documentation for the Revolt frontend.

This is very much incomplete and needs more work!

Feature Matrix

Comparison of implemented features across Revolt's clients.

CategorySubcategoryFeature ReviteFrontendAndroidiOSPriority
AuthorisationLogin Log into an accountP0 Must
   Create an accountP0 Must
   Send password resetP0 Must
   Resend email verificationP0 Must
   Confirm password resetUnapplicable
   Confirm email verificationUnapplicable
   Confirm account deletionUnapplicable
 Multi-Factor Authentication Use PasswordP0 Must
   Use TOTPP0 Must
   Use RecoveryP0 Must
 Session Lifecycle Spec Compliant🚧P0 Must
HomeGeneralHomeLaunch PageP0 Must
   Saved NotesP0 Must
  FriendsList Friends & BlockedP0 Must
   List Pending Requests🚧P0 Must
   Accept Requests🚧P0 Must
   Send Requests🚧P0 Must
   Remove / Block Users🚧P0 Must
   Unblock Users🚧P0 Must
   Quick Actions for UsersP0 Must
  User ProfileShow ProfileP0 Must
   Mutual FriendsP1 Preferred
   Mutual GroupsP1 Preferred
   Mutual ServersP1 Preferred
  GroupsList ConversationsP0 Must
   Create GroupP0 Must
   Show Group MembersP0 Must
   Edit SettingsP0 Must
ServersServer List User HomeP0 Must
   Unread ConversationsP0 Must
   List ServersP0 Must
   Reorder Servers🚧P1 Preferred
   Create ServerP0 Must
   Join ServerP0 Must
   Revolt DiscoverP0 Must
 Roles Coloured UsernamesP0 Must
 Users Change Server AvatarP1 Preferred
   Change NicknameP1 Preferred
 SettingsBasic InformationUpdate InformationP1 Preferred
   Update IconP1 Preferred
   Update BannerP1 Preferred
   Update System Message TargetsP1 Preferred
   Update CategoriesP1 Preferred
  RolesCreate RoleP1 Preferred
   List RolesP1 Preferred
   Delete RoleP1 Preferred
   Update Role InformationP1 Preferred
   Update PermissionsP1 Preferred
  CustomisationCreate EmojiP2 Best Effort
   List EmojiP2 Best Effort
   Delete EmojiP2 Best Effort
  UsersList MembersP2 Best Effort
   Set RolesP2 Best Effort
   Create InviteP0 Must
   List InviteP2 Best Effort
   Delete InviteP2 Best Effort
  BansList BansP1 Preferred
   Pardon UserP1 Preferred
  Delete Server P1 Preferred
ChannelsInterfaceChannel InformationView Channel DescriptionP1 Preferred
   Age GateP0 Must
 ServerLeft SidebarServer InformationP0 Must
   View Server DescriptionP1 Preferred
   List ChannelsP0 Must
   Channel CategoriesP0 Must
   Channel IconsP1 Preferred
  Member ListView MembersP0 Must
   Hoisted RolesP0 Must
 Messaging (Text Channel)Read MessagesLoad Recent MessagesP0 Must
   Inline Badges🚧🚧P1 Preferred
   Inline Pronouns🚧Unapplicable
   MasqueradeP1 Preferred
   Show MentionsP0 Must
   Show Channel LinksP0 Must
   Show Server LinksP3 Unimportant
   Show Message LinksP3 Unimportant
   Show RepliesP0 Must
   Show ReactionsP0 Must
   Attachments🚧P0 Must
   Embeds🚧P0 Must
   System🚧P1 Preferred
   InvitesP1 Preferred
  Quick ActionsReplyP0 Must
   ReactP1 Preferred
   Copy TextP0 Must
   Copy LinkP0 Must
   Copy IDP0 Must
   Mark as unreadP1 Preferred
   QuoteP3 Unimportant
   EditP0 Must
   DeleteP0 Must
  Read Chat HistoryLoad Older MessagesP0 Must
   Jump to EndP1 Preferred
   Jump to MessageP2 Best Effort
   Search MessagesP2 Best Effort
  Message CompositionSend MessagesP0 Must
   Reply to MessagesP0 Must
   Pick EmojiP2 Best Effort
   Pick GIF🚧P3 Unimportant
   Autocomplete Channel🚧P1 Preferred
   Autocomplete User🚧P1 Preferred
   Autocomplete Emoji🚧P1 Preferred
   Send FilesP0 Must
   Preview files to send🚧P1 Preferred
   Show messages being sentP1 Preferred
   Retry sending failed messagesP2 Best Effort
   Show attachments being sentP2 Best Effort
   Cancel message being sentP3 Unimportant
 Settings Update InformationP2 Best Effort
   Set IconP2 Best Effort
   Edit Role PermissionsP2 Best Effort
   Edit Group PermissionsP2 Best Effort
MarkdownRSM Basic StylesP0 Must
   Code BlocksP1 Preferred
   Code FormattingP1 Preferred
   Block QuotesP1 Preferred
   SpoilersP1 Preferred
   LinksP1 Preferred
   HeadingsP2 Best Effort
   TablesP2 Best Effort
   ListsP2 Best Effort
   KaTeXP2 Best Effort
   TimestampsP2 Best Effort
   Unicode EmojiP1 Preferred
   Custom Emoji🚧P1 Preferred
User SafetyReporting Report MessageP0 Must
   Report ServerP0 Must
   Report UserP0 Must
SettingsUserAccountUpdate UsernameP1 Preferred
   Update EmailP1 Preferred
   Update PasswordP1 Preferred
   Configure MFA RecoveryP2 Best Effort
   Configure MFA TOTPP2 Best Effort
   Disable AccountP0 Must
   Delete AccountP0 Must
  ProfileUpdate AvatarP1 Preferred
   Update BackgroundP1 Preferred
   Update BioP1 Preferred
  SessionsList SessionsP2 Best Effort
   Delete SessionP2 Best Effort
   Log out all other sessionsP2 Best Effort
 ClientAppearanceCustomise ThemeP2 Best Effort
   Customise FontP3 Unimportant
   Customise Emoji PackP3 Unimportant
  NotificationsDesktopP0 Must
   Web PushN/AP0 Must
   Desktop Native PushP3 Unimportant
   Mobile Native PushP0 Must
  Language P2 Best Effort
  Settings Sync P0 Must
  DesktopStart with ComputerN/AN/AP2 Best Effort
   Minimise to TrayN/AN/AP2 Best Effort
 RevoltBotsCreate BotP3 Unimportant
   List BotsP3 Unimportant
   Update InformationP3 Unimportant
   Update IconP3 Unimportant
   Invite to Server / GroupP3 Unimportant
 MiscFeedback Information P1 Preferred
  Changelogs P2 Best Effort
  Source code Unapplicable
  Log out P0 Must

Session Lifecycle

To ensure reliability for users on Revolt, clients should implement the following rigid specification for maintaing a session. At a high-level, it should be implemented as a state machine.

flowchart TD
subgraph LOGGED_IN[Logged In - Display Client UI]
CONNECTED
CONNECTING
RECONNECTING
DISCONNECTED
OFFLINE
...
end

subgraph LOGGED_OUT[Logged Out - Display Auth Flow or Loading Indicator]
READY
LOGGING_IN
ONBOARDING
DISPOSE
ERROR
end

READY -->|LOGIN_UNCACHED| LOGGING_IN
READY -->|LOGIN_CACHED| CONNECTING
LOGGING_IN -->|NO_USER| ONBOARDING
LOGGING_IN -->|PERMANENT_FAILURE| ERROR
LOGGING_IN -->|TEMPORARY_FAILURE| ERROR
ONBOARDING -->|CANCEL| DISPOSE
DISPOSE -->|READY| READY
ERROR -->|DISMISS| DISPOSE

LOGGING_IN -->|SOCKET_CONNECTED| CONNECTED
RECONNECTING -->|SOCKET_CONNECTED| CONNECTED
CONNECTING -->|SOCKET_CONNECTED| CONNECTED

ONBOARDING -->|USER_CREATED| LOGGING_IN
CONNECTED -->|TEMPORARY_FAILURE| DISCONNECTED
DISCONNECTED -->|RETRY| RECONNECTING
DISCONNECTED -->|DEVICE_OFFLINE| OFFLINE
RECONNECTING -->|TEMPORARY_FAILURE| DISCONNECTED
CONNECTING -->|TEMPORARY_FAILURE| DISCONNECTED
CONNECTING -->|PERMANENT_FAILURE| ERROR
RECONNECTING -->|PERMANENT_FAILURE| ERROR
OFFLINE -->|DEVICE_ONLINE| RECONNECTING

... -->|LOGOUT| DISPOSE

Implementation Details

The table below describes how each node should behave.

  • All nodes SHOULD have corresponding visual feedback.
  • Nodes MAY have effects on entry.
  • You SHOULD keep track of additional state such as:
    • Number of connection failures
NodeUser InterfaceLogic
READYShow login interfaceMay transition out by external source.
LOGGING_INShow loading indicatorOn entry, try to authenticate the user.
ONBOARDINGShow username selectionMay transition out by external source.
ERRORShow the permanent error with option to dismiss itMay transition out by external source.
DISPOSEShow loading indicatorDispose current client and create a new one.
CONNECTINGShow client UI with banner "Connecting"On entry, try to connect socket.
CONNECTEDShow client UIMay transition out by external source.
Set connection failures to .
DISCONNECTEDShow client UI with banner "Disconnected"May transition out by external source.
Increment connection failures by .

If the device is offline, trigger transition to OFFLINE.

On entry, set a timer to retry.
On exit, cancel timer.
RECONNECTINGShow client UI with banner "Reconnecting"On entry, invalidate cached data (message history, members list) and try to connect socket.
OFFLINEShow client UI with banner "Device offline"May transition out by external source.

Please use the formula for the delay where is failure count.

// JavaScript implementation
let retryIn =
  (Math.pow(2, connectionFailureCount) - 1) * (0.8 + Math.random() * 0.4);
let retryInMs = retryIn * 1e3;
setTimeout(() => reconnect(), retryInMs);

The following listeners need to be registered that emit the given transitions:

ListenerTransition
Connected to Revolt (and initial data loaded)SOCKET_CONNECTED
Connection to Revolt droppedSOCKET_DROPPED
Received logout event from socketLOGOUT
Connection failedTEMPORARY_FAILURE
Connection failed (session invalid)PERMANENT_FAILURE
Device has gone onlineDEVICE_ONLINE

Socket Details

When implementing your WebSocket connection, you should also implement the following:

  • A heartbeat mechanism that sends the Ping event every 30 seconds, and disconnects if a Pong event is not received within 10 seconds.
  • A connection timeout mechanism that drops the WebSocket connection if no message is received within 10 seconds of initiating the connection.

User Experience Considerations

  • While not strictly relevant to session lifecycle, if you encounter BlockedByShield during login, you should provide a link to the relevant support article.
  • Upon encountering a permanent error (session invalid), you should use the known user information to fetch their current flags. This way the message can be tailored to display if: they have been logged out, they disabled their account, their account has been suspended, or their account has been banned.
  • When a logout event is received externally, show some sort of indicator that they have been logged out beyond just kicking them to the login screen.
  • If the connection failure count reaches or more, query the health service for any outage information. This point is WIP, need considerations about increasing polling rate while connection failures are high, etc.