| 1 | use super::{InputReplicaId, Role, Selection}; |
| 2 | use serde::{Deserialize, Serialize}; |
| 3 | use uuid::Uuid; |
| 4 | |
| 5 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize, Serialize)] |
| 6 | pub enum ParticipantType { |
| 7 | Sharer, |
| 8 | Viewer { role: Role }, |
| 9 | } |
| 10 | |
| 11 | /// An ID for a shared session participant that is unique across all participants across all shared sessions. |
| 12 | /// If a viewer joins a shared session multiple times from the same machine, they are treated as separate participants with their own ParticipantId. |
| 13 | /// A participant reconnecting should keep the same participant ID. |
| 14 | #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] |
| 15 | pub struct ParticipantId(String); |
| 16 | |
| 17 | impl From<String> for ParticipantId { |
| 18 | fn from(value: String) -> Self { |
| 19 | ParticipantId(value) |
| 20 | } |
| 21 | } |
| 22 | |
| 23 | impl ParticipantId { |
| 24 | pub fn new() -> ParticipantId { |
| 25 | ParticipantId(Uuid::new_v4().to_string()) |
| 26 | } |
| 27 | } |
| 28 | |
| 29 | impl Default for ParticipantId { |
| 30 | fn default() -> Self { |
| 31 | ParticipantId::new() |
| 32 | } |
| 33 | } |
| 34 | |
| 35 | impl std::fmt::Display for ParticipantId { |
| 36 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| 37 | std::fmt::Display::fmt(&self.0, f) |
| 38 | } |
| 39 | } |
| 40 | |
| 41 | /// Mostly static information about a participant. |
| 42 | #[derive(Clone, Debug, Default, Deserialize, Serialize)] |
| 43 | pub struct ProfileData { |
| 44 | pub firebase_uid: String, |
| 45 | pub display_name: String, |
| 46 | |
| 47 | /// If None, the client should render an avatar themselves. |
| 48 | pub photo_url: Option<String>, |
| 49 | pub email: Option<String>, |
| 50 | |
| 51 | pub input_replica_id: InputReplicaId, |
| 52 | } |
| 53 | |
| 54 | /// Contains information about a shared session participant. |
| 55 | #[derive(Clone, Debug, Default, Deserialize, Serialize)] |
| 56 | pub struct ParticipantInfo { |
| 57 | pub id: ParticipantId, |
| 58 | pub profile_data: ProfileData, |
| 59 | pub selection: Selection, |
| 60 | } |
| 61 | |
| 62 | #[derive(Clone, Debug, Default, Deserialize, Serialize)] |
| 63 | pub struct Sharer { |
| 64 | pub info: ParticipantInfo, |
| 65 | } |
| 66 | |
| 67 | #[derive(Clone, Debug, Default, Deserialize, Serialize)] |
| 68 | pub struct Viewer { |
| 69 | pub info: ParticipantInfo, |
| 70 | pub role: Role, |
| 71 | /// Whether or not this viewer is still part of the session. |
| 72 | pub is_present: bool, |
| 73 | } |
| 74 | |
| 75 | /// Information about a viewer that is still part of the session. |
| 76 | #[derive(Clone, Debug, Default, Deserialize, Serialize)] |
| 77 | pub struct PresentViewer { |
| 78 | pub info: ParticipantInfo, |
| 79 | /// The maximum access level this viewer has been given. |
| 80 | pub max_acl: Role, |
| 81 | } |
| 82 | |
| 83 | /// Information about a viewer that is no longer a part of the session. |
| 84 | #[derive(Clone, Debug, Default, Deserialize, Serialize)] |
| 85 | pub struct AbsentViewer { |
| 86 | pub info: ParticipantInfo, |
| 87 | } |
| 88 | |
| 89 | /// Information about a user who is a direct guest on the session. |
| 90 | #[derive(Clone, Debug, Default, Deserialize, Serialize)] |
| 91 | pub struct Guest { |
| 92 | pub profile_data: ProfileData, |
| 93 | /// The direct access level that this guest has been given. |
| 94 | pub direct_acl: Role, |
| 95 | } |
| 96 | |
| 97 | /// Information about a non-Warp user who has been invited to the session. |
| 98 | #[derive(Clone, Debug, Default, Deserialize, Serialize)] |
| 99 | pub struct PendingGuest { |
| 100 | pub email: String, |
| 101 | /// The direct access level that this guest has been given. |
| 102 | pub direct_acl: Role, |
| 103 | } |
| 104 | |
| 105 | /// Information about the full list of all participants in a shared session. |
| 106 | /// |
| 107 | /// To derive the session's direct guests, all of the users with direct acls |
| 108 | /// across `present_viewers`, `absent_viewers`, and `non_viewer_guests` must be |
| 109 | /// accumulated. |
| 110 | #[derive(Clone, Debug, Default, Deserialize, Serialize)] |
| 111 | pub struct ParticipantList { |
| 112 | pub sharer: Sharer, |
| 113 | |
| 114 | /// Legacy field kept for backwards compatibility. After the ACL transition |
| 115 | /// we should be using `present_viewers`, `absent_viewers`, and |
| 116 | /// `non_viewer_guests` and can remove this field. |
| 117 | pub viewers: Vec<Viewer>, |
| 118 | |
| 119 | /// Viewers that are currently on the session. |
| 120 | pub present_viewers: Vec<PresentViewer>, |
| 121 | /// Viewers that are no longer on the session. |
| 122 | pub absent_viewers: Vec<AbsentViewer>, |
| 123 | /// Users that have a direct ACL on the session. |
| 124 | pub guests: Vec<Guest>, |
| 125 | /// Non-Warp users who have been invited to the session. |
| 126 | pub pending_guests: Vec<PendingGuest>, |
| 127 | } |
| 128 | |
| 129 | impl ParticipantList { |
| 130 | /// Downgrades all `Role::Full` fields to `Role::Executor`. |
| 131 | /// Used for backward compatibility with clients that don't support the Full role. |
| 132 | pub fn downgrade_full_roles(&mut self) { |
| 133 | for viewer in &mut self.viewers { |
| 134 | viewer.role.downgrade_full(); |
| 135 | } |
| 136 | for viewer in &mut self.present_viewers { |
| 137 | viewer.max_acl.downgrade_full(); |
| 138 | } |
| 139 | for guest in &mut self.guests { |
| 140 | guest.direct_acl.downgrade_full(); |
| 141 | } |
| 142 | for guest in &mut self.pending_guests { |
| 143 | guest.direct_acl.downgrade_full(); |
| 144 | } |
| 145 | } |
| 146 | } |
| 147 | |
| 148 | /// Information received from fetching and processing the participant list. |
| 149 | pub struct ParticipantListInfo { |
| 150 | /// The full list of participants in a shared session. |
| 151 | pub list: ParticipantList, |
| 152 | /// The list of present participants who do not have access to the session. |
| 153 | pub viewers_without_access: Vec<ParticipantId>, |
| 154 | } |