Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Peeking unknown rooms #1037

Open
wants to merge 10 commits into
base: master
Choose a base branch
from

Conversation

ashfame
Copy link

@ashfame ashfame commented Feb 16, 2023

👋 This PR introduces the preview/peeking functionality when you load an unknown room by directly going to the URL http://localhost:3000/#/session/3442497412902854/room/!wOlkWNmgkAZFxbTaqj%3Amatrix.org

When you land on this page, we check whether the room supports preview/peeking i.e. world_readable history visibility by showing a spinner in the UI:

Screenshot 2023-02-16 at 6 51 20 PM

Then if the room isn't preview-able, the spinner goes away and we are left with Unknown Room View exactly how it is prior to this PR. But in case, if its possible to preview the room messages, we fetch the 100 most recent messages from the homeserver and store them in indexedDB tables (timelineEvents and timelineFragments) as they would have been stored via sync response for a regular room. On every page load, the old messages stored in both tables are deleted and freshly fetched 100 messages are shown. Also when you are navigating away from a room, by clicking on another room from left sidebar, we delete the data from both tables that were fetched in context of peeking.

Screenshot 2023-02-16 at 6 59 51 PM

Currently back-scrolling works but it doesn't sync new messages i.e. doesn't show more messages as they come in, in the room. Also, the users are currently displayed as their matrix identity.

Looking forward to your review and happy to make any changes as needed to get this merged :)

ashfame and others added 9 commits February 15, 2023 18:44
…e by fetching messages and storing in the indexed db tables
…nd loading things async and updating view as we do

This shows a spinner on UnknownRoomView stating "checking preview capability" and goes away when done
and if room is world_readable, then renders the timeline with the last 100 messages
@psrpinto
Copy link
Contributor

Related: #719

- UnknownRoomViewModel now receives a promise using which it can display a spinner to the user indicating we are checking whether the preview is possible for this room
and updates the model to WorldReadableRoomViewModel
- kind is now changed to "preview" for WorldReadableRooms
- data stored is now deleted when navigating away to another room by clicking on it
@ashfame
Copy link
Author

ashfame commented Feb 27, 2023

@MidhunSureshR This is now finished and ready for your review :)

Copy link
Member

@MidhunSureshR MidhunSureshR left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doing an initial review; mostly looks good 👍

@@ -41,7 +41,7 @@ export class RoomViewModel extends ErrorReportViewModel {
this._composerVM = null;
if (room.isArchived) {
this._composerVM = this.track(new ArchivedViewModel(this.childOptions({archivedRoom: room})));
} else {
} else if (!room.isWorldReadable) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see this property (isWorldReadable) added to Room anywhere?

@@ -29,6 +30,11 @@ export class UnknownRoomView extends TemplateView {
onClick: () => vm.join(),
disabled: vm => vm.busy,
}, vm.i18n`Join room`),
t.br(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use CSS to add some margin/padding instead of the br element?

@@ -29,6 +30,11 @@ export class UnknownRoomView extends TemplateView {
onClick: () => vm.join(),
disabled: vm => vm.busy,
}, vm.i18n`Join room`),
t.br(),
t.if(vm => vm.checkingPreviewCapability, t => t.div({className: "checkingPreviewCapability"}, [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
t.if(vm => vm.checkingPreviewCapability, t => t.div({className: "checkingPreviewCapability"}, [
t.if(vm => vm.checkingPreviewCapability, t => t.div({className: "UnknownRoomVIew__PreviewIndicator"}, [

Following BEM

@@ -29,6 +30,11 @@ export class UnknownRoomView extends TemplateView {
onClick: () => vm.join(),
disabled: vm => vm.busy,
}, vm.i18n`Join room`),
t.br(),
t.if(vm => vm.checkingPreviewCapability, t => t.div({className: "checkingPreviewCapability"}, [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
t.if(vm => vm.checkingPreviewCapability, t => t.div({className: "checkingPreviewCapability"}, [
t.if(vm => vm.checkingPreviewCapability, t => t.div({className: "UnknownRoomVIew__PreviewIndicator"}, [

Following BEM

});
}

async _fetchWorldReadableRoomEvents(roomId, limit = 30, dir = 'b', end = null, log = null) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a typescript const enum for dir? You can add it in HomeSeverApi.

log.set("id", roomId);
let options = {
limit: limit,
dir: 'b',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
dir: 'b',
dir

Comment on lines +1077 to +1086
const resp = await this._hsApi.currentState(roomId).response();
for ( let i=0; i<resp.length; i++ ) {
if ( resp[i].type === 'm.room.name') {
summary["name"] = resp[i].content.name;
} else if ( resp[i].type === 'm.room.canonical_alias' ) {
summary["canonicalAlias"] = resp[i].content.alias;
} else if ( resp[i].type === 'm.room.avatar' ) {
summary["avatarUrl"] = resp[i].content.url;
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We usually use for-of loops whenever possible. Also can you refactor the if-else ladder here into a switch-case?

return new UnknownRoomViewModel(this.childOptions({
roomIdOrAlias,
session: this._client.session,
isWorldReadablePromise: isWorldReadablePromise
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
isWorldReadablePromise: isWorldReadablePromise
isWorldReadablePromise

}));
}

async _createWorldReadableRoomViewModel(roomIdOrAlias) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this method used anywhere?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants