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;
|
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 {
|
.CalendarView {
|
||||||
max-width: 280px;
|
|
||||||
font: 100% system-ui;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.CalendarView_header {
|
.CalendarView_header {
|
||||||
|
@ -132,7 +173,8 @@ body {
|
||||||
.CalendarView_dayLink {
|
.CalendarView_dayLink {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 2px 5px;
|
padding-top: 18%;
|
||||||
|
padding-bottom: 18%;
|
||||||
|
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
@ -154,7 +196,6 @@ body {
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Error pages */
|
/* Error pages */
|
||||||
|
|
||||||
.heading-sub-detail {
|
.heading-sub-detail {
|
||||||
|
@ -162,7 +203,6 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
.tracing-span-list {
|
.tracing-span-list {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.tracing-span-list-item {
|
.tracing-span-list-item {
|
||||||
|
@ -170,7 +210,6 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
.tracing-span-item-http-details {
|
.tracing-span-item-http-details {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.tracing-span-item-sub-details {
|
.tracing-span-item-sub-details {
|
||||||
|
|
|
@ -209,6 +209,7 @@ function installRoutes(app) {
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
${sanitizeHtml(`<title>${roomData.name} - Matrix Public Archive</title>`)}
|
${sanitizeHtml(`<title>${roomData.name} - Matrix Public Archive</title>`)}
|
||||||
<link href="${hydrogenStylesUrl}" rel="stylesheet">
|
<link href="${hydrogenStylesUrl}" rel="stylesheet">
|
||||||
<link href="${stylesUrl}" rel="stylesheet">
|
<link href="${stylesUrl}" rel="stylesheet">
|
||||||
|
|
|
@ -55,6 +55,7 @@ async function timeoutMiddleware(req, res, next) {
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<title>Server timeout - Matrix Public Archive</title>
|
<title>Server timeout - Matrix Public Archive</title>
|
||||||
<link href="${hydrogenStylesUrl}" rel="stylesheet">
|
<link href="${hydrogenStylesUrl}" rel="stylesheet">
|
||||||
<link href="${stylesUrl}" rel="stylesheet">
|
<link href="${stylesUrl}" rel="stylesheet">
|
||||||
|
|
|
@ -234,6 +234,13 @@ async function mountHydrogen() {
|
||||||
navigation,
|
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
|
// FIXME: We shouldn't have to dive into the internal fields to make this work
|
||||||
roomViewModel._timelineVM = timelineViewModel;
|
roomViewModel._timelineVM = timelineViewModel;
|
||||||
roomViewModel._composerVM = {
|
roomViewModel._composerVM = {
|
||||||
|
@ -292,6 +299,7 @@ async function mountHydrogen() {
|
||||||
class ArchiveViewModel extends ViewModel {
|
class ArchiveViewModel extends ViewModel {
|
||||||
roomViewModel = roomViewModel;
|
roomViewModel = roomViewModel;
|
||||||
rightPanelModel = {
|
rightPanelModel = {
|
||||||
|
navigation,
|
||||||
activeViewModel: {
|
activeViewModel: {
|
||||||
type: 'custom',
|
type: 'custom',
|
||||||
customView: RightPanelContentView,
|
customView: RightPanelContentView,
|
||||||
|
@ -302,15 +310,27 @@ async function mountHydrogen() {
|
||||||
calendarDate: fromDate,
|
calendarDate: fromDate,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
closePanel() {
|
||||||
|
const path = this.navigation.path.until('room');
|
||||||
|
this.navigation.applyPath(path);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
get shouldShowRightPanel() {
|
||||||
|
return this._shouldShowRightPanel;
|
||||||
|
}
|
||||||
|
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
super(options);
|
super(options);
|
||||||
|
|
||||||
this.#setupNavigation();
|
this.#setupNavigation();
|
||||||
|
this._updateRightPanel();
|
||||||
}
|
}
|
||||||
|
|
||||||
#setupNavigation() {
|
#setupNavigation() {
|
||||||
|
const rightpanel = this.navigation.observe('right-panel');
|
||||||
|
this.track(rightpanel.subscribe(() => this._updateRightPanel()));
|
||||||
|
|
||||||
setupLightboxNavigation(this, 'lightboxViewModel', (eventId) => {
|
setupLightboxNavigation(this, 'lightboxViewModel', (eventId) => {
|
||||||
return {
|
return {
|
||||||
room,
|
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({
|
const archiveViewModel = new ArchiveViewModel({
|
||||||
|
|
|
@ -2,22 +2,70 @@
|
||||||
|
|
||||||
const {
|
const {
|
||||||
TemplateView,
|
TemplateView,
|
||||||
|
AvatarView,
|
||||||
RoomView,
|
RoomView,
|
||||||
RightPanelView,
|
RightPanelView,
|
||||||
LightboxView,
|
LightboxView,
|
||||||
viewClassForTile,
|
viewClassForTile,
|
||||||
} = require('hydrogen-view-sdk');
|
} = 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 {
|
class ArchiveView extends TemplateView {
|
||||||
render(t, vm) {
|
render(t, vm) {
|
||||||
return t.div(
|
return t.div(
|
||||||
{
|
{
|
||||||
className: {
|
className: {
|
||||||
ArchiveView: true,
|
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.view(new RightPanelView(vm.rightPanelModel)),
|
||||||
t.mapView(
|
t.mapView(
|
||||||
(vm) => vm.lightboxViewModel,
|
(vm) => vm.lightboxViewModel,
|
||||||
|
|
|
@ -66,6 +66,7 @@ class CalendarView extends TemplateView {
|
||||||
month: 'long',
|
month: 'long',
|
||||||
timeZone: 'UTC',
|
timeZone: 'UTC',
|
||||||
}),
|
}),
|
||||||
|
// Dropdown arrow
|
||||||
t.svg(
|
t.svg(
|
||||||
{
|
{
|
||||||
xmlns: 'http://www.w3.org/2000/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
|
// downstream call of `urlRouter.attach()` which we do when bootstraping
|
||||||
// everything.
|
// everything.
|
||||||
if (window.history) {
|
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:
|
// Make the URLs we use in the UI of the app relative to the room:
|
||||||
|
|
Loading…
Reference in New Issue