mirror of
https://github.com/Blah-IM/blahrs.git
synced 2025-05-01 00:31:09 +00:00
Impl room listing with filter=unseen
This commit is contained in:
parent
e74da2812b
commit
8b096ba802
2 changed files with 51 additions and 6 deletions
|
@ -24,10 +24,11 @@ paths:
|
||||||
in: query
|
in: query
|
||||||
required: true
|
required: true
|
||||||
description: |
|
description: |
|
||||||
Either "public" or "joined".
|
Must be one of following values:
|
||||||
For "public", it returns all public rooms on the server.
|
- "public": list all public rooms on the server.
|
||||||
For "joined", `Authorization` must be provided and it will return
|
- "joined": list rooms the user have joined.
|
||||||
rooms user have joined.
|
- "unseen": list rooms the user have joined and have unseen
|
||||||
|
messages.
|
||||||
top:
|
top:
|
||||||
in: query
|
in: query
|
||||||
description:
|
description:
|
||||||
|
@ -41,7 +42,9 @@ paths:
|
||||||
should be included (as the same value) for each page fetch.
|
should be included (as the same value) for each page fetch.
|
||||||
headers:
|
headers:
|
||||||
Authorization:
|
Authorization:
|
||||||
description: Proof of membership for private rooms. Required if `filter=joined`.
|
description: |
|
||||||
|
Proof of membership for private rooms.
|
||||||
|
Required if `filter` is other than "public".
|
||||||
required: false
|
required: false
|
||||||
schema:
|
schema:
|
||||||
$ret: WithSig<AuthPayload>
|
$ret: WithSig<AuthPayload>
|
||||||
|
|
|
@ -213,8 +213,12 @@ struct ListRoomParams {
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
enum ListRoomFilter {
|
enum ListRoomFilter {
|
||||||
|
/// List all public rooms.
|
||||||
Public,
|
Public,
|
||||||
|
/// List joined rooms (authentication required).
|
||||||
Joined,
|
Joined,
|
||||||
|
/// List all joined rooms with unseen messages (authentication required).
|
||||||
|
Unseen,
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn room_list(
|
async fn room_list(
|
||||||
|
@ -261,12 +265,14 @@ async fn room_list(
|
||||||
.transpose()?;
|
.transpose()?;
|
||||||
let last_seen_cid =
|
let last_seen_cid =
|
||||||
Some(row.get::<_, Id>("last_seen_cid")?).filter(|cid| cid.0 != 0);
|
Some(row.get::<_, Id>("last_seen_cid")?).filter(|cid| cid.0 != 0);
|
||||||
|
let unseen_cnt = row.get("unseen_cnt").ok();
|
||||||
Ok(RoomMetadata {
|
Ok(RoomMetadata {
|
||||||
rid,
|
rid,
|
||||||
title,
|
title,
|
||||||
attrs,
|
attrs,
|
||||||
last_chat,
|
last_chat,
|
||||||
last_seen_cid,
|
last_seen_cid,
|
||||||
|
unseen_cnt,
|
||||||
})
|
})
|
||||||
})?
|
})?
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
@ -320,6 +326,36 @@ async fn room_list(
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
ListRoomFilter::Unseen => {
|
||||||
|
let user = auth?.0;
|
||||||
|
query(
|
||||||
|
r"
|
||||||
|
SELECT
|
||||||
|
`rid`, `title`, `attrs`, `last_seen_cid`,
|
||||||
|
`cid`, `last_author`.`userkey`, `timestamp`, `nonce`, `sig`, `rich_text`,
|
||||||
|
(SELECT COUNT(*)
|
||||||
|
FROM `room_item` AS `unseen_item`
|
||||||
|
WHERE `unseen_item`.`rid` = `room`.`rid` AND
|
||||||
|
`last_seen_cid` < `unseen_item`.`cid`) AS `unseen_cnt`
|
||||||
|
FROM `user`
|
||||||
|
JOIN `room_member` USING (`uid`)
|
||||||
|
JOIN `room` USING (`rid`)
|
||||||
|
LEFT JOIN `room_item` USING (`rid`)
|
||||||
|
LEFT JOIN `user` AS `last_author` ON (`last_author`.`uid` = `room_item`.`uid`)
|
||||||
|
WHERE `user`.`userkey` = :userkey AND
|
||||||
|
`rid` > :start_rid AND
|
||||||
|
`cid` > `last_seen_cid`
|
||||||
|
GROUP BY `rid` HAVING `cid` IS MAX(`cid`)
|
||||||
|
ORDER BY `rid` ASC
|
||||||
|
LIMIT :page_len
|
||||||
|
",
|
||||||
|
named_params! {
|
||||||
|
":start_rid": start_rid,
|
||||||
|
":page_len": page_len,
|
||||||
|
":userkey": user,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.map(Json)
|
.map(Json)
|
||||||
}
|
}
|
||||||
|
@ -466,8 +502,10 @@ async fn room_get_metadata(
|
||||||
rid,
|
rid,
|
||||||
title,
|
title,
|
||||||
attrs,
|
attrs,
|
||||||
|
// TODO: Should we include these here?
|
||||||
last_chat: None,
|
last_chat: None,
|
||||||
last_seen_cid: None,
|
last_seen_cid: None,
|
||||||
|
unseen_cnt: None,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -579,11 +617,15 @@ pub struct RoomMetadata {
|
||||||
pub title: String,
|
pub title: String,
|
||||||
pub attrs: RoomAttrs,
|
pub attrs: RoomAttrs,
|
||||||
|
|
||||||
/// Optional extra information. Only included by the room list response.
|
// Optional extra information. Only included by the room list response.
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub last_chat: Option<WithItemId<ChatItem>>,
|
pub last_chat: Option<WithItemId<ChatItem>>,
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub last_seen_cid: Option<Id>,
|
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>(
|
||||||
|
|
Loading…
Add table
Reference in a new issue