feat(webapi): impl room member listing

This commit is contained in:
oxalica 2024-10-01 06:31:53 -04:00
parent bc6e6c2056
commit 367f6d2a4b
7 changed files with 250 additions and 18 deletions

View file

@ -41,7 +41,7 @@
& label {
margin-left: 0;
}
& > #rooms {
& > #rooms, & > #room-members {
flex: 1;
}
}
@ -128,6 +128,8 @@
<label for="join-new-room">join new room:</label>
<select id="join-new-room"></select>
</div>
<label for="room-members">members:</label>
<select id="room-members" size="2"></select>
</div>
<div id="mainbar">

View file

@ -4,7 +4,8 @@ const msgFlow = document.querySelector('#msg-flow');
const idPubkeyInput = document.querySelector('#id-pubkey');
const actPubkeyDisplay = document.querySelector('#act-pubkey');
const serverUrlInput = document.querySelector('#server-url');
const roomsInput = document.querySelector('#rooms');
const roomsList = document.querySelector('#rooms');
const membersList = document.querySelector('#room-members');
const joinNewRoomInput = document.querySelector('#join-new-room');
const chatInput = document.querySelector('#chat');
@ -25,6 +26,10 @@ function hexToBuf(hex) {
return new Uint8Array(hex.match(/[\da-f]{2}/gi).map(m => parseInt(m, 16)))
}
function shortenIdKey(id_key) {
return id_key.replace(/^(.{4}).*(.{4})$/, '$1…$2');
}
function getIdPubkey() {
const s = idPubkeyInput.value.trim();
if (!s.match(/^[a-zA-Z0-9]{64}$/)) {
@ -186,7 +191,7 @@ async function showChatMsg(chat) {
}
// TODO: The relationship of id_key and act_key is not verified.
const shortUser = chat.signee.id_key.replace(/^(.{4}).*(.{4})$/, '$1…$2');
const shortUser = shortenIdKey(chat.signee.id_key);
const time = new Date(chat.signee.timestamp * 1000).toISOString();
const el = document.createElement('div', {});
@ -243,9 +248,10 @@ async function genAuthHeader() {
async function enterRoom(rid) {
log(`loading room: ${rid}`);
curRoom = rid;
roomsInput.value = rid;
roomsList.value = rid;
msgFlow.replaceChildren();
membersList.replaceChildren();
let roomMetadata;
try {
@ -257,6 +263,20 @@ async function enterRoom(rid) {
log(`failed to get room metadata: ${err}`);
}
try {
const resp = await fetch(`${apiUrl}/room/${rid}/member`, await genAuthHeader());
const json = await resp.json();
if (resp.status !== 200) throw new Error(`status ${resp.status}: ${json.error.message}`);
for (const { id_key, permission, last_seen_cid } of json.members) {
const el = document.createElement('option')
el.value = id_key;
el.innerText = `${shortenIdKey(id_key)} perm=${permission} last_seen=${last_seen_cid || '-'}`;
membersList.appendChild(el);
}
} catch (err) {
log(`failed to fetch members: ${err}`);
}
try {
const resp = await fetch(`${apiUrl}/room/${rid}/msg`, await genAuthHeader());
const json = await resp.json();
@ -357,10 +377,10 @@ async function loadRoomList(autoJoin) {
}
}
loadInto(roomsInput, 'joined')
loadInto(roomsList, 'joined')
.then(async (_) => {
if (autoJoin) {
const el = roomsInput.querySelector('option:nth-child(2)');
const el = roomsList.querySelector('option:nth-child(2)');
if (el !== null) {
await enterRoom(el.value);
}
@ -556,8 +576,8 @@ chatInput.onkeypress = async (e) => {
chatInput.focus();
}
};
roomsInput.onchange = async (_) => {
await enterRoom(roomsInput.value);
roomsList.onchange = async (_) => {
await enterRoom(roomsList.value);
};
joinNewRoomInput.onchange = async (_) => {
await joinRoom(joinNewRoomInput.value);