GithubHelp home page GithubHelp logo

comme2e / comm Goto Github PK

View Code? Open in Web Editor NEW
258.0 10.0 28.0 212.79 MB

Comm is the working name of this open source messaging project.

Home Page: https://comm.app

License: BSD 3-Clause "New" or "Revised" License

JavaScript 76.83% CSS 1.85% Java 0.86% Objective-C 0.06% Ruby 0.06% Shell 0.49% HTML 0.08% Starlark 0.01% C 0.01% Swift 0.12% C++ 8.40% CMake 0.22% Objective-C++ 1.24% Dockerfile 0.20% Groovy 0.05% Rust 8.21% Nix 0.23% HCL 0.89% Kotlin 0.17% Python 0.02%
flowtype javascript nodejs react-native rust

comm's People

Contributors

adartulloch avatar andnasnd avatar ashoat avatar atulsmadhugiri avatar barthap avatar benschac avatar def-au1t avatar dependabot[bot] avatar dereknelson avatar geekbrother avatar ginsueddy avatar inkaalicja avatar jakub-kedra-swm avatar jimpo avatar jonringer avatar jonringer-comm avatar karol-bisztyga avatar katpo avatar kosmydel avatar marcinwasowicz avatar michalgniadek avatar palys-swm avatar pklatka avatar pweglik avatar rohank6 avatar vdhanan avatar wyilio avatar xsanm avatar yayabosh avatar zrebcu411 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

comm's Issues

Default notif settings

Right now notif settings can be customized on a per-thread basis, but whenever you are added to a new thread (or create one) the default is { pushNotifs: true, home: true }. It would be cool if you could customize the default, separately for single-person threads and multi-person threads.

Simple replies

This task depends on first building out message formatting for Markdown quoting syntax ("> quote"), see #37.

Once this syntax is supported, it should be possible to reply to a message by swiping it (native), or by pressing it and selecting an option from the resultant dropdown (web/native).

Tree view

It would be cool if you can see a thread in the context of its ancestors and descendants. This "tree view" would look sort of like a Reddit thread, with child threads appearing nested within their parents. It should be possible to scroll up, down, left, and right in this tree view.

Friend list / block list

Right now: everybody is "friends" with everybody. Anybody can start a thread with anybody. You don't have a friend list - there is just a list of threads, each of which contains one or more users.

In the future: when you search for a user, or select them from the UI, the app pulls up your thread with that user. This thread is visible even if you have the user blocked. When you open the thread:

  • If the user has blocked you or you have blocked the user, you'll be able to see your past messages, but won't be able to send any new ones
  • Otherwise, if neither user has blocked the other, they should be able to chat, even if they are not friends
  • If the user isn't your friend yet, there should be a prompt to friend request them
  • If the user has friend requested you, there should be a prompt to respond to the request

In the "More" tab there should be a way to see your friend list and your block list, and to remove or add users to either.

In the "Compose thread" screen you should be able to create a thread with users you're not currently friends with. However, you shouldn't be able to create a thread with a user who has blocked you, or a user you have blocked. If you create a thread with somebody you're not currently friends with, the behavior should be the same as if you search for a user (as described below).

If you search for a user in the "thread list" page:

  • Entries for friends should list your existing thread with them
  • Entries for non-friends should list a fake thread. When you click through, it gives you the option to friend request or send a message to the user, which will start the thread

Custom message formatting

We'd like to support several kinds of message formatting:

  1. Replies, similar to how Telegram or Facebook Messenger does it today. A reply to a thread uses the standard Markdown syntax for quoting ("> quote")
  2. General Markdown syntax, enabling users to format text in messages, with things like headings and bold/italics
  3. Code formatting and JSON pretty-printing, so the dev team can communicate better :)

Queueing messages

It would be great if there was a way to queue up messages, and then send them all at once when you're ready.

Default thread for user

Even if you don't currently have a thread with a user, it should be possible to search for them in the chat list. The result that pops up will look like a thread, but will only create the thread when you friend send a message.

When you friend somebody a thread should be automatically created, so this use case is only for non-friends. If you pull up somebody you have blocked or who has blocked you, it will be treated as if the VOICED permission is missing.

Both before and after you create the thread (by sending a message), there should be a button somewhere to let you friend request the user.

Integrations

We want to build integrations for three reasons:

  1. To bootstrap the friendship graph: #25
  2. To integrate with calendars: #30
  3. To make log-in easier: #28

Integrations should exist with:

  1. Facebook, for log-in and friendship graph
  2. Google, for log-in, friendship graph, and calendar
  3. Apple, for log-in and calendar

Note that iOS App Store requirements mean that if it's possible to log in with Facebook or Google, it must be possible to log in with Apple.

Bootstrap friend lists based on shared threads

When we launch friend lists for the first time, we'll want to "bootstrap" the friend graph based on existing connections. A good approach would be to just look at which users have shared threads. To do this "bootstrap", we can probably just set up a script in server/src/scripts that we will run once.

GIPHY integration

It should be possible to browse GIPHY and send animated GIFs to your friends in any chat.

Web feature parity

Right now many features exist only on native:

  1. The ability to create a new thread
  2. The entire thread settings page, including ability to edit thread, create subthreads, add members

I'll keep this issue updated as I think of more things. Before we do a hard launch we'll need to get to these.

Friend list sync

We want to bootstrap our friendship graph based on external data. When a user creates an account, if we detect that their email/phone number is already in the system through an existing friend, we will auto-generate that friendship.

Friend list sync should definitely work with Facebook, and possibly with Google.

We want this friend list sync to be continuous, meaning if any changes occur on Facebook/Google, they are reflected back to us.

Auto-parsing event text

Our events are meant to be very lightweight. They are basically just a text blob that a user can fill out with any details they want.

We want to make the system smarter about understanding the context of these text blobs:

  1. If a user puts in a time, either precise or something general like "dinner" or "evening", we should highlight that text, and use it to sort the entries for a given day. Pressing the time should allow the user to export the event into any integrated calendar
  2. If a user puts in an address, we should highlight that text. Pressing the address should allow the user to open it up in either Google Maps or Apple Maps

If the system is smart enough about parsing time, we can start to auto-generate notifs when an event is coming up without a specified time. These notifs will prompt the event creator to figure out a more specific time.

When a user presses a general time, along with the option to export to their calendar, we show a button that links to a user settings page under the "More" tab. This allows the user to configure how general time strings (like "dinner") are parsed into specific times.

Better inform assumptions about video transcoding decisions

Right now we make some assumptions when deciding whether to transcode video.

  1. We assume 4 MiB/s upload speed for WiFi and 0.5 MiB/s upload speed for cellular
  2. We assume the transcoded video will be 0.35 MiB per second of video
  3. We assume the transcoding process will process 1.15 seconds of video per second

Instead of making these global assumptions, we should try to be more specific. For upload speeds, we could measure them on the device, perhaps even live. For the size of the transcoded video, the number is accurate for iOS, but we should check for Android (which uses a different codec). As for the length of the transcoding process, this depends on the individual device hardware. We should try and measure this and store it in Redux.

It would also be useful to know more about the destination client devices. For instance, if all the destination devices support hevc, we could avoid transcoding to h264.

Reactions

We want to build out support for a "reactions" feature. We'll want it to be closer to Slack than to Facebook Messenger.

  1. It should be possible to "react" with any emoji
  2. We'll want to build a custom emoji keyboard that lets you search for emojis using text strings
  3. It should be possible to upload custom emojis from a device that you can afterwards use from any of your devices
  4. When you see somebody use an emoji you like, it should be possible to grab that emoji so that you can use it from any of your devices

Phone number integration

When a user creates an account, they should be prompted to provide their phone number, and we should send a text to confirm it. This is crucial for getting contact list sync (#26) to work.

I'm not sure about what details we should ask for in the registration screen. Right now we ask for username, email, and password. We could pare this down to just username / phone number, or we could leave phone number to be specified in the NUX (#21).

Distinguish user notif settings from client notif settings

Right now our subscription settings for each thread are stored on the server in the membership table, and apply to all clients that have notifs enabled. It would be great the user could customize this subscription setting, as well as the default notif settings from #61, on both a per-client and global (per-user) basis.

Stop requiring complete list of threads in client Redux

Right now, web and native both expect that all threads visible to the user are in Redux's threadStore. This won't scale well long-term.

We should move to a model where threads might be missing on the client's local store. If the user needs to see any threads that might be missing from the local store, the app should request them from the keyserver.

Note - in the case of E2E encryption, the server holding the true list of threads would be the user's keyserver. In the case where the keyserver is on a user's phone, then requests from other clients (such as web) will route to the phone. In the case where the keyserver is external, requests (from web, native, etc.) will route to that keyserver. Additional details in #13 about how this database might work.

Time zone support

Related to #29 and #30. We want to make it really easy for users to just type in a time in the event blob and the system will figure out what they mean. But how do we handle time zones?

I think in general, our blob-parsing logic should make assumptions if it's easy, and try to get clarification if it's not sure.

Right now we don't have a great awareness of the user's current time zone. At any given point, clients know the current time zone, but the server does not. We should start by having the client inform the server about the user's time zone. Next, we should probably include this info in the UserInfo object, so that a given client can know the time zones of all the people it is inviting.

When a calendar entry is created with a time like "5 PM" or "17:00" or something like that, the client can check all the time zones of everybody in the given thread. If they're all the same, it will leave the text as-is, and underline it as discussed in #29.

If there are users with different time zones, we could automatically edit the text "5 PM" -> "5 PM EST". The first time this happens, we could show a little overlay that explains what happened. Then, when the user from the different time zone sees the event, it will show the time in their time zone.

There are other "ambiguities" in times that might be worth taking a similar approach with. For instance, if I see "meet up with Josh at 9", is it 9 AM or 9 PM? For users that have 12-hour time, we could have the system either ask for clarification, or make an assumption and edit the text to clarify.

E2E encryption

This one will be a huge task.

We want to support E2E encryption with keyservers that may be external. In this world, the user may choose to use either their phone or an external server as the "keyserver". This keyserver will hold on to the user's private key as well as being the "source of truth" for client data (see #13).

For this reason, we'll want to build the E2E encryption library in C/C++, so that it can be used across iOS/Android/custom hardware. We'll ideally integrate it into React Native using the upcoming bridgeless architecture.

To make this work correctly, we'll have to move all message generation and update generation to occur on the keyserver side, so that they can be encrypted properly. Right now many messages and updates are generated on the server side.

We also will have to think carefully about notifs. Right now all notifs are generated on the server side.

  1. For Android, we send FCM messages to the client that are actually not notifs. Instead, these FCM messages boot up the client, which then generates a local notif. On Android we have a high degree of certainty that the FCM messages will get delivered and that they will boot up the client app. It should be fairly easy to move the code for generating these notif payloads to the keyserver, allowing us to encrypt them before they hit any external server (either ours or Google's). We could probably even move the code to send the payloads to the keyserver as well, although this would require the keyserver to be aware of each user's device tokens
  2. iOS is a bit more complicated. It has a similar kind of functionality to Android for sending "fake" notifs that generate local notifs. But unfortunately, it's harder to rely on that functionality (the content_available flag). Apple's dasd may filter notifs if it decides the device is busy or too many are coming in, or the user doesn't care. Furthermore, the notifs don't always boot up the app if it's in the background. For that reason, we currently use standard notifs on iOS. The downside there is that we have to send the notif text in cleartext over to Apple. We could move the sending logic to occur on the keyserver, those preventing our servers from seeing the cleartext. As for Apple seeing it, we could argue that they have access anyways if you display a local notif on your device. But it's not ideal

Besides thinking about notifs, we also need to consider every place in the app where cleartext data can leak. For instance, right now crash reports include cleartext data.

Recurring events

It should be possible to set up recurring events. Similar to how it works in Exchange-style calendars, individual occurrences of recurring events should link to the root recurring event.

Implementation of this one might be a bit complex. Right now each individual occurrence ("entry") has its own ID and a specific date. With recurring events, we will probably have multiple entries using the same IDs, and will have to "dynamically" generate them as users scroll.

Mark as unread

We need a way to a user to mark a thread they've read as unread, so they can remember to get back to it later. An easy option would be to use a "swipeable" component in the thread list view.

Link previews

Right now we "linkify" URLs in chat, but we don't show any link previews.

There are security concerns here given that generating link previews requires HTTP requests. For that reason, link previews should be opt-in. They'll be configured as a plugin.

  • As a sender, you can set up the plugin to include link previews for your outgoing messages. If you do this, your device will query for the link preview and then include it in your message
  • If you have outgoing link previews enabled, there's an option in the message composer to X them out
  • As a receiver, if the sender includes a link preview, by default the client will render that preview. If you're using Nerd Mode (#76), we'll display a notice that explains that it was included by the sender. You can X out the notice
  • As a receiver, you can opt in to generating link previews for received messages as well
  • And finally, as a receiver you can opt out of rendering even the link previews that are sent to you, in case you just don't want to see them

Server awareness of client's user store

Right now, the server has awareness of every client's threadStore, entryStore, and messageStore. That means when any of these change, the server knows which clients need to be sent updates. This allows the server to send incremental updates to clients and to avoid large payloads.

This is not currently the case for a client's user store. Instead, the server makes sure to include all relevant user objects whenever it sends any kind of update to a client. For instance, a thread update will include all user objects for all users in that thread every time. An event update will include the user object for its creator every time.

This is fairly wasteful. It means that any change to a thread results in all of that's thread users objects being sent down to each client individually. It also means that when a user deletes their account, we send an update to every single client. This won't scale well.

Instead, the server should keep track of which user objects every client is aware of, and only send updates when those user objects change, or when the client becomes aware of a new user. (For instance, if somebody in a thread adds a friend of theirs to the thread.)

Following friend list implementation (#12), it may seem like we can limit updates about users to just their friends and blockers. However, this is insufficient because threads can exist with users who are not friends.

The server will have to be aware of what users can see each other based on what threads they share. This means we'll need an "adjacency table" on the server-side database that lists which users are aware of which other users.

We can treat "friend" and "block" as special cases in this adjacency table.

RSVP to events

Right now events are very simple. They have a containing thread, a date, and a text blob.

As a next step, it should be possible to RSVP to events on your calendar.

By default, we'll want events you have not RSVP'd to yet to be colored with a lighter shade. When you RSVP, the shade becomes the standard shade. To make this "lighter shade" concept possible, we'll need to restrict available thread colors to only high-contrast options.

NUX: thread list notices for growth

"NUX" stands for "new user experience".

Right now we have a simple register screen. Once you fill it out, you're dumped into the app, and asked for notification permissions.

There are a bunch of things we'd like you to set up:

  1. Notification permissions
  2. Contact list sync
  3. Profile picture
  4. Contact info
    • email
    • phone number
  5. Integrations
    • Google
    • Apple
    • Facebook

We'll try to use the chat thread list for these things. We'll prepend notices to the list that let you set up each of these.

If Nerd Mode is enabled (#76), there will be extra explanations about the security/privacy implications of each of these integrations in the notice.

Improve handling of events in thread view

When an event is created or modified, a message is generated in its containing thread. Right now, those messages are just a simple "robotext" string.

We should come up with a better UI for displaying these messages in the thread view. Additionally, it should be possible to create a new event from the thread view.

Dockerize everything

Right now everything is running on my personal server. We aren't prepared to scale the infrastructure. Before we do a hard launch, we need to get this figured out.

As a first step, we need to Dockerize all the infra on the server side. This includes:

  • Node
  • nvm
  • yarn
  • Redis
  • ffmpeg
  • certbot (or some alternate solution for auto-generating https certificates)

We won't Dockerize the database layer. (Is that even possible?) It's currently on a MySQL instance on my personal server. We can keep that setup until we're ready to replace it with a cloud store. Replacing MySQL is tracked in #15.

react-native-web

It would be great if we could run the native codebase on web. This should be possible with react-native-web and react-navigation, but will require a lot of customization, since none of the native modules are available.

At first we could use this for a simple demo on our landing page. Medium term, it would be great to have a mobile web client based on the native codebase. And long term, if and when React Navigation starts to support a "responsive" approach based on screen resolution, we could maybe even get rid of the web codebase altogether.

External log-in providers

It should be possible to log in with Facebook, Google, or Apple. Providing these log in options allows us to enable integrations (#24) faster.

Note that iOS App Store requirements mean that if it's possible to log in with Facebook or Google, it must be possible to log in with Apple.

Contact list sync

When a user creates a new account, we should ask for permissions to look at their phone's contact list, and use it to prepopulate the friend graph.

The sync should be continuous, meaning any changes that occur to the user's contact list are reflected in the app.

This task depends on #27

Thread-specific nicknames

Similar to the FB Messenger feature, would be cool if members of a chat thread could set nicknames for each other.

Revamp calendar view design on native

Right now the design isn't great. I like that it scrolls infinitely in either direction, but the date labels are very easy to miss. Additionally, it should be possible to see a monthly view, so you can scroll to any specific location you want.

Note that right now the calendar view is built around the assumption that the current day is always visible. We'd like to break this assumption in the future, for instance if you use the monthly view to select a date far in the future.

OTA updates

Right now the only way we can update the app is through making a new release. It would be cool to support OTA updates. expo-updates seems like a great option for this. We'll want to host everything locally, though.

Thread/user avatars

We want to allow each user and each thread to have an image associated with them.

  1. When a user first creates their account, the NUX (see #21) prompts them to set a profile picture. This can be done by uploading an image, or logging in to Facebook/Google/Apple and sourcing the picture from there
  2. If a thread is created without an image specified, an image is generated from the individual users in that thread
  3. It should be possible to update your profile pic from the "More" tab
  4. It should be possible to update any thread's avatar from the thread settings screen
  5. When any avatar is updated, the server should dispatch appropriate updates to everybody affected. This will require server awareness of the client user store, see #22
  6. Avatars should appear next to user messages in the thread view, both on native and on web

Sharing events

It should be possible to share events to threads you are in.

If somebody shares an event with you that originated from a thread you are not in, you'll be able to see the text of the event, but won't be able to edit it or RSVP. Your friend will need to add you to the containing thread for you to be able to RSVP.

Shared events appear on your calendar with a share icon and are colored with a lighter shade. When you RSVP, the shade becomes the standard shade. To make this "lighter shade" concept possible, we'll need to restrict available thread colors to only high-contrast options.

If you can see the thread in which the shared event was created, the color will come from that thread. If not, the color will come from the thread in which it was shared to you.

Chat thread personalization

Long-term we want to have a separate paid plan. One thing this paid plan could offer is improved personalization. If you have the paid plan, you can go to any thread you're in and customize it in cool ways. You could set a custom background color, maybe custom fonts, etc.

Launch to App Store

Right now we're still beta testing the app. This is okay on Android, where the Play Store treats betas much like normal apps. But on iOS you have to use Testflight, which is a really crappy experience. Users have to open the Testflight app to receive updates. If a user misses an update notif, the app will start autocrashing 90 days after the build was first uploaded. Not great.

We want to get something on the App Store sooner rather than later. We'll keep it under the SquadCal name for now. It's meant to be a "soft launch", ie. we won't publicize it for now. It's primarily to make it a little easier to continue testing and iterating.

Here's what's blocking:

  1. Friend list/block list: #12
  2. Integrations: #24
    • Facebook (log in, friend list sync)
    • Google (log in, calendar sync, friend list sync)
    • Apple (log in, calendar sync)
  3. Avatars for users and threads: #23
  4. Contact list sync: #26
  5. License page: #81

Only the friend list and license page are really necessary. The others are all growth features that we want to have in place ahead of the soft launch.

On-device database for native

Right now both web and native treat Redux as a database. This isn't great for performance and really isn't what Redux is intended for. It makes sense for web, where we don't have great access to a persistent store. But for native we want to move away from this model.

Redux keys used as data stores:

  • threadStore - threads
  • messageStore - messages
  • entryStore - calendar entries
  • userInfos - users

An aside: long-term we want to support E2E encryption with keyservers that may be external. In this world, the user may choose to use either their phone or an external server as the "keyserver". This keyserver will hold on to the user's private key as well as being the "source of truth" for the above pieces of data (see #45).

In the world where the phone is the keyserver, any requests for objects in the data store will have to be routed to the phone. This includes somebody using the web client.

In the world where the user has an external keyserver, requests for objects in the data store will be routed there. This includes somebody using the native client.

Since this database may be located on either a phone (iOS/Android) or on an external keyserver (Linux), we would ideally select a database that works across both. We'll probably want to build an API in C/C++ to access this database, since these are the only common languages across these platforms. We could use React Native's new JSI to allow bridgeless communication between the React Native JS runtime and the C/C++ API.

Staying in touch

I have a lot of friends that I try to keep up with, but I often forget. It should be possible to set up the app to ping you to check on friends you haven't heard from in a while, sort of similar to a CRM. It should be possible to configure the "haven't heard from in a while" check to occur either based on 1:1 messages, or based on any messages in shared threads.

Replace MySQL

Our server-side database right now is a single MySQL instance running on my personal server. This won't scale well and in general is probably unideal for a messaging app.

We want to migrate our data off of MySQL and probably move to some cloud store well-suited for our messaging workload. We'll probably have a period of time where we keep both databases (MySQL and whatever is replacing it) online. Once we're sure all the data has been migrated and the new setup is good, we will switch APIs to serve from the new database. If that's looking good after a week or so, we can finally shut down the MySQL instance.

Editing messages

It's not currently possible to edit messages.

Since the message list is an immutable log for encryption reasons, message edits can be delivered as a follow-up message that the client integrates into the original message.

"Background" threads

Right now, either you have notifs enabled for a thread or you don't. If you disable notifs for a thread, the app icon will still display a "badge" listing the number of unread threads, including any threads you've muted.

We want to add a concept of a "background" thread. To do this, we'll separate the thread list into two categories, "home" and "background", using a Material Design-style top tab view.

When you join or are added to a thread, by default it appears in your "home" view. You can then chose to move it to "background" using the thread settings screen.

Background threads do not contribute to the unread badge count.

External calendar integration

This is a big one, and I imagine will get quite hairy.

It should be possible to sync events from our calendar to external "Exchange"-style calendars. These calendars are generally delineated hour-by-hour. Most people are familiar with them from a business context. Google Calendar and iCal are examples of these sort of calendars.

One complexity is that our events don't always have a specific time. Exchange-style calendar don't work well with this model; they generally create a big vertical event covering the whole day.

When setting up calendar integration, the user should have several options:

  1. They can set up a calendar to import into our app. Each individual calendar will appear as a distinct thread
  2. They can set up a thread, or all of their threads, to export to an external calendar. There is an option to do this for:
    • All events
    • Only for events that have a specific time
    • Only for events that have any time at all, general or specific (see #29). For this last option, we allow the user to define how they want general strings like "afternoon" or "dinner" to get converted into specific times
  3. They can set up an external calendar without any sort of automatic import/export syncing. This will make it easy to export individual events as desired from the Calendar tab

Video (non-live) support

I've been working on this one for a while. We want to build out support for sending videos to your friends. This requires a whole transcoding pipeline on both native and server. I'm probably about halfway through right now.

Sidebars

Sidebars are a kind of child thread. They're meant for short back-and-forth conversations that start in a longer thread, but don't need to include everybody on that parent thread. In that sense they're somewhat similar to Slack threads.

You can create one by pressing on any message in a chat thread. People in the parent thread won't get notifs about messages in the child thread unless they press through to the child thread and choose to join it.

One crucial difference between the existing kind of child threads and sidebars is how they appear in the thread list. Whereas child threads are their own top-level entity, sidebars appear grouped below their parent thread. You only see the sidebars in which you are a member. If a new message occurs in a sidebar that you are a member, it bumps the whole parent thread to the top of the thread list.

For this reason, whereas standard child threads can have their own child threads, sidebars can not.

If the discussion in a sidebar drags on, and it starts to look like a long-term conversation, it's possible for any user to "upgrade" the sidebar to a standard child thread. If a sidebar gets upgraded, it will retain its link to the message in the parent thread that started it, but will otherwise behave like a standard child thread, appearing as its own entity in the thread list.

Lists

"Lists" can contain any number of threads. When a user sends a message to a list, that messages is copied to every thread in the list. It's as if the user copy-pasted the message into every thread in the list. People receiving the message should not be aware that it came from a list.

Lists appear in the thread list view, but with a different icon.

Note that it's possible to send non-text messages to a list. For instance, you could share an event to a list (see #32).

The system maintains a default friend list that contains all of your friends.

Event threads

Event threads are a kind of child thread. Any user can create an event thread for an existing event, either through the calendar view or the chat view. When this happens, a new child thread is created with the "yes" and "maybe" RSVPs to an event (see #19).

An event thread behaves similarly to a sidebar in the thread list view, appearing below its parent thread (see #18). It's not possible to create subthreads of an event thread, but you can promote the event thread to a standard child thread.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.