···11//// Branched out the Model into a module.
22//// The Model is about to be huge, I'm just preselecting for that.
3344+import gleam/dict
45import gleam/dynamic/decode
56import gleam/json
67import gleam/option.{type Option}
78import lustre_websocket
89910/// # Model
1111+///
1012/// blablabla
1113pub type Model {
1214 Model(
···2022 token: Option(String),
2123 /// Used to show error screens on unrecoverable errors
2224 status: Result(Nil, String),
2525+ /// 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
2626+ /// Displaying some loading screen in between.
2727+ /// Once it is there, this is where it's stored:
2828+ cache: Cached,
2929+ )
3030+}
3131+3232+pub type Cached {
3333+ Cached(
3434+ /// Posts are requested if nonexistent in the dict, and a loading screen can be displayed immediately
3535+ /// The server will afterwards send all corresponding comments, which can also be stored and, if deemed
3636+ /// necessary by the Lustre runtime, also update the DOM.
3737+ /// Only drawback is that the view function might run a lot, but I don't believe that'd have such a big impact.
3838+ ///
3939+ /// `Dict(post_uuid, CachedPost)`
4040+ cached_posts: dict.Dict(String, CachedPost),
4141+ // /// Comments received:
4242+ // cached_comments: List(CachedComment)
4343+ // /// Users received:
4444+ // cached_users: Dict(String, CachedUser)
4545+ )
4646+}
4747+4848+pub type CachedPost {
4949+ /// A media post, embedded is either webp or mp4.
5050+ CachedMediaPost(
5151+ /// Source instance. 'local' by default, hostname if external.
5252+ source_instance: String,
5353+ /// Media description
5454+ description: String,
5555+ /// Media files as base64-encoded 'data:'-strings
5656+ /// Try matching on the substring of content-type
5757+ /// to determine the valid HTML embed element to put it in.
5858+ medias: List(String),
5959+ /// Unix timestamp of the moment of posting
6060+ timestamp: Int,
6161+ /// User id of poster, which is why the source_instance matters.
6262+ /// This means that client will do a lookup and stores the user once it gets it.
6363+ author_id: String,
6464+ )
6565+ /// The 'default', bluesky-like post, contains markdown and not much else.
6666+ CachedTextualPost(
6767+ /// Source instance. 'local' by default, hostname if external.
6868+ source_instance: String,
6969+ /// Markdown content.
7070+ content: String,
7171+ /// Unix timestamp of the moment of posting
7272+ timestamp: Int,
7373+ /// User id of poster, which is why the source_instance matters.
7474+ /// This means that client will do a lookup and stores the user once it gets it.
7575+ author_id: String,
7676+ )
7777+ /// Article posts
7878+ CachedArticlePost(
7979+ /// Title of the article post
8080+ title: String,
8181+ /// Markdown content
8282+ content: String,
8383+ /// Unix timestamp of the moment of posting
8484+ timestamp: Int,
8585+ /// User id of poster, which is why the source_instance matters.
8686+ /// This means that client will do a lookup and stores the user once it gets it.
8787+ author_id: String,
2388 )
2489}
2590
+33
server/src/client_communication.rs
···33use cynthia_con::{CynthiaColors, CynthiaStyles};
44extern crate rocket;
55use rocket::State;
66+use uuid::Uuid;
6778#[get("/connection")]
89pub(crate) fn wsconnection<'k>(ws: ws::WebSocket, state: &'k State<AppState>) -> ws::Channel<'k> {
···292293 AuthSuccess { token: String, username: String },
293294 #[serde(rename = "auth_failure")]
294295 AuthFailure,
296296+ #[serde(rename = "data_article_post")]
297297+ ArticlePostDataSent {
298298+ post_id: Uuid,
299299+ /// Source instance. 'local' by default, hostname if external.
300300+ source_instance: String,
301301+ title: String,
302302+ content: String,
303303+ /// Unix timestamp of the moment of posting
304304+ timestamp: u64,
305305+ /// User id of poster, which is why the source_instance matters.
306306+ /// This means that client will do a lookup and stores the user once it gets it.
307307+ author_id: String,
308308+ },
309309+ #[serde(rename = "data_embed_post")]
310310+ MediaPostDataSent {
311311+ post_id: Uuid,
312312+ /// Source instance. 'local' by default, hostname if external.
313313+ source_instance: String,
314314+ /// Media description
315315+ description: String,
316316+ /// Base64 encoded media strings, either webp or mp4.
317317+ medias: Vec<String>,
318318+ },
319319+ #[serde(rename = "data_textual_post")]
320320+ TextPostDataSent {
321321+ post_id: Uuid,
322322+ /// Source instance. 'local' by default, hostname if external.
323323+ source_instance: String,
324324+ /// Markdown content.
325325+ content: String,
326326+ },
327327+ /// "Yeah I don't know what I'm sending either!"
295328 #[serde(rename = "unknown")]
296329 Unknown,
297330}