171 lines
6.0 KiB
JavaScript
171 lines
6.0 KiB
JavaScript
|
'use strict';
|
||
|
|
||
|
const { ViewModel, setupLightboxNavigation } = require('hydrogen-view-sdk');
|
||
|
|
||
|
const assert = require('matrix-public-archive-shared/lib/assert');
|
||
|
|
||
|
const MatrixPublicArchiveURLCreator = require('matrix-public-archive-shared/lib/url-creator');
|
||
|
const CalendarViewModel = require('matrix-public-archive-shared/viewmodels/CalendarViewModel');
|
||
|
const DeveloperOptionsViewModel = require('matrix-public-archive-shared/viewmodels/DeveloperOptionsViewModel');
|
||
|
const RightPanelContentView = require('matrix-public-archive-shared/views/RightPanelContentView');
|
||
|
|
||
|
class ArchiveRoomViewModel extends ViewModel {
|
||
|
constructor(options) {
|
||
|
super(options);
|
||
|
const { roomViewModel, room, fromDate, eventEntriesByEventId, shouldIndex, basePath } = options;
|
||
|
assert(roomViewModel);
|
||
|
assert(room);
|
||
|
assert(fromDate);
|
||
|
assert(shouldIndex !== undefined);
|
||
|
assert(eventEntriesByEventId);
|
||
|
|
||
|
this._room = room;
|
||
|
this._eventEntriesByEventId = eventEntriesByEventId;
|
||
|
this._currentTopPositionEventEntry = null;
|
||
|
this._matrixPublicArchiveURLCreator = new MatrixPublicArchiveURLCreator(basePath);
|
||
|
|
||
|
this._calendarViewModel = new CalendarViewModel({
|
||
|
// The day being shown in the archive
|
||
|
activeDate: fromDate,
|
||
|
// The month displayed in the calendar
|
||
|
calendarDate: fromDate,
|
||
|
room,
|
||
|
basePath,
|
||
|
});
|
||
|
|
||
|
this._shouldShowDeveloperOptions = false;
|
||
|
this._developerOptionsViewModel = new DeveloperOptionsViewModel(
|
||
|
this.childOptions({
|
||
|
/* any explicit options */
|
||
|
})
|
||
|
);
|
||
|
this._developerOptionsViewModel.loadValuesFromPersistence();
|
||
|
|
||
|
const navigation = this.navigation;
|
||
|
const urlCreator = this.urlCreator;
|
||
|
|
||
|
this.roomViewModel = roomViewModel;
|
||
|
// FIXME: Do we have to fake this?
|
||
|
this.rightPanelModel = {
|
||
|
navigation,
|
||
|
activeViewModel: {
|
||
|
// Our own custom options
|
||
|
type: 'custom',
|
||
|
customView: RightPanelContentView,
|
||
|
calendarViewModel: this._calendarViewModel,
|
||
|
shouldIndex,
|
||
|
get developerOptionsUrl() {
|
||
|
return urlCreator.urlForSegments([
|
||
|
navigation.segment('room', room.id),
|
||
|
navigation.segment('developer-options'),
|
||
|
]);
|
||
|
},
|
||
|
},
|
||
|
closePanel() {
|
||
|
const path = this.navigation.path.until('room');
|
||
|
this.navigation.applyPath(path);
|
||
|
},
|
||
|
};
|
||
|
|
||
|
this.#setupNavigation();
|
||
|
}
|
||
|
|
||
|
#setupNavigation() {
|
||
|
// Make sure the right panel opens when the URL changes (only really matters
|
||
|
// on mobile)
|
||
|
const handleRightPanelNavigationChange = (rightpanelHashExists) => {
|
||
|
this._shouldShowRightPanel = rightpanelHashExists;
|
||
|
this.emitChange('shouldShowRightPanel');
|
||
|
};
|
||
|
const rightpanel = this.navigation.observe('right-panel');
|
||
|
this.track(rightpanel.subscribe(handleRightPanelNavigationChange));
|
||
|
// Also handle the case where the URL already includes right-panel stuff
|
||
|
// from page-load
|
||
|
const initialRightPanel = rightpanel.get();
|
||
|
handleRightPanelNavigationChange(initialRightPanel);
|
||
|
|
||
|
// Make sure the developer options open when the URL changes
|
||
|
const handleDeveloperOptionsNavigationChange = () => {
|
||
|
const shouldShowDeveloperOptions = !!this.navigation.path.get('developer-options')?.value;
|
||
|
this.setShouldShowDeveloperOptions(shouldShowDeveloperOptions);
|
||
|
};
|
||
|
const developerOptions = this.navigation.observe('developer-options');
|
||
|
this.track(developerOptions.subscribe(handleDeveloperOptionsNavigationChange));
|
||
|
// Also handle the case where the URL already includes `#/developer-options`
|
||
|
// stuff from page-load
|
||
|
const initialDeveloperOptions = developerOptions.get();
|
||
|
handleDeveloperOptionsNavigationChange(initialDeveloperOptions);
|
||
|
|
||
|
// Make sure the lightbox opens when the URL changes
|
||
|
setupLightboxNavigation(this, 'lightboxViewModel', (eventId) => {
|
||
|
return {
|
||
|
room: this._room,
|
||
|
eventEntry: this._eventEntriesByEventId[eventId],
|
||
|
};
|
||
|
});
|
||
|
|
||
|
// Also make sure when someone opens the lightbox, the day in the URL
|
||
|
// changes to when the timestamp of the associated event so the link opens
|
||
|
// with the event in the timeline and the lightbox opens again. We don't
|
||
|
// want to have a date mismatch because your scroll is on another day while
|
||
|
// viewing the lightbox.
|
||
|
const handleLightBoxNavigationChange = (eventId) => {
|
||
|
if (eventId) {
|
||
|
const eventEntry = this._eventEntriesByEventId[eventId];
|
||
|
if (eventEntry) {
|
||
|
this.setCurrentTopPositionEventEntry(eventEntry);
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
const lightbox = this.navigation.observe('lightbox');
|
||
|
this.track(lightbox.subscribe(handleLightBoxNavigationChange));
|
||
|
// Also handle the case where the URL already includes `/lightbox/$eventId` (like
|
||
|
// from page-load)
|
||
|
const initialLightBoxEventId = lightbox.get();
|
||
|
handleLightBoxNavigationChange(initialLightBoxEventId);
|
||
|
}
|
||
|
|
||
|
get shouldShowDeveloperOptions() {
|
||
|
return this._shouldShowDeveloperOptions;
|
||
|
}
|
||
|
|
||
|
setShouldShowDeveloperOptions(shouldShowDeveloperOptions) {
|
||
|
this._shouldShowDeveloperOptions = shouldShowDeveloperOptions;
|
||
|
this.emitChange('shouldShowDeveloperOptions');
|
||
|
}
|
||
|
|
||
|
get developerOptionsViewModel() {
|
||
|
return this._developerOptionsViewModel;
|
||
|
}
|
||
|
|
||
|
get eventEntriesByEventId() {
|
||
|
return this._eventEntriesByEventId;
|
||
|
}
|
||
|
|
||
|
get currentTopPositionEventEntry() {
|
||
|
return this._currentTopPositionEventEntry;
|
||
|
}
|
||
|
|
||
|
get shouldShowRightPanel() {
|
||
|
return this._shouldShowRightPanel;
|
||
|
}
|
||
|
|
||
|
setCurrentTopPositionEventEntry(currentTopPositionEventEntry) {
|
||
|
this._currentTopPositionEventEntry = currentTopPositionEventEntry;
|
||
|
this.emitChange('currentTopPositionEventEntry');
|
||
|
|
||
|
// Update the calendar
|
||
|
this._calendarViewModel.setActiveDate(currentTopPositionEventEntry.timestamp);
|
||
|
|
||
|
// Update the URL
|
||
|
this.history.replaceUrlSilently(
|
||
|
this._matrixPublicArchiveURLCreator.archiveUrlForDate(
|
||
|
this._room.id,
|
||
|
new Date(currentTopPositionEventEntry.timestamp)
|
||
|
) + window.location.hash
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
module.exports = ArchiveRoomViewModel;
|