basic handling of event and group preview

This commit is contained in:
Bruno Windels 2020-12-04 16:38:10 +01:00
parent a705621dd5
commit 920a95296c
3 changed files with 39 additions and 58 deletions

View file

@ -19,9 +19,8 @@ import {orderedUnique} from "./utils/unique.js";
const ROOMALIAS_PATTERN = /^#([^:]*):(.+)$/;
const ROOMID_PATTERN = /^!([^:]*):(.+)$/;
const EVENT_WITH_ROOMID_PATTERN = /^[!]([^:]*):(.+)\/\$([^:]+):(.+)$/;
const EVENT_WITH_ROOMALIAS_PATTERN = /^[#]([^:]*):(.+)\/\$([^:]+):(.+)$/;
const USERID_PATTERN = /^@([^:]+):(.+)$/;
const EVENTID_PATTERN = /^$([^:]+):(.+)$/;
const GROUPID_PATTERN = /^\+([^:]+):(.+)$/;
export const IdentifierKind = createEnum(
@ -71,7 +70,7 @@ export class Link {
if (!fragment) {
return null;
}
let [identifier, queryParams] = fragment.split("?");
let [linkStr, queryParams] = fragment.split("?");
let viaServers = [];
if (queryParams) {
@ -81,29 +80,13 @@ export class Link {
.map(([,value]) => value);
}
if (identifier.startsWith("#/")) {
identifier = identifier.substr(2);
if (linkStr.startsWith("#/")) {
linkStr = linkStr.substr(2);
}
let kind;
const [identifier, eventId] = linkStr.split("/");
let matches;
// longest first, so they dont get caught by ROOMALIAS_PATTERN and ROOMID_PATTERN
matches = EVENT_WITH_ROOMID_PATTERN.exec(identifier);
if (matches) {
const roomServer = matches[2];
const messageServer = matches[4];
const roomLocalPart = matches[1];
const messageLocalPart = matches[3];
return new Link(viaServers, IdentifierKind.RoomId, roomLocalPart, roomServer, messageLocalPart, messageServer);
}
matches = EVENT_WITH_ROOMALIAS_PATTERN.exec(identifier);
if (matches) {
const roomServer = matches[2];
const messageServer = matches[4];
const roomLocalPart = matches[1];
const messageLocalPart = matches[3];
return new Link(viaServers, IdentifierKind.RoomAlias, roomLocalPart, roomServer, messageLocalPart, messageServer);
}
matches = USERID_PATTERN.exec(identifier);
if (matches) {
const server = matches[2];
@ -114,13 +97,13 @@ export class Link {
if (matches) {
const server = matches[2];
const localPart = matches[1];
return new Link(viaServers, IdentifierKind.RoomAlias, localPart, server);
return new Link(viaServers, IdentifierKind.RoomAlias, localPart, server, eventId);
}
matches = ROOMID_PATTERN.exec(identifier);
if (matches) {
const server = matches[2];
const localPart = matches[1];
return new Link(viaServers, IdentifierKind.RoomId, localPart, server);
return new Link(viaServers, IdentifierKind.RoomId, localPart, server, eventId);
}
matches = GROUPID_PATTERN.exec(identifier);
if (matches) {
@ -131,16 +114,13 @@ export class Link {
return null;
}
constructor(viaServers, identifierKind, localPart, server, messageLocalPart = null, messageServer = null) {
constructor(viaServers, identifierKind, localPart, server, eventId) {
const servers = [server];
if (messageServer) {
servers.push(messageServer);
}
servers.push(...viaServers);
this.servers = orderedUnique(servers);
this.identifierKind = identifierKind;
this.identifier = `${asPrefix(identifierKind)}${localPart}:${server}`;
this.eventId = messageLocalPart ? `$${messageLocalPart}:${messageServer}` : null;
this.eventId = eventId;
}
get kind() {

View file

@ -47,10 +47,6 @@ export class HomeServer {
return body;
}
getGroupProfile(groupId) {
//`/_matrix/client/r0/groups/${groupId}/profile`
}
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") {

View file

@ -37,32 +37,37 @@ export class PreviewViewModel extends ViewModel {
}
async load() {
this.loading = true;
this.emitChange();
for (const server of this._consentedServers) {
try {
const homeserver = await resolveServer(this.request, server);
switch (this._link.kind) {
case LinkKind.User:
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
this.domain = server;
this.loading = false;
this.emitChange();
return;
} catch (err) {
continue;
}
}
const {kind} = this._link;
const supportsPreview = kind === LinkKind.User || kind === LinkKind.Room || kind === LinkKind.Event;
if (supportsPreview) {
this.loading = true;
this.emitChange();
for (const server of this._consentedServers) {
try {
const homeserver = await resolveServer(this.request, server);
switch (this._link.kind) {
case LinkKind.User:
await this._loadUserPreview(homeserver, this._link.identifier);
break;
case LinkKind.Room:
case LinkKind.Event:
await this._loadRoomPreview(homeserver, this._link);
break;
}
// assume we're done if nothing threw
this.domain = server;
this.loading = false;
this.emitChange();
return;
} catch (err) {
continue;
}
}
}
this._setNoPreview(this._link);
this.loading = false;
if (this._consentedServers.length) {
this._setNoPreview(this._link);
if (this._consentedServers.length && supportsPreview) {
this.domain = this._consentedServers[this._consentedServers.length - 1];
this.failed = true;
}