Refactor to use `TimelineView` (#117)

We have to figure out our own layout but does get rid of some of the `RoomView` boilerplate.
The `TimelineView` still has outside boilerplate styles to work.

There shouldn't be any visible change.
This commit is contained in:
Eric Eastwood 2022-11-01 08:36:32 -05:00 committed by GitHub
parent b75b807865
commit 718f01e5a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 130 additions and 96 deletions

View File

@ -55,6 +55,15 @@ summary {
min-width: 0;
}
.ArchiveRoomView_mainArea {
grid-area: middle;
display: flex;
flex-direction: column;
width: 100%;
min-width: 0;
min-height: 0;
}
.RoomHeader_actionButton {
display: inline-flex;
justify-content: center;
@ -75,6 +84,19 @@ summary {
display: none;
}
.ArchiveRoomView_mainBody {
flex: 1 1;
display: flex;
flex-direction: column;
height: 100%;
min-height: 0;
min-width: 0;
}
.ArchiveRoomView_mainBody > .Timeline {
flex: 1 0;
}
@media screen and (max-width: 800px) {
/* Only the middle needs to be visible mobile by default */
.ArchiveRoomView {
@ -95,7 +117,7 @@ summary {
'right' 1fr /
1fr;
}
.ArchiveRoomView.right-shown .middle {
.ArchiveRoomView.right-shown .ArchiveRoomView_mainArea {
display: none;
}
/* And show the button to open the right-panel on mobile */

View File

@ -11,7 +11,6 @@ const {
MediaRepository,
createNavigation,
createRouter,
tag,
RetainedObservableValue,
PowerLevels,
@ -22,11 +21,8 @@ const {
encodeKey,
encodeEventIdKey,
Timeline,
ViewModel,
RoomViewModel,
} = require('hydrogen-view-sdk');
const MatrixPublicArchiveURLCreator = require('matrix-public-archive-shared/lib/url-creator');
const ArchiveRoomView = require('matrix-public-archive-shared/views/ArchiveRoomView');
const ArchiveHistory = require('matrix-public-archive-shared/lib/archive-history');
const supressBlankAnchorsReloadingThePage = require('matrix-public-archive-shared/lib/supress-blank-anchors-reloading-the-page');
@ -52,8 +48,6 @@ assert(config);
assert(config.matrixServerUrl);
assert(config.basePath);
const matrixPublicArchiveURLCreator = new MatrixPublicArchiveURLCreator(config.basePath);
let txnCount = 0;
function getFakeEventId() {
txnCount++;
@ -258,93 +252,22 @@ async function mountHydrogen() {
tiles,
};
const roomViewModel = new RoomViewModel({
room,
// This is an arbitrary string (doesn't need to match anything and it shouldn't)
ownUserId: 'xxx-ownUserId',
platform,
urlCreator: urlRouter,
navigation,
});
roomViewModel.openRightPanel = function () {
let path = this.navigation.path.until('room');
path = path.with(this.navigation.segment('right-panel', true));
path = path.with(this.navigation.segment('change-dates', true));
this.navigation.applyPath(path);
};
roomViewModel.roomDirectoryUrl = matrixPublicArchiveURLCreator.roomDirectoryUrl();
Object.defineProperty(roomViewModel, 'timelineViewModel', {
get() {
return timelineViewModel;
},
});
const archiveRoomViewModel = new ArchiveRoomViewModel({
// Hydrogen options
navigation: navigation,
urlCreator: urlRouter,
history: archiveHistory,
// Our options
roomViewModel,
homeserverUrl: config.matrixServerUrl,
timelineViewModel,
room,
fromDate: new Date(fromTimestamp),
// The timestamp from the URL that was originally visited
dayTimestamp: fromTimestamp,
eventEntriesByEventId,
shouldIndex,
basePath: config.basePath,
});
// Create a custom disabled composer view that shows our archive message.
class DisabledArchiveComposerViewModel extends ViewModel {
constructor(options) {
super(options);
// Whenever the `archiveRoomViewModel.currentTopPositionEventEntry`
// changes, re-render the composer view with the updated date.
archiveRoomViewModel.on('change', (changedProps) => {
if (changedProps === 'currentTopPositionEventEntry') {
this.emitChange();
}
});
}
get kind() {
return 'disabled';
}
get description() {
return [
(/*vm*/) => {
const activeDate = new Date(
// If the date from our `archiveRoomViewModel` is available, use that
archiveRoomViewModel?.currentTopPositionEventEntry?.timestamp ||
// Otherwise, use our initial `fromTimestamp`
fromTimestamp
);
const dateString = activeDate.toISOString().split('T')[0];
return `You're viewing an archive of events from ${dateString}. Use a `;
},
tag.a(
{
href: matrixPublicArchiveURLCreator.permalinkForRoom(roomData.id),
rel: 'noopener',
target: '_blank',
},
['Matrix client']
),
` to start chatting in this room.`,
];
}
}
const disabledArchiveComposerViewModel = new DisabledArchiveComposerViewModel({});
Object.defineProperty(roomViewModel, 'composerViewModel', {
get() {
return disabledArchiveComposerViewModel;
},
});
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------

View File

@ -9,18 +9,29 @@ const MatrixPublicArchiveURLCreator = require('matrix-public-archive-shared/lib/
const CalendarViewModel = require('matrix-public-archive-shared/viewmodels/CalendarViewModel');
const DeveloperOptionsContentViewModel = require('matrix-public-archive-shared/viewmodels/DeveloperOptionsContentViewModel');
const RightPanelContentView = require('matrix-public-archive-shared/views/RightPanelContentView');
const AvatarViewModel = require('matrix-public-archive-shared/viewmodels/AvatarViewModel');
class ArchiveRoomViewModel extends ViewModel {
constructor(options) {
super(options);
const { roomViewModel, room, fromDate, eventEntriesByEventId, shouldIndex, basePath } = options;
assert(roomViewModel);
const {
homeserverUrl,
timelineViewModel,
room,
dayTimestamp,
eventEntriesByEventId,
shouldIndex,
basePath,
} = options;
assert(homeserverUrl);
assert(timelineViewModel);
assert(room);
assert(fromDate);
assert(dayTimestamp);
assert(shouldIndex !== undefined);
assert(eventEntriesByEventId);
this._room = room;
this._dayTimestamp = dayTimestamp;
this._eventEntriesByEventId = eventEntriesByEventId;
this._currentTopPositionEventEntry = null;
this._matrixPublicArchiveURLCreator = new MatrixPublicArchiveURLCreator(basePath);
@ -28,11 +39,25 @@ class ArchiveRoomViewModel extends ViewModel {
const navigation = this.navigation;
const urlCreator = this.urlCreator;
this._roomAvatarViewModel = new AvatarViewModel({
homeserverUrlToPullMediaFrom: homeserverUrl,
avatarUrl: this._room.avatarUrl,
avatarTitle: this._room.name || this._room.canonicalAlias || this._room.id,
avatarLetterString:
this._room.name ||
// Strip the `#` off the alias
this._room.canonicalAlias?.[1] ||
// Strip the `!` off the room_id
this._room.id?.[1],
entityId: this._room.id,
});
const initialDate = new Date(dayTimestamp);
this._calendarViewModel = new CalendarViewModel({
// The day being shown in the archive
activeDate: fromDate,
activeDate: initialDate,
// The month displayed in the calendar
calendarDate: fromDate,
calendarDate: initialDate,
room,
basePath,
});
@ -55,7 +80,7 @@ class ArchiveRoomViewModel extends ViewModel {
})
);
this.roomViewModel = roomViewModel;
this._timelineViewModel = timelineViewModel;
// FIXME: Do we have to fake this?
this.rightPanelModel = {
navigation,
@ -136,6 +161,10 @@ class ArchiveRoomViewModel extends ViewModel {
handleLightBoxNavigationChange(initialLightBoxEventId);
}
get timelineViewModel() {
return this._timelineViewModel;
}
setShouldShowDeveloperOptions(shouldShowDeveloperOptions) {
this._developerOptionsModalViewModel.setOpen(shouldShowDeveloperOptions);
}
@ -175,6 +204,33 @@ class ArchiveRoomViewModel extends ViewModel {
) + window.location.hash
);
}
get dayTimestamp() {
return this._dayTimestamp;
}
get roomDirectoryUrl() {
return this._matrixPublicArchiveURLCreator.roomDirectoryUrl();
}
get roomPermalink() {
return this._matrixPublicArchiveURLCreator.permalinkForRoom(this._room.id);
}
get roomName() {
return this._room.name;
}
get roomAvatarViewModel() {
return this._roomAvatarViewModel;
}
openRightPanel() {
let path = this.navigation.path.until('room');
path = path.with(this.navigation.segment('right-panel', true));
path = path.with(this.navigation.segment('change-dates', true));
this.navigation.applyPath(path);
}
}
module.exports = ArchiveRoomViewModel;

View File

@ -3,7 +3,7 @@
const {
TemplateView,
AvatarView,
RoomView,
TimelineView,
RightPanelView,
LightboxView,
} = require('hydrogen-view-sdk');
@ -43,8 +43,8 @@ class RoomHeaderView extends TemplateView {
),
]
),
t.view(new AvatarView(vm, 32)),
t.div({ className: 'room-description' }, [t.h2((vm) => vm.name)]),
t.view(new AvatarView(vm.roomAvatarViewModel, 32)),
t.div({ className: 'room-description' }, [t.h2((vm) => vm.roomName)]),
t.button(
{
className: 'button-utility RoomHeader_actionButton RoomHeader_changeDatesButton',
@ -82,6 +82,37 @@ class RoomHeaderView extends TemplateView {
}
}
class DisabledComposerView extends TemplateView {
render(t /*, vm*/) {
return t.div({ className: 'DisabledComposerView' }, [
t.h3([
t.map(
(vm) => vm.currentTopPositionEventEntry,
(_currentTopPositionEventEntry, t, vm) => {
const activeDate = new Date(
// If the date from our `archiveRoomViewModel` is available, use that
vm?.currentTopPositionEventEntry?.timestamp ||
// Otherwise, use our initial `dayTimestamp`
vm.dayTimestamp
);
const dateString = activeDate.toISOString().split('T')[0];
return t.span(`You're viewing an archive of events from ${dateString}. Use a `);
}
),
t.a(
{
href: (vm) => vm.roomPermalink,
rel: 'noopener',
target: '_blank',
},
['Matrix client']
),
` to start chatting in this room.`,
]),
]);
}
}
class ArchiveRoomView extends TemplateView {
render(t, vm) {
const rootElement = t.div(
@ -112,11 +143,13 @@ class ArchiveRoomView extends TemplateView {
});
}
),
t.view(
new RoomView(vm.roomViewModel, customViewClassForTile, {
RoomHeaderView,
})
),
t.main({ className: 'ArchiveRoomView_mainArea' }, [
t.view(new RoomHeaderView(vm)),
t.main({ className: 'ArchiveRoomView_mainBody' }, [
t.view(new TimelineView(vm.timelineViewModel, customViewClassForTile)),
t.view(new DisabledComposerView(vm)),
]),
]),
t.view(new RightPanelView(vm.rightPanelModel)),
t.mapView(
(vm) => vm.lightboxViewModel,