Merge pull request #4 from matrix-org/use-cases

Add Client-Server v2 General API Design
pull/8/head
Kegsay 9 years ago
commit 51a7681ece

@ -1,303 +0,0 @@
#1: Lightweight IM client (no perm storage)
#2: Mobile IM client (perm storage)
#3: MIDI client
#4: Animatrix client
#5: Unity object trees
#6: Forum
#7: Social Network ("Walls", PMs, groups)
#8: Minecraft-clone
#9: Bug Tracking Software
#10: Global 'Like' widget, which links through to a room.
================
#1: Lightweight IM client (no perm storage)
-------------------------------------------
Description:
An IM client (think web client) with no way of persisting data beyond
a session (the instance a person is using the app).
Features:
Recent activity, Room screen (member list, etc), User page, just like
the web client.
Actions:
- Send a one-to-one message to someone.
- Accept an invite.
- Populate recent activity (all rooms joined with latest message + room names/aliases, rooms invited to + room names/aliases)
- Populate scrollback if click on room
- Populate member list if click on room + get presence updates for them
- Populate room name / topic if click on room
- Create an empty room.
- Join a room from an alias.
---
Action:
Send a one-to-one message to someone.
How:
Enter their username and hit Message. Taken to room page with invited user.
History displays that I've invited someone / joined the room. Enter a message
and hit send. Message appears in window.
::
Client Server
-- @user:domain -->
<--- room ID, ACK--
<-historical msgs--
-- msg,room ID --->
<--- ACK ----------
---
Action:
Accept an invite.
How:
Get list of invites. Click one of them to 'accept' it. May or may not want
room content.
::
Client Server
---- req invites ->
<--- [inv,inv] ----
---- accept inv -->
<--- ACK ----------
<--- room content-- (optional)
---
Action:
Populate recent activity (all rooms joined with latest message + room names/aliases, rooms invited to + room names/aliases)
How:
Request joined rooms with latest message and room name. Request rooms invited to. Possibly extra info like # joined members.
::
Client Server
---- req sync ---->
<---joined rooms--- {msg,name,alias,#members?}
<---invited rooms-- {name,alias}
---
Action:
Populate scrollback if click on room.
How:
Request scrollback for room.
::
Client Server
---- room id ----->
<--- scrollback ---
---
Action:
Populate member list if click on room + get presence updates for them.
How:
Click on room. Member list with names/presence/pics appears. May not want
pic.
::
Client Server
---- req mem list ->
<--- members ------- {name,pic,presence}
- monitor presence->
...
<- presence change--
<- presence change--
...
-- stop presence --->
---
Action:
Populate room name / topic if click on room.
How:
Click on room. Room name and topic with aliases appears. May not want topic
(eg screen size).
::
Client Server
---- req room info->
<--- room info ----- {name,topic,aliases}
---
Action:
Create an empty room.
How:
Type in room config (desired name, public/private, etc). Hit Create. Room is
created. Possibly get room info.
::
Client Server
---- mkroom{config}->
<--ACK{room_id}------
<-- room info ------- (optional)
---
Action:
Join a room from an alias.
How:
Type in alias. Hit Join. Room is joined. Possibly get room info.
::
Client Server
-- join{alias} ----->
<--ACK{room_id}------
<--room info--------- (optional)
===========================
#2: Mobile IM client (perm storage)
-----------------------------------
Description:
An IM client (think android/ios) which persists data on a database.
Features:
Recent activity, Room screen (member list, etc), User page, just like
the web client.
Actions:
- Send a one-to-one message to someone.
- Accept a stored invite.
- Populate recent activity (all rooms joined with latest message + room names/aliases, rooms invited to + room names/aliases)
- Populate scrollback if click on room
- Populate member list if click on room + get presence updates for them
- Populate room name / topic if click on room
- Create an empty room.
- Join a room from an alias.
---
Action:
Send a one-to-one message to someone (single room).
How:
Enter their username and hit Message. Taken to room page with invited user if no room exists,
else takes to existing room. History displays that I've invited someone or scrollback. Enter
a message and hit send. Message appears in window.
::
Client Server
-- @user:domain -->
<--- room ID, ACK--
<-historical msgs-- (optional; not if existing room)
-- msg,room ID --->
<--- ACK ----------
---
Action:
Accept a stored invite.
How:
Send invite to server. Get room content (or NO-OP if already joined).
::
Client Server
---- accept inv -->
<--- ACK ----------
<--- room content-- (optional)
---
Action:
Populate recent activity (all rooms joined with latest message + room names/aliases, rooms invited to + room names/aliases)
incrementally.
How:
Request recent activity diff. Get updated msg/name/#members for changed values only.
::
Client Server
- req sync{token}->
<---diff{rooms}---- {msg,name,alias,#members?}
---
Action:
Populate scrollback if click on room.
How:
Request scrollback for room. Either a diff or a page of scrollback
depending on cached data.
::
Client Server
-room id{latest event}-> {max msgs}
<--- scrollback -------- {fresh/incremental flag}
---
Action:
Populate member list if click on room + get presence updates for them.
How:
Click on room. Member list with names/presence/pics appears. May not want
pic.
::
Client Server
---- req mem list ->
<--- members ------- {name,pic,presence}
- monitor presence->
...
<- presence change--
<- presence change--
...
-- stop presence --->
---
Action:
Populate room name / topic if click on room.
How:
Click on room. Room name and topic with aliases appears. May not want topic
(eg screen size). Display cached info until updated.
::
Client Server
---- req room info->
<--- room info ----- {name,topic,aliases}
---
Action:
Create an empty room.
How:
Type in room config (desired name, public/private, etc). Hit Create. Room is
created. Possibly get room info.
::
Client Server
---- mkroom{config}->
<--ACK{room_id}------
<-- room info ------- (optional)
---
Action:
Join a room from an alias.
How:
Type in alias. Hit Join. Room is joined. Possibly get room info.
::
Client Server
-- join{alias} ----->
<--ACK{room_id}------
<--room info--------- (optional)

@ -0,0 +1,222 @@
Data flows for use cases
========================
::
<- Data from server to client
-> Data from client to server
Instant Messaging
-----------------
Without storage
~~~~~~~~~~~~~~~
::
Home screen
Data required on load:
<- For each room the user is joined: Name, topic, # members, last message, room ID, aliases
Data required when new message arrives for a room:
<- Room ID, message content, sender (user ID, display name, avatar url)
Data required when someone invites you to a room:
<- Room ID, sender (user ID, display name, avatar url), Room Name, Room Topic
Data required when you leave a room on another device:
<- Room ID
Data required when you join a room on another device:
<- Name, topic, # members, last message, room ID, aliases
Data required when your profile info changes on another device:
<- new profile info e.g. avatar, display name, etc.
Creating a room
-> Invitee list of user IDs, public/private, name of room, alias of room, topic of room
<- Room ID
Joining a room (and dumped into chat screen on success)
-> Room ID / Room alias
<- Room ID, Room aliases (plural), Name, topic, member list (f.e. member: user ID,
avatar, presence, display name, power level, whether they are typing), enough
messages to fill screen (and whether there are more)
Chat Screen
Data required when member name changes:
<- new name, room ID, user ID, when in the context of the room did this occur
Data required when the room name changes:
<- new name, room ID, old room name?
Invite a user:
-> user ID, room ID
<- display name / avatar of user invited (if known)
Kick a user:
-> user ID, room ID
<- what message it came after
Leave a room:
-> room ID
<- what message it came after
Send a message
-> Message content, room ID, message sequencing (eg sending my 1st, 2nd, 3rd msg)
<- actual content sent (if server mods it), what message it comes after (to correctly
display the local echo)
Place a call (receive a call is just reverse)
<- turn servers
-> SDP offer
-> Ice candidates (1 by 1; trickling)
<- SDP answer
<- Ice candidates
Scrolling back (infinite scrolling)
-> Identifier for the earliest message, # requested messages
<- requested messages (f.e change in display name, what the old name was), whether
there are more.
With storage
~~~~~~~~~~~~
::
Home Screen
On Load
-> Identifier which tells the server the client's current state (which rooms it is aware
of, which messages it has, what display names for users, etc..)
<- A delta from the client's current state to the current state on the server (e.g. the
new rooms, the *latest* message if different, the changed display names, the new
invites, etc). f.e Room: Whether the cache of the room that you have has been replaced
with this new state.
Pre-load optimisation (not essential for this screen)
-> Number of desired messages f.e room to cache
<- f.e Room: the delta OR the entire state
Bug Tracking
------------
::
Landing Page
On Load
<- Issues assigned to me, Issues I'm watching, Recent activity on other issues includes
comments, list of projects
Search for an issue (assume text)
-> Search string
<- List of paginated issues
Request page 2:
-> Page number requested
<- Page of paginated issues
Issue Page
On Load
-> Issue ID and Project ID (equiv to Room)
<- Issue contents e.g. priority, resolution state, etc. All comments e.g. user ID,
comment text, timestamp. Entire issue history e.g. changes in priority
Post a comment
-> Issue ID, comment content, Project ID (equiv to Room)
<- actual content sent (if modded), what comment it comes after
Set issue priority
-> Issue ID, Project ID, desired priority
<- What action in the history it came after
Someone else sets issue priority
<- Issue ID, Project ID, new priority, where in the history
Mapping model use cases to matrix models (Room, Message, etc)
=============================================================
To think about:
- Do we want to support the idea of forking off new rooms from existing ones? This
and forums could benefit from it.
Bug tracking UI
---------------
::
Projects => Rooms
Issues => Message Events
Comments => Message Events (relates_to key)
Projects:
- Unlikely that there will be 100,000s of issues, so having to pull in all the issues for a project is okay.
- Permissions are usually per project and this Just Works.
- New issues come in automatically and Just Work.
- Can have read-only members
Issues:
- Don't really want 1 Room per Issue, else you can have thousands of Rooms PER PROJECT, hence choice for
Issues as Messages. Don't need to join a room for each issue.
- Idea of issue owner is clear (sender of the message)
- Updating issues requires an additional event similar to comments (with ``relates_to``)? Could possibly
be state events? Don't really want all the history if say the priority was changed 1000 times, just want
the current state of the key.
Comments:
- Additional event with ``relates_to`` key.
Forum
-----
::
Forum => Room (with pointers to Board Rooms)
Boards => Room (with pointers to Thread Rooms)
Threads => Room
Messages => Message Events
Forum:
- Contains 10s of Boards.
- Contains special Message Events which point to different rooms f.e Board.
Boards:
- Contains 100s of Threads.
- Contains special Message Events which point to different rooms f.e. Thread.
Threads:
- Contains 100s of Messages.
Can't do this nicely with the current Federation API because you have loads of
Rooms and what does posting a message look like? Creating a thread is done by..?
The user who is posting cannot create the thread because otherwise they would be
the room creator and have ultimate privileges. So it has to be created by a bot
of some kind which ties into auth (Application services?). To follow a board,
you need a bot to join the Board Room and then watch it for changes...
Fundamental problem with forums is that there is only 1 PDU graph per room and
you either have to pull in lots of graphs separately or one graph and filter it
separately to get to the desired sub set of data. You have to subscribe into a
lot of graphs if you subscribe to a board... If you have the entire board...
good luck scrollbacking a particular thread.
Google+ Community
-----------------
::
Community => Room (with pointers to Category Rooms)
Category => Room
Post => Message Events
Comment => Message Events (relates_to key)
Community:
- Contains 10s of categories.
- Contains special Message Events which point to different rooms f.e Category.
- Moderators of the community are mods in this room. They are in charge of making
new categories and the subsequent rooms. Can get a bit funky if a mod creates a
category room without the same permissions as the community room... but another
mod can always delete the pointer to the buggy category room and make a new one.
- Do we want to support the idea of forking off new rooms from existing ones? This
and forums could benefit from it.
Category:
- Contains 1000s of posts.
- Same permissions as the community room. How to enforce? Fork off the community
room?
Posts:
- Contains 10s of comments.
This is similar to forums but you can more reasonably say "screw it, pull in the
entire community of posts."

@ -0,0 +1,14 @@
Matrix Spec Design Workflow
===========================
1. Write use cases
2. Design data flows for use cases
3. Design generic API (factoring out commonalities where possible)
4. Design transport-specific API with justifications
5. Formalise transport-specific API as swagger or similar
6. Evolve the generic API design doc and transport-specific API into the actual spec.

File diff suppressed because it is too large Load Diff

@ -0,0 +1,28 @@
::
+---------------+
| Room |
| "Room-ID" |
| {State} | +----------------------+
| Name------|-------->| Event m.room.name |
| Topic | | "Name" |
| [Aliases] | +----------------------+ +-------------+
| [Members]-|---+ +----------------------+ <----| Start Token |
| [Messages] | | | Event m.room.member | +-------------+
| | | | +---->| "invite/join/ban" |
+---------------+ | "User-ID" |
| | +----------------------+
| | +----------------------+
| | Message | Event m.room.message |
| +-------------->| {content} |<--+
| +----------------------+ |
| Comment +----------------------+ |
+------------------>| Event m.room.message | |
| {content} | |
| "relates-to"-------|---+ +-------------+
+----------------------+ <----| End Token |
+-------------+

@ -0,0 +1,314 @@
General UI/UX requirements:
===========================
- Live updates
- No flicker:
* Sending message (local echo)
* Receiving images (encoding w/h)
* Scrollback
* Resolving display names (from user ID)
- Fast startup times
- Fast "opening room" times (esp. when clicking through from a notification)
- Low latency file transfer.
Use cases
---------
- #1: Lightweight IM client (no perm storage) - e.g. Web client
- #2: Bug tracking software
- #3: Forum
- #4: Google + style communities
- #5: Email style threading
- #6: Multi-column threaded IM
- #7: Mobile IM client (perm storage)
- #8: MIDI client
- #9: Animatrix client
- #10: Unity object trees
- #11: Social Network ("Walls", PMs, groups)
- #12: Minecraft-clone
- #13: Global 'Like' widget, which links through to a room.
#1 Web client UI
================
Model::
Rooms ----< Messages
- name - type (call/image)
- topic
Home Screen
What's visible:
- Recent chats ordered by timestamp of latest event (with # users)
- Your own display name, user ID and avatar url
- A searchable list of public rooms (with # users and alias + room name + room topic)
What you can do:
- Create a room (public/private, with alias)
- Join a room from alias
- Message a user (with user ID)
- Leave a recent room
- Open a room
- Open a chat history link.
- Search for a public room.
Chat Screen
What's visible:
- Enough scrollback to fill a "screen full" of content.
- Each message: timestamp, user ID, display name at the time the message was
sent, avatar URL at the time the message was sent, whether it was a bing message
or not.
- User list: for each user: presence, current avatar url in the room, current
display name in the room, power level, ordered by when they were last speaking.
- Recents list: (same as Home Screen)
- Room name
- Room topic
- Typing notifications
- Desktop/Push Notifications for messages
What you can do:
- Invite a user
- Kick a user
- Ban/Unban a user
- Leave the room
- Send a message (image/text/emote)
- Change someone's power level
- Change your own display name
- Accept an incoming call
- Make an outgoing call
- Get older messages by scrolling up (scrollback)
- Redact a message
- Resend a message which was not sent
Message sending:
- Immediate local echo
- Queue up messages which haven't been sent yet
- Reordering local echo to where it actually happened
VoIP:
- One entry in your display for a call (which may contain duration, type, status)
- Glare resolution
Scrollback:
- Display in reverse chronological order by the originating server's timestamp
- Terminates at the start of the room (which then makes it impossible to request
more scrollback)
Local storage:
- Driven by desire for fast startup times and minimal network traffic
- Display messages from storage and from the network without any gaps in messages.
- Persist scrollback if possible: Scrollback from storage first then from the
network.
Notifications:
- Receive notifications for rooms you're interested in (explicitly or from a default)
- Maybe per device.
- Maybe depending on presence (e.g. idle)
- Maybe depending on message volume
- Maybe depending on room config options.
Message contents:
- images
- video
- rich text
- audio
- arbitrary files
- location
- vcards (potentially)
Chat History Screen
What's visible:
- The linked message and enough scrollback to fill a "screen full" of content.
- Each message: timestamp, user ID, display name at the time the message was
sent, avatar URL at the time the message was sent, whether it was a bing message
or not.
- The historical user list. *TODO: Is this taken at the linked message, or at
wherever the user has scrolled to?*
What you can do:
- Get older messages by scrolling up (scrollback)
- Get newer messages by scrolling down
Public Room Search Screen
What's visible:
- The current search text.
- The homeserver being searched (defaults to the HS the client is connected to).
- The results of the current search with enough results to fill the screen
with # users and alias + room name + room topic.
What you can do:
- Change what you are searching for.
- Change the server that's being searched.
- Scroll down to get more search results.
User screen
What's visible:
- Display name
- Avatar
- User ID
What you can do:
- Start a chat with the user
#2 Bug tracking UI
==================
Model::
Projects ----< Issues ---< Comments
- key - summary - user
- name - ID - message
SYN SYN-52 Fix it nooow!
Landing page
What's visible:
- Issues assigned to me
- Issues I'm watching
- Recent activity on other issues (not refined to me)
- List of projects
What you can do:
- View an issue
- Create an issue
- Sort issues
- View a user
- View a project
- Search for issues (by name, time, priority, description contents, reporter, etc...)
Issue page
What's visible:
- Summary of issue
- Issue key
- Project affected
- Description
- Comments
- Priority, labels, type, purpose, etc..
- Reporter/assignee
- Creation and last updated times
- History of issue changes
What you can do:
- Comment on issue
- Change issue info (labels, type, purpose, etc..)
- Open/Close/Resolve the issue
- Edit the issue
- Watch/Unwatch the issue
#3 Forum UI
===========
Model::
Forum ----< Boards ----< Threads ----< Messages
- Matrix - Dev - HALP! - please halp!
Main page
What's visible:
- Categories (containing boards)
- Boards (with names and # posts and tagline and latest post)
What you can do:
- View a board
- View the latest message on a board
Board page
What's visible:
- Threads (titles, OP, latest post date+author, # replies, # upvotes, whether
the OP contains an image or hyperlink (small icon on title))
- Whether the thread is answered (with link to the answer)
- Pagination for posts within a thread (1,2,3,4,5...10)
- Pagination for threads within a board
- List of threads in chronological order
- Stickied threads
What you can do:
- View a user
- View a thread on a particular page
- View the latest message on a thread
- View older threads (pagination)
- Search the board
Thread page
What's visible:
- Messages in chronological order
- For each message: author, timestamp, # posts by author, avatar, registration
date, status message, message contents, # views of message
What you can do:
- Upvote the message
- Flag the message for a mod
- Reply to the message
- Subscribe to thread or message's RSS feed
- Go to previous/next thread
#4 Google+ community
====================
Model::
Community -----< Categories ----< Posts ---< Comments
Kerbal SP Mods, Help Text Text
(no title!)
Communities page
What's visible:
- List of communities
- For each community: # users, # posts, group pic, title
What you can do:
- Join a community
- View a community
Community Page
What's visible:
- Title, pic
- List of categories
- List of members with avatars (+ total #)
- Most recent posts with comments (most recent comment if >1)
What you can do:
- Join the group
- Post a post (with voting and options)
- Report abuse
- View member
- Expand comments
- Infinite scrolling
- Add a comment to a post
- Share a post
- +1 a post
#5 Email style threading
========================
Chat Screen
What's visible:
- Enough scrollback to fill a "screen full" of content.
- Threads:
- Initially will only display the timestamp and user ID of the *first*
message. But can expand to show the entire tree.
- Tree of messages indicating which message is a reply to which.
- Ordered by the arbitrary field (timestamp of oldest message in thread;
newest message in thread; sender id; sender display name; etc)
- Each message: timestamp, user ID, display name at the time of the message
- Room name
- Room topic
- Typing notifications
- Desktop/Push Notifications for messages
What you can do:
- Send a message in reply to another message:
- Immediate local echo, may cause messages to re-order
- Messages that haven't reached the server are queued.
- Thread is displayed where it should be in the thread order once the
message is sent.
- Start a new thread by sending a message.
#6 Multi-threaded IM
====================
Chat Screen
What's visible:
- A multi-column grid of threads from a number of chatrooms
Each concurrent thread is displayed in a different column.
The columns start and end as threads split and rejoin the main conversation
The messages for each thread are ordered by how recent they are::
Room #1 Room # 2 Room # 2
+------------+ +----------------+ Side thread.
| * Message1 | | * Root | +--------------+
| * Message2 | | * A1 -> Root | | * B1 -> Root |
+------------+ | * A2 -> A1 | | * B2 -> B1 |
| * M -> A2, B2 | +--------------+
+----------------+
- Typing notifications. Displayed within the correct thread/column.
What you can do:
- Send a message into a particular thread/column.
- Move an *existing* message into a new thread creating a new column
- Move an existing message into an existing thread, causing the threads to
reconverge (i.e. provide a route from the sidebar back into the existing
thread). This does not imply terminating the thread, which can continue
independently of the merge.
Loading…
Cancel
Save