mirror of
https://github.com/Blah-IM/blahrs.git
synced 2025-05-21 17:41:09 +00:00
refactor(webapi): hoist RoomMetadata
to blah_types
and rename last_chat
to last_item
This commit is contained in:
parent
c0ec429c24
commit
74c6fa6f6a
5 changed files with 40 additions and 33 deletions
|
@ -308,6 +308,29 @@ impl RichText {
|
||||||
|
|
||||||
pub type ChatItem = WithSig<ChatPayload>;
|
pub type ChatItem = WithSig<ChatPayload>;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct RoomMetadata {
|
||||||
|
/// Room id.
|
||||||
|
pub rid: Id,
|
||||||
|
/// Plain text room title.
|
||||||
|
pub title: String,
|
||||||
|
/// Room attributes.
|
||||||
|
pub attrs: RoomAttrs,
|
||||||
|
|
||||||
|
// Extra information is only available for some APIs.
|
||||||
|
/// The last item in the room.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub last_item: Option<WithItemId<ChatItem>>,
|
||||||
|
/// The current user's last seen item id.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub last_seen_cid: Option<Id>,
|
||||||
|
/// The number of unseen messages, ie. the number of items from `last_seen_cid` to
|
||||||
|
/// `last_item.cid`.
|
||||||
|
/// This may or may not be a precise number.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub unseen_cnt: Option<u64>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
#[serde(tag = "typ", rename = "create_room")]
|
#[serde(tag = "typ", rename = "create_room")]
|
||||||
pub struct CreateRoomPayload {
|
pub struct CreateRoomPayload {
|
||||||
|
|
|
@ -12,7 +12,7 @@ use axum::{Json, Router};
|
||||||
use axum_extra::extract::WithRejection as R;
|
use axum_extra::extract::WithRejection as R;
|
||||||
use blah_types::{
|
use blah_types::{
|
||||||
ChatItem, ChatPayload, CreateRoomPayload, Id, MemberPermission, RoomAdminOp, RoomAdminPayload,
|
ChatItem, ChatPayload, CreateRoomPayload, Id, MemberPermission, RoomAdminOp, RoomAdminPayload,
|
||||||
RoomAttrs, ServerPermission, Signee, UserKey, WithItemId, WithSig,
|
RoomAttrs, RoomMetadata, ServerPermission, Signee, UserKey, WithItemId, WithSig,
|
||||||
};
|
};
|
||||||
use config::ServerConfig;
|
use config::ServerConfig;
|
||||||
use ed25519_dalek::SIGNATURE_LENGTH;
|
use ed25519_dalek::SIGNATURE_LENGTH;
|
||||||
|
@ -138,7 +138,7 @@ async fn handle_ws(State(st): ArcState, ws: WebSocketUpgrade) -> Response {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub struct RoomList {
|
pub struct RoomList {
|
||||||
pub rooms: Vec<RoomMetadata>,
|
pub rooms: Vec<RoomMetadata>,
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
@ -189,7 +189,7 @@ async fn room_list(
|
||||||
let rid = row.get("rid")?;
|
let rid = row.get("rid")?;
|
||||||
let title = row.get("title")?;
|
let title = row.get("title")?;
|
||||||
let attrs = row.get("attrs")?;
|
let attrs = row.get("attrs")?;
|
||||||
let last_chat = row
|
let last_item = row
|
||||||
.get::<_, Option<Id>>("cid")?
|
.get::<_, Option<Id>>("cid")?
|
||||||
.map(|cid| {
|
.map(|cid| {
|
||||||
Ok::<_, rusqlite::Error>(WithItemId {
|
Ok::<_, rusqlite::Error>(WithItemId {
|
||||||
|
@ -216,7 +216,7 @@ async fn room_list(
|
||||||
rid,
|
rid,
|
||||||
title,
|
title,
|
||||||
attrs,
|
attrs,
|
||||||
last_chat,
|
last_item,
|
||||||
last_seen_cid,
|
last_seen_cid,
|
||||||
unseen_cnt,
|
unseen_cnt,
|
||||||
})
|
})
|
||||||
|
@ -439,20 +439,21 @@ async fn room_get_metadata(
|
||||||
R(Path(rid), _): RE<Path<Id>>,
|
R(Path(rid), _): RE<Path<Id>>,
|
||||||
auth: MaybeAuth,
|
auth: MaybeAuth,
|
||||||
) -> Result<Json<RoomMetadata>, ApiError> {
|
) -> Result<Json<RoomMetadata>, ApiError> {
|
||||||
let (title, attrs) =
|
let conn = st.db.get();
|
||||||
get_room_if_readable(&st.db.get(), rid, auth.into_optional()?.as_ref(), |row| {
|
let (title, attrs) = get_room_if_readable(&conn, rid, auth.into_optional()?.as_ref(), |row| {
|
||||||
Ok((
|
Ok((
|
||||||
row.get::<_, String>("title")?,
|
row.get::<_, String>("title")?,
|
||||||
row.get::<_, RoomAttrs>("attrs")?,
|
row.get::<_, RoomAttrs>("attrs")?,
|
||||||
))
|
))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Ok(Json(RoomMetadata {
|
Ok(Json(RoomMetadata {
|
||||||
rid,
|
rid,
|
||||||
title,
|
title,
|
||||||
attrs,
|
attrs,
|
||||||
|
|
||||||
// TODO: Should we include these here?
|
// TODO: Should we include these here?
|
||||||
last_chat: None,
|
last_item: None,
|
||||||
last_seen_cid: None,
|
last_seen_cid: None,
|
||||||
unseen_cnt: None,
|
unseen_cnt: None,
|
||||||
}))
|
}))
|
||||||
|
@ -560,23 +561,6 @@ struct FeedItemExtra {
|
||||||
sig: [u8; SIGNATURE_LENGTH],
|
sig: [u8; SIGNATURE_LENGTH],
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
|
||||||
pub struct RoomMetadata {
|
|
||||||
pub rid: Id,
|
|
||||||
pub title: String,
|
|
||||||
pub attrs: RoomAttrs,
|
|
||||||
|
|
||||||
// Optional extra information. Only included by the room list response.
|
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
|
||||||
pub last_chat: Option<WithItemId<ChatItem>>,
|
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
|
||||||
pub last_seen_cid: Option<Id>,
|
|
||||||
/// The number of unseen messages. Only available for `room_list` response with
|
|
||||||
/// "filter=unseen".
|
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
|
||||||
pub unseen_cnt: Option<u64>,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_room_if_readable<T>(
|
fn get_room_if_readable<T>(
|
||||||
conn: &rusqlite::Connection,
|
conn: &rusqlite::Connection,
|
||||||
rid: Id,
|
rid: Id,
|
||||||
|
|
|
@ -233,7 +233,7 @@ async fn room_create_get(server: Server, ref mut rng: impl RngCore, #[case] publ
|
||||||
} else {
|
} else {
|
||||||
RoomAttrs::empty()
|
RoomAttrs::empty()
|
||||||
},
|
},
|
||||||
last_chat: None,
|
last_item: None,
|
||||||
last_seen_cid: None,
|
last_seen_cid: None,
|
||||||
unseen_cnt: None,
|
unseen_cnt: None,
|
||||||
};
|
};
|
||||||
|
|
|
@ -377,7 +377,7 @@ components:
|
||||||
description: Room attributes bitset, see `RoomAttrs`.
|
description: Room attributes bitset, see `RoomAttrs`.
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
last_chat:
|
last_item:
|
||||||
$ref: '#/components/schemas/WithItemId-WithSig-Chat'
|
$ref: '#/components/schemas/WithItemId-WithSig-Chat'
|
||||||
last_seen_cid:
|
last_seen_cid:
|
||||||
description: The `cid` of the last chat being marked as seen.
|
description: The `cid` of the last chat being marked as seen.
|
||||||
|
|
|
@ -269,11 +269,11 @@ async function loadRoomList(autoJoin) {
|
||||||
const resp = await fetch(`${serverUrl}/room?filter=${filter}`, await genAuthHeader())
|
const resp = await fetch(`${serverUrl}/room?filter=${filter}`, await genAuthHeader())
|
||||||
const json = await resp.json()
|
const json = await resp.json()
|
||||||
if (resp.status !== 200) throw new Error(`status ${resp.status}: ${json.error.message}`);
|
if (resp.status !== 200) throw new Error(`status ${resp.status}: ${json.error.message}`);
|
||||||
for (const { rid, title, attrs, last_chat, last_seen_cid } of json.rooms) {
|
for (const { rid, title, attrs, last_item, last_seen_cid } of json.rooms) {
|
||||||
const el = document.createElement('option');
|
const el = document.createElement('option');
|
||||||
el.value = rid;
|
el.value = rid;
|
||||||
el.innerText = `${title} (rid=${rid}, attrs=${attrs})`;
|
el.innerText = `${title} (rid=${rid}, attrs=${attrs})`;
|
||||||
if (last_chat !== undefined && last_chat.cid !== last_seen_cid) {
|
if (last_item !== undefined && last_item.cid !== last_seen_cid) {
|
||||||
el.innerText += ' (unread)';
|
el.innerText += ' (unread)';
|
||||||
}
|
}
|
||||||
targetEl.appendChild(el);
|
targetEl.appendChild(el);
|
||||||
|
|
Loading…
Add table
Reference in a new issue