Make the archive responsive (#53)
This also needs a release of `@mlm/hydrogen-view-sdk` with our latest scratch changes in https://github.com/vector-im/hydrogen-web/pull/653 but we can make the dependency update later.
This commit is contained in:
parent
b45c31a597
commit
eb5dc23d5d
|
@ -29,9 +29,50 @@ body {
|
|||
min-width: 0;
|
||||
}
|
||||
|
||||
/* No need to open the right-panel when it's always visible at desktop widths */
|
||||
.room-header-change-dates-button {
|
||||
display: none;
|
||||
color: var(--icon-color--darker-20);
|
||||
}
|
||||
/* No need to close the right-panel when it's always visible at desktop widths */
|
||||
.RightPanelView_buttons .close {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 800px) {
|
||||
/* Only the middle needs to be visible mobile by default */
|
||||
.ArchiveView {
|
||||
grid-template:
|
||||
'status' auto
|
||||
'middle' 1fr /
|
||||
1fr;
|
||||
}
|
||||
/* Which also means hiding the right-panel by default on mobile */
|
||||
.ArchiveView:not(.right-shown) .RightPanelView {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* When the user opens the right-panel, show it */
|
||||
.ArchiveView.right-shown {
|
||||
grid-template:
|
||||
'status' auto
|
||||
'right' 1fr /
|
||||
1fr;
|
||||
}
|
||||
.ArchiveView.right-shown .middle {
|
||||
display: none;
|
||||
}
|
||||
/* And show the button to open the right-panel on mobile */
|
||||
.room-header-change-dates-button {
|
||||
display: block;
|
||||
}
|
||||
/* And show the button to close the right-panel on mobile */
|
||||
.RightPanelView_buttons .close {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.CalendarView {
|
||||
max-width: 280px;
|
||||
font: 100% system-ui;
|
||||
}
|
||||
|
||||
.CalendarView_header {
|
||||
|
@ -132,7 +173,8 @@ body {
|
|||
.CalendarView_dayLink {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
padding: 2px 5px;
|
||||
padding-top: 18%;
|
||||
padding-bottom: 18%;
|
||||
|
||||
text-decoration: none;
|
||||
}
|
||||
|
@ -154,7 +196,6 @@ body {
|
|||
opacity: 0.5;
|
||||
}
|
||||
|
||||
|
||||
/* Error pages */
|
||||
|
||||
.heading-sub-detail {
|
||||
|
@ -162,7 +203,6 @@ body {
|
|||
}
|
||||
|
||||
.tracing-span-list {
|
||||
|
||||
}
|
||||
|
||||
.tracing-span-list-item {
|
||||
|
@ -170,7 +210,6 @@ body {
|
|||
}
|
||||
|
||||
.tracing-span-item-http-details {
|
||||
|
||||
}
|
||||
|
||||
.tracing-span-item-sub-details {
|
||||
|
|
|
@ -209,6 +209,7 @@ function installRoutes(app) {
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
${sanitizeHtml(`<title>${roomData.name} - Matrix Public Archive</title>`)}
|
||||
<link href="${hydrogenStylesUrl}" rel="stylesheet">
|
||||
<link href="${stylesUrl}" rel="stylesheet">
|
||||
|
|
|
@ -55,6 +55,7 @@ async function timeoutMiddleware(req, res, next) {
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Server timeout - Matrix Public Archive</title>
|
||||
<link href="${hydrogenStylesUrl}" rel="stylesheet">
|
||||
<link href="${stylesUrl}" rel="stylesheet">
|
||||
|
|
|
@ -234,6 +234,13 @@ async function mountHydrogen() {
|
|||
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);
|
||||
};
|
||||
|
||||
// FIXME: We shouldn't have to dive into the internal fields to make this work
|
||||
roomViewModel._timelineVM = timelineViewModel;
|
||||
roomViewModel._composerVM = {
|
||||
|
@ -292,6 +299,7 @@ async function mountHydrogen() {
|
|||
class ArchiveViewModel extends ViewModel {
|
||||
roomViewModel = roomViewModel;
|
||||
rightPanelModel = {
|
||||
navigation,
|
||||
activeViewModel: {
|
||||
type: 'custom',
|
||||
customView: RightPanelContentView,
|
||||
|
@ -302,15 +310,27 @@ async function mountHydrogen() {
|
|||
calendarDate: fromDate,
|
||||
}),
|
||||
},
|
||||
closePanel() {
|
||||
const path = this.navigation.path.until('room');
|
||||
this.navigation.applyPath(path);
|
||||
},
|
||||
};
|
||||
|
||||
get shouldShowRightPanel() {
|
||||
return this._shouldShowRightPanel;
|
||||
}
|
||||
|
||||
constructor(options) {
|
||||
super(options);
|
||||
|
||||
this.#setupNavigation();
|
||||
this._updateRightPanel();
|
||||
}
|
||||
|
||||
#setupNavigation() {
|
||||
const rightpanel = this.navigation.observe('right-panel');
|
||||
this.track(rightpanel.subscribe(() => this._updateRightPanel()));
|
||||
|
||||
setupLightboxNavigation(this, 'lightboxViewModel', (eventId) => {
|
||||
return {
|
||||
room,
|
||||
|
@ -318,6 +338,11 @@ async function mountHydrogen() {
|
|||
};
|
||||
});
|
||||
}
|
||||
|
||||
_updateRightPanel() {
|
||||
this._shouldShowRightPanel = !!this.navigation.path.get('right-panel')?.value;
|
||||
this.emitChange('shouldShowRightPanel');
|
||||
}
|
||||
}
|
||||
|
||||
const archiveViewModel = new ArchiveViewModel({
|
||||
|
|
|
@ -2,22 +2,70 @@
|
|||
|
||||
const {
|
||||
TemplateView,
|
||||
AvatarView,
|
||||
RoomView,
|
||||
RightPanelView,
|
||||
LightboxView,
|
||||
viewClassForTile,
|
||||
} = require('hydrogen-view-sdk');
|
||||
|
||||
class RoomHeaderView extends TemplateView {
|
||||
render(t, vm) {
|
||||
return t.div({ className: 'RoomHeader middle-header' }, [
|
||||
t.view(new AvatarView(vm, 32)),
|
||||
t.div({ className: 'room-description' }, [t.h2((vm) => vm.name)]),
|
||||
t.button(
|
||||
{
|
||||
className: 'button-utility room-header-change-dates-button',
|
||||
'aria-label': vm.i18n`Change dates`,
|
||||
onClick: (/*evt*/) => {
|
||||
vm.openRightPanel();
|
||||
},
|
||||
},
|
||||
[
|
||||
// Calendar icon (via `calendar2-date` from Bootstrap)
|
||||
t.svg(
|
||||
{
|
||||
xmlns: 'http://www.w3.org/2000/svg',
|
||||
width: '16',
|
||||
height: '16',
|
||||
viewBox: '0 0 16 16',
|
||||
fill: 'currentColor',
|
||||
style: 'vertical-align: middle;',
|
||||
},
|
||||
[
|
||||
t.path({
|
||||
d: 'M6.445 12.688V7.354h-.633A12.6 12.6 0 0 0 4.5 8.16v.695c.375-.257.969-.62 1.258-.777h.012v4.61h.675zm1.188-1.305c.047.64.594 1.406 1.703 1.406 1.258 0 2-1.066 2-2.871 0-1.934-.781-2.668-1.953-2.668-.926 0-1.797.672-1.797 1.809 0 1.16.824 1.77 1.676 1.77.746 0 1.23-.376 1.383-.79h.027c-.004 1.316-.461 2.164-1.305 2.164-.664 0-1.008-.45-1.05-.82h-.684zm2.953-2.317c0 .696-.559 1.18-1.184 1.18-.601 0-1.144-.383-1.144-1.2 0-.823.582-1.21 1.168-1.21.633 0 1.16.398 1.16 1.23z',
|
||||
}),
|
||||
t.path({
|
||||
d: 'M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5zM2 2a1 1 0 0 0-1 1v11a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1H2z',
|
||||
}),
|
||||
t.path({
|
||||
d: 'M2.5 4a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5H3a.5.5 0 0 1-.5-.5V4z',
|
||||
}),
|
||||
]
|
||||
),
|
||||
]
|
||||
),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
class ArchiveView extends TemplateView {
|
||||
render(t, vm) {
|
||||
return t.div(
|
||||
{
|
||||
className: {
|
||||
ArchiveView: true,
|
||||
'right-shown': (vm) => vm.shouldShowRightPanel,
|
||||
},
|
||||
},
|
||||
[
|
||||
t.view(new RoomView(vm.roomViewModel, viewClassForTile)),
|
||||
t.view(
|
||||
new RoomView(vm.roomViewModel, viewClassForTile, {
|
||||
RoomHeaderView,
|
||||
})
|
||||
),
|
||||
t.view(new RightPanelView(vm.rightPanelModel)),
|
||||
t.mapView(
|
||||
(vm) => vm.lightboxViewModel,
|
||||
|
|
|
@ -66,6 +66,7 @@ class CalendarView extends TemplateView {
|
|||
month: 'long',
|
||||
timeZone: 'UTC',
|
||||
}),
|
||||
// Dropdown arrow
|
||||
t.svg(
|
||||
{
|
||||
xmlns: 'http://www.w3.org/2000/svg',
|
||||
|
|
|
@ -27,8 +27,22 @@ class ArchiveHistory extends History {
|
|||
// downstream call of `urlRouter.attach()` which we do when bootstraping
|
||||
// everything.
|
||||
if (window.history) {
|
||||
super.replaceUrlSilently(url);
|
||||
let replacingUrl = url;
|
||||
// This is a way to make sure the hash gets cleared out
|
||||
if (url === '') {
|
||||
replacingUrl = window.location.pathname;
|
||||
}
|
||||
super.replaceUrlSilently(replacingUrl);
|
||||
}
|
||||
}
|
||||
|
||||
pushUrlSilently(url) {
|
||||
let replacingUrl = url;
|
||||
// This is a way to make sure the hash gets cleared out
|
||||
if (url === '') {
|
||||
replacingUrl = window.location.pathname;
|
||||
}
|
||||
super.pushUrlSilently(replacingUrl);
|
||||
}
|
||||
|
||||
// Make the URLs we use in the UI of the app relative to the room:
|
||||
|
|
Loading…
Reference in New Issue