implement room preview

This commit is contained in:
Bruno Windels 2020-12-02 11:06:35 +01:00
parent 1957277463
commit ca74aaf4d1
4 changed files with 62 additions and 8 deletions

View file

@ -23,7 +23,7 @@ const EVENT_WITH_ROOMALIAS_PATTERN = /^[#]([^:]*):(.+)\/\$([^:]+):(.+)$/;
const USERID_PATTERN = /^@([^:]+):(.+)$/; const USERID_PATTERN = /^@([^:]+):(.+)$/;
const GROUPID_PATTERN = /^\+([^:]+):(.+)$/; const GROUPID_PATTERN = /^\+([^:]+):(.+)$/;
const IdentifierKind = createEnum( export const IdentifierKind = createEnum(
"RoomId", "RoomId",
"RoomAlias", "RoomAlias",
"UserId", "UserId",

View file

@ -43,7 +43,7 @@ export class HomeServer {
} }
async getUserProfile(userId) { async getUserProfile(userId) {
const {body} = await this._request(`${this.baseURL}/_matrix/client/r0/profile/${userId}`, {method: "GET"}).response(); const {body} = await this._request(`${this.baseURL}/_matrix/client/r0/profile/${encodeURIComponent(userId)}`).response();
return body; return body;
} }
@ -51,8 +51,28 @@ export class HomeServer {
//`/_matrix/client/r0/groups/${groupId}/profile` //`/_matrix/client/r0/groups/${groupId}/profile`
} }
getPublicRooms() { async findPublicRoomById(roomId) {
const {body, status} = await this._request(`${this.baseURL}/_matrix/client/r0/directory/list/room/${encodeURIComponent(roomId)}`).response();
if (status !== 200 || body.visibility !== "public") {
return;
}
let nextBatch;
do {
const queryParams = encodeQueryParams({limit: 10000, since: nextBatch});
const {body, status} = await this._request(`${this.baseURL}/_matrix/client/r0/publicRooms?${queryParams}`).response();
nextBatch = body.next_batch;
const publicRoom = body.chunk.find(c => c.room_id === roomId);
if (publicRoom) {
return publicRoom;
}
} while (nextBatch);
}
async getRoomIdFromAlias(alias) {
const {status, body} = await this._request(`${this.baseURL}/_matrix/client/r0/directory/room/${encodeURIComponent(alias)}`).response();
if (status === 200) {
return body.room_id;
}
} }
mxcUrlThumbnail(url, width, height, method) { mxcUrlThumbnail(url, width, height, method) {
@ -73,4 +93,16 @@ function parseMxcUrl(url) {
} else { } else {
return null; return null;
} }
} }
function encodeQueryParams(queryParams) {
return Object.entries(queryParams || {})
.filter(([, value]) => value !== undefined)
.map(([name, value]) => {
if (typeof value === "object") {
value = JSON.stringify(value);
}
return `${encodeURIComponent(name)}=${encodeURIComponent(value)}`;
})
.join("&");
}

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
import {LinkKind, getLabelForLinkKind} from "../Link.js"; import {LinkKind, IdentifierKind, getLabelForLinkKind} from "../Link.js";
import {ViewModel} from "../utils/ViewModel.js"; import {ViewModel} from "../utils/ViewModel.js";
import {resolveServer} from "./HomeServer.js"; import {resolveServer} from "./HomeServer.js";
import {ClientListViewModel} from "../client/ClientListViewModel.js"; import {ClientListViewModel} from "../client/ClientListViewModel.js";
@ -32,6 +32,7 @@ export class PreviewViewModel extends ViewModel {
this.loading = false; this.loading = false;
this.name = null; this.name = null;
this.avatarUrl = null; this.avatarUrl = null;
this.identifier = null;
this.previewDomain = null; this.previewDomain = null;
this.clientsViewModel = null; this.clientsViewModel = null;
this.acceptInstructions = null; this.acceptInstructions = null;
@ -51,6 +52,10 @@ export class PreviewViewModel extends ViewModel {
switch (this._link.kind) { switch (this._link.kind) {
case LinkKind.User: case LinkKind.User:
await this._loadUserPreview(homeserver, this._link.identifier); await this._loadUserPreview(homeserver, this._link.identifier);
break;
case LinkKind.Room:
await this._loadRoomPreview(homeserver, this._link);
break;
} }
// assume we're done if nothing threw // assume we're done if nothing threw
this.previewDomain = server; this.previewDomain = server;
@ -69,10 +74,24 @@ export class PreviewViewModel extends ViewModel {
this.avatarUrl = profile.avatar_url ? this.avatarUrl = profile.avatar_url ?
homeserver.mxcUrlThumbnail(profile.avatar_url, 64, 64, "crop") : homeserver.mxcUrlThumbnail(profile.avatar_url, 64, 64, "crop") :
null; null;
this.identifier = userId;
} }
get identifier() { async _loadRoomPreview(homeserver, link) {
return this._link.identifier; let publicRoom;
if (link.identifierKind === IdentifierKind.RoomId) {
publicRoom = await homeserver.findPublicRoomById(link.identifier);
} else if (link.identifierKind === IdentifierKind.RoomAlias) {
const roomId = await homeserver.getRoomIdFromAlias(link.identifier);
if (roomId) {
publicRoom = await homeserver.findPublicRoomById(roomId);
}
}
this.name = publicRoom?.name || publicRoom?.canonical_alias || link.identifier;
this.avatarUrl = publicRoom?.avatar_url ?
homeserver.mxcUrlThumbnail(publicRoom.avatar_url, 64, 64, "crop") :
null;
this.identifier = `${publicRoom?.canonical_alias || link.identifier} | ${publicRoom?.num_joined_members} members`;
} }
get showClientsLabel() { get showClientsLabel() {

View file

@ -79,7 +79,10 @@ function xhrAsPromise(xhr, method, url) {
}); });
} }
export function xhrRequest(url, options) { export function xhrRequest(url, options = {}) {
if (!options.method) {
options.method = "GET";
}
let {cache, body, method} = options; let {cache, body, method} = options;
if (!cache) { if (!cache) {
url = addCacheBuster(url); url = addCacheBuster(url);