this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Added... I should plan

+98
+65
client/src/lumina_client/model_type.gleam
··· 1 1 //// Branched out the Model into a module. 2 2 //// The Model is about to be huge, I'm just preselecting for that. 3 3 4 + import gleam/dict 4 5 import gleam/dynamic/decode 5 6 import gleam/json 6 7 import gleam/option.{type Option} 7 8 import lustre_websocket 8 9 9 10 /// # Model 11 + /// 10 12 /// blablabla 11 13 pub type Model { 12 14 Model( ··· 20 22 token: Option(String), 21 23 /// Used to show error screens on unrecoverable errors 22 24 status: Result(Nil, String), 25 + /// To keep the client going while navigating, the websocket just requests certain data and then stores it in the model so that view can update once it's there 26 + /// Displaying some loading screen in between. 27 + /// Once it is there, this is where it's stored: 28 + cache: Cached, 29 + ) 30 + } 31 + 32 + pub type Cached { 33 + Cached( 34 + /// Posts are requested if nonexistent in the dict, and a loading screen can be displayed immediately 35 + /// The server will afterwards send all corresponding comments, which can also be stored and, if deemed 36 + /// necessary by the Lustre runtime, also update the DOM. 37 + /// Only drawback is that the view function might run a lot, but I don't believe that'd have such a big impact. 38 + /// 39 + /// `Dict(post_uuid, CachedPost)` 40 + cached_posts: dict.Dict(String, CachedPost), 41 + // /// Comments received: 42 + // cached_comments: List(CachedComment) 43 + // /// Users received: 44 + // cached_users: Dict(String, CachedUser) 45 + ) 46 + } 47 + 48 + pub type CachedPost { 49 + /// A media post, embedded is either webp or mp4. 50 + CachedMediaPost( 51 + /// Source instance. 'local' by default, hostname if external. 52 + source_instance: String, 53 + /// Media description 54 + description: String, 55 + /// Media files as base64-encoded 'data:'-strings 56 + /// Try matching on the substring of content-type 57 + /// to determine the valid HTML embed element to put it in. 58 + medias: List(String), 59 + /// Unix timestamp of the moment of posting 60 + timestamp: Int, 61 + /// User id of poster, which is why the source_instance matters. 62 + /// This means that client will do a lookup and stores the user once it gets it. 63 + author_id: String, 64 + ) 65 + /// The 'default', bluesky-like post, contains markdown and not much else. 66 + CachedTextualPost( 67 + /// Source instance. 'local' by default, hostname if external. 68 + source_instance: String, 69 + /// Markdown content. 70 + content: String, 71 + /// Unix timestamp of the moment of posting 72 + timestamp: Int, 73 + /// User id of poster, which is why the source_instance matters. 74 + /// This means that client will do a lookup and stores the user once it gets it. 75 + author_id: String, 76 + ) 77 + /// Article posts 78 + CachedArticlePost( 79 + /// Title of the article post 80 + title: String, 81 + /// Markdown content 82 + content: String, 83 + /// Unix timestamp of the moment of posting 84 + timestamp: Int, 85 + /// User id of poster, which is why the source_instance matters. 86 + /// This means that client will do a lookup and stores the user once it gets it. 87 + author_id: String, 23 88 ) 24 89 } 25 90
+33
server/src/client_communication.rs
··· 3 3 use cynthia_con::{CynthiaColors, CynthiaStyles}; 4 4 extern crate rocket; 5 5 use rocket::State; 6 + use uuid::Uuid; 6 7 7 8 #[get("/connection")] 8 9 pub(crate) fn wsconnection<'k>(ws: ws::WebSocket, state: &'k State<AppState>) -> ws::Channel<'k> { ··· 292 293 AuthSuccess { token: String, username: String }, 293 294 #[serde(rename = "auth_failure")] 294 295 AuthFailure, 296 + #[serde(rename = "data_article_post")] 297 + ArticlePostDataSent { 298 + post_id: Uuid, 299 + /// Source instance. 'local' by default, hostname if external. 300 + source_instance: String, 301 + title: String, 302 + content: String, 303 + /// Unix timestamp of the moment of posting 304 + timestamp: u64, 305 + /// User id of poster, which is why the source_instance matters. 306 + /// This means that client will do a lookup and stores the user once it gets it. 307 + author_id: String, 308 + }, 309 + #[serde(rename = "data_embed_post")] 310 + MediaPostDataSent { 311 + post_id: Uuid, 312 + /// Source instance. 'local' by default, hostname if external. 313 + source_instance: String, 314 + /// Media description 315 + description: String, 316 + /// Base64 encoded media strings, either webp or mp4. 317 + medias: Vec<String>, 318 + }, 319 + #[serde(rename = "data_textual_post")] 320 + TextPostDataSent { 321 + post_id: Uuid, 322 + /// Source instance. 'local' by default, hostname if external. 323 + source_instance: String, 324 + /// Markdown content. 325 + content: String, 326 + }, 327 + /// "Yeah I don't know what I'm sending either!" 295 328 #[serde(rename = "unknown")] 296 329 Unknown, 297 330 }