142 lines
5.0 KiB
JavaScript
142 lines
5.0 KiB
JavaScript
'use strict';
|
|
|
|
// Isomorphic script that runs in the browser and on the server for SSR (needs
|
|
// browser context) that renders Hydrogen to the `document.body`.
|
|
//
|
|
// Data is passed in via `window.matrixViewerContext`
|
|
|
|
const assert = require('matrix-viewer-shared/lib/assert');
|
|
const { Platform, MediaRepository, createNavigation, createRouter } = require('hydrogen-view-sdk');
|
|
|
|
const { TIME_PRECISION_VALUES } = require('matrix-viewer-shared/lib/reference-values');
|
|
const RoomView = require('matrix-viewer-shared/views/RoomView');
|
|
const MatrixViewerHistory = require('matrix-viewer-shared/lib/matrix-viewer-history');
|
|
const supressBlankAnchorsReloadingThePage = require('matrix-viewer-shared/lib/supress-blank-anchors-reloading-the-page');
|
|
const RoomViewModel = require('matrix-viewer-shared/viewmodels/RoomViewModel');
|
|
const stubPowerLevelsObservable = require('matrix-viewer-shared/lib/stub-powerlevels-observable');
|
|
|
|
const toTimestamp = window.matrixViewerContext.toTimestamp;
|
|
assert(toTimestamp);
|
|
const precisionFromUrl = window.matrixViewerContext.precisionFromUrl;
|
|
assert(Object.values(TIME_PRECISION_VALUES).includes(precisionFromUrl));
|
|
const roomData = window.matrixViewerContext.roomData;
|
|
assert(roomData);
|
|
const events = window.matrixViewerContext.events;
|
|
assert(events);
|
|
const stateEventMap = window.matrixViewerContext.stateEventMap;
|
|
assert(stateEventMap);
|
|
const shouldIndex = window.matrixViewerContext.shouldIndex;
|
|
assert(shouldIndex !== undefined);
|
|
const config = window.matrixViewerContext.config;
|
|
assert(config);
|
|
assert(config.matrixServerUrl);
|
|
assert(config.basePath);
|
|
assert(config.messageLimit);
|
|
|
|
function addSupportClasses() {
|
|
const input = document.createElement('input');
|
|
input.type = 'month';
|
|
const isMonthTypeSupported = input.type === 'month';
|
|
|
|
// Signal `<input type="month">` support to our CSS
|
|
document.body.classList.toggle('fallback-input-month', !isMonthTypeSupported);
|
|
}
|
|
|
|
supressBlankAnchorsReloadingThePage();
|
|
|
|
// eslint-disable-next-line max-statements
|
|
async function mountHydrogen() {
|
|
console.log('Mounting Hydrogen...');
|
|
console.time('Completed mounting Hydrogen');
|
|
const appElement = document.querySelector('#app');
|
|
|
|
const qs = new URLSearchParams(window?.location?.search);
|
|
const scrollStartEventId = qs.get('at');
|
|
|
|
const platformConfig = {};
|
|
const assetPaths = {};
|
|
const platform = new Platform({
|
|
container: appElement,
|
|
assetPaths,
|
|
config: platformConfig,
|
|
options: { development: true },
|
|
});
|
|
|
|
const navigation = createNavigation();
|
|
platform.setNavigation(navigation);
|
|
|
|
const matrixViewerHistory = new MatrixViewerHistory(
|
|
// We just have to match what Hydrogen is doing here.
|
|
`#/session/123/room/${encodeURIComponent(roomData.id)}`
|
|
);
|
|
const urlRouter = createRouter({
|
|
navigation: navigation,
|
|
// We use our own history because we want the hash to be relative to the
|
|
// room and not include the session/room.
|
|
//
|
|
// Normally, people use `history: platform.history,`
|
|
history: matrixViewerHistory,
|
|
});
|
|
// Make it listen to changes from the history instance. And populate the
|
|
// `Navigation` with path segments to work from so `href`'s rendered on the
|
|
// page don't say `undefined`.
|
|
urlRouter.attach();
|
|
|
|
const mediaRepository = new MediaRepository({
|
|
// Strip the trailing slash from the URL
|
|
homeserver: config.matrixServerUrl.replace(/\/$/, ''),
|
|
});
|
|
|
|
const room = {
|
|
name: roomData.name,
|
|
id: roomData.id,
|
|
canonicalAlias: roomData.canonicalAlias,
|
|
avatarUrl: roomData.avatarUrl,
|
|
avatarColorId: roomData.id,
|
|
// Hydrogen options used by the event TilesCollection (roomVM)
|
|
mediaRepository: mediaRepository,
|
|
// Based on https://github.com/vector-im/hydrogen-web/blob/5f9cfffa3b547991b665f57a8bf715270a1b2ef1/src/matrix/room/BaseRoom.js#L480
|
|
observePowerLevels: async function () {
|
|
return stubPowerLevelsObservable;
|
|
},
|
|
};
|
|
|
|
const roomViewModel = new RoomViewModel({
|
|
// Hydrogen options
|
|
platform: platform,
|
|
navigation: navigation,
|
|
urlRouter: urlRouter,
|
|
history: matrixViewerHistory,
|
|
// Our options
|
|
homeserverUrl: config.matrixServerUrl,
|
|
messageLimit: config.messageLimit,
|
|
room,
|
|
// The timestamp from the URL that was originally visited
|
|
dayTimestampTo: toTimestamp,
|
|
precisionFromUrl,
|
|
scrollStartEventId,
|
|
events,
|
|
stateEventMap,
|
|
shouldIndex,
|
|
historyVisibilityEventMeta: roomData.historyVisibilityEventMeta,
|
|
basePath: config.basePath,
|
|
});
|
|
|
|
// ---------------------------------------------------------------------
|
|
// ---------------------------------------------------------------------
|
|
|
|
// Render what we actually care about
|
|
const view = new RoomView(roomViewModel);
|
|
appElement.replaceChildren(view.mount());
|
|
|
|
addSupportClasses();
|
|
supressBlankAnchorsReloadingThePage();
|
|
|
|
console.timeEnd('Completed mounting Hydrogen');
|
|
}
|
|
|
|
// N.B.: When we run this in a virtual machine (`vm`), it will return the last
|
|
// statement. It's important to leave this as the last statement so we can await
|
|
// the promise it returns and signal that all of the async tasks completed.
|
|
mountHydrogen();
|