Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve single room mode #151

Merged
merged 14 commits into from
Jan 5, 2023
Merged
27 changes: 24 additions & 3 deletions frontend/iframe/styles/theme/theme.css
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,30 @@ body {
left: 0;
}

/* Hide back button when in single-room mode. */
.RootView.single-room-mode .RoomHeader .close-middle {
display: none !important;
/* Hide the left panel when in single-room mode. */
.RootView.single-room-mode .SessionView .LeftPanel {
display: none;
}
.RootView.single-room-mode .RightPanelView {
grid-area: middle / right;
}
@media screen and (max-width: 800px) {
.RootView.single-room-mode .RightPanelView {
grid-area: middle;
}
}

/* Make the middle take all the grid when in single-room mode. */
.RootView.single-room-mode .SessionView {
grid-template:
"status status" auto
"middle middle" 1fr /
320px 1fr;
}

/* Always show the back button in single-room mode. */
.RootView.single-room-mode .close-middle {
display: block;
}

/* Remove horizontal scrollbars in pre-session screen. */
Expand Down
64 changes: 64 additions & 0 deletions frontend/iframe/viewmodels/RoomViewModel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { SegmentType } from "hydrogen-web/src/domain/navigation";
import { Segment } from "hydrogen-web/src/domain/navigation/Navigation";
import { RoomViewModel as BaseRoomViewModel } from "hydrogen-web/src/domain/session/room/RoomViewModel";
import { URLRouter } from "../platform/URLRouter";

export class RoomViewModel extends BaseRoomViewModel {
constructor(options) {
super(options);
}

async load() {
super.load();
}

get urlRouter(): URLRouter {
return super.urlRouter;
}

get closeUrl() {
if (this.singleRoomMode) {
const path = this.navigation.path.with(new Segment<SegmentType>("session"));

return this.urlRouter.urlForPath(path);
}

return super.closeUrl;
}

get singleRoomMode(): boolean {
return !!super.platform.config.roomId;
}

get navigation() {
return super.navigation;
}

i18n(parts: TemplateStringsArray, ...expr: any[]): string {
return super.i18n(parts, expr);
}

openDetailsPanel() {
super.openDetailsPanel();
}

get canLeave() {
return super.canLeave;
}

get canForget() {
return super.canForget;
}

forgetRoom() {
super.forgetRoom();
}

get canRejoin() {
return super.canRejoin;
}

rejoinRoom() {
super.rejoinRoom();
}
}
4 changes: 2 additions & 2 deletions frontend/iframe/viewmodels/RootViewModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import { ForcedLogoutViewModel } from "hydrogen-web/src/domain/ForcedLogoutViewM
import { LoginViewModel } from "hydrogen-web/src/domain/login/LoginViewModel";
import { LogoutViewModel } from "hydrogen-web/src/domain/LogoutViewModel";
import { SegmentType } from "hydrogen-web/src/domain/navigation";
import { SessionViewModel } from "hydrogen-web/src/domain/session/SessionViewModel";
import { SessionLoadViewModel } from "hydrogen-web/src/domain/SessionLoadViewModel";
import { SessionPickerViewModel } from "hydrogen-web/src/domain/SessionPickerViewModel";
import { Options as BaseOptions, ViewModel } from "hydrogen-web/src/domain/ViewModel";
import { Client } from "hydrogen-web/src/matrix/Client.js";
import { allSections, Section } from "../platform/Navigation";
import { SessionViewModel } from "./SessionViewModel";

type Options = {} & BaseOptions;

Expand Down Expand Up @@ -112,7 +112,7 @@ export class RootViewModel extends ViewModel<SegmentType, Options> {
void this._showPicker();
}
} else if (sessionId) {
if (this.platform.config.roomId) {
if (this.singleRoomMode) {
this.navigation.push("room", this.platform.config.roomId);
}

Expand Down
106 changes: 106 additions & 0 deletions frontend/iframe/viewmodels/SessionViewModel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { SessionViewModel as BaseSessionViewModel } from "hydrogen-web/src/domain/session/SessionViewModel";
import { RoomViewModel } from "./RoomViewModel";
import { SettingsViewModel } from "./SettingsViewModel";

export class SessionViewModel extends BaseSessionViewModel {
constructor(options) {
super(options);
}

get id() {
return super.id;
}

start() {
super.start();
}

i18n(parts: TemplateStringsArray, ...expr: any[]): string {
return super.i18n(parts, expr);
}

get activeMiddleViewModel() {
return super.activeMiddleViewModel;
}

get roomGridViewModel() {
return super.roomGridViewModel;
}

get leftPanelViewModel() {
return super.leftPanelViewModel;
}

get sessionStatusViewModel() {
return super.sessionStatusViewModel;
}

get currentRoomViewModel() {
// @ts-ignore
return this._roomViewModelObservable?.get();
}

get rightPanelViewModel() {
return super.rightPanelViewModel;
}

get createRoomViewModel() {
return super.createRoomViewModel;
}

get joinRoomViewModel() {
return super.joinRoomViewModel;
}

_updateSettings(settingsOpen) {
if (this.settingsViewModel) {
this.settingsViewModel = super.disposeTracked(super.settingsViewModel);
}
if (settingsOpen) {
this.settingsViewModel = super.track(new SettingsViewModel(super.childOptions({
client: this.client,
})));
void this.settingsViewModel.load();
}
super.emitChange("activeMiddleViewModel");
}

get settingsViewModel(): SettingsViewModel {
// @ts-ignore
return this._settingsViewModel;
}

private set settingsViewModel(vm: SettingsViewModel) {
// @ts-ignore
this._settingsViewModel = vm;
}

dispose(): void {
super.dispose();
}

private get client() {
// @ts-ignore
return this._client;
}

_createRoomViewModelInstance(roomId) {
const room = this.client.session.rooms.get(roomId);
if (room) {
const roomVM = new RoomViewModel(super.childOptions({room}));
void roomVM.load();
return roomVM;
}
return null;
}

async _createArchivedRoomViewModel(roomId) {
const room = await this.client.session.loadArchivedRoom(roomId);
if (room) {
const roomVM = new RoomViewModel(super.childOptions({room}));
void roomVM.load();
return roomVM;
}
return null;
}
}
37 changes: 37 additions & 0 deletions frontend/iframe/viewmodels/SettingsViewModel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { SegmentType } from "hydrogen-web/src/domain/navigation";
import { Segment } from "hydrogen-web/src/domain/navigation/Navigation";
import { SettingsViewModel as BaseSettingsViewModel } from "hydrogen-web/src/domain/session/settings/SettingsViewModel";
import { URLRouter } from "../platform/URLRouter";

export class SettingsViewModel extends BaseSettingsViewModel {
constructor(options) {
super(options);
}

async load() {
return super.load();
}

get urlRouter(): URLRouter {
return super.urlRouter;
}

get navigation() {
return super.navigation;
}

get closeUrl() {
if (this.singleRoomMode) {
const roomId = super.platform.config.roomId;
const path = this.navigation.path.with(new Segment<SegmentType>("room", roomId));

return this.urlRouter.urlForPath(path);
}

return super.closeUrl;
}

get singleRoomMode(): boolean {
return !!super.platform.config.roomId;
}
}
40 changes: 40 additions & 0 deletions frontend/iframe/views/RoomView.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { Menu, MenuOption } from "hydrogen-web/src/platform/web/ui/general/Menu";
import { Popup } from "hydrogen-web/src/platform/web/ui/general/Popup";
import { RoomView as BaseRoomView } from "hydrogen-web/src/platform/web/ui/session/room/RoomView";
import { RoomViewModel } from "../viewmodels/RoomViewModel";

export class RoomView extends BaseRoomView {
constructor(value: RoomViewModel, viewClassForTile) {
super(value, viewClassForTile);
}

_toggleOptionsMenu(evt) {
if (super._optionsPopup && super._optionsPopup.isOpen) {
super._optionsPopup.close();
} else {
const vm: RoomViewModel = super.value;
const options: MenuOption[] = [];
options.push(Menu.option(vm.i18n`Room details`, () => vm.openDetailsPanel()));
if (vm.canLeave) {
options.push(Menu.option(vm.i18n`Leave room`, () => super._confirmToLeaveRoom()).setDestructive());
}
if (vm.canForget) {
options.push(Menu.option(vm.i18n`Forget room`, () => vm.forgetRoom()).setDestructive());
}
if (vm.canRejoin) {
options.push(Menu.option(vm.i18n`Rejoin room`, () => vm.rejoinRoom()));
}
if (vm.singleRoomMode) {
options.push(Menu.option(vm.i18n`Settings`, () => vm.navigation.push("settings")));
}
if (!options.length) {
return;
}
const optionsPopup = new Popup(new Menu(options));
optionsPopup.trackInTemplateView(this);
optionsPopup.showRelativeTo(evt.target, 10);

super._optionsPopup = optionsPopup;
}
}
}
2 changes: 1 addition & 1 deletion frontend/iframe/views/RootView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import { LoginView } from "hydrogen-web/src/platform/web/ui/login/LoginView";
import { SessionLoadView } from "hydrogen-web/src/platform/web/ui/login/SessionLoadView";
import { SessionPickerView } from "hydrogen-web/src/platform/web/ui/login/SessionPickerView";
import { LogoutView } from "hydrogen-web/src/platform/web/ui/LogoutView";
import { SessionView } from "hydrogen-web/src/platform/web/ui/session/SessionView";
import { Section } from "../platform/Navigation";
import { RootViewModel } from "../viewmodels/RootViewModel";
import { SessionView } from "./SessionView";

export class RootView extends TemplateView<RootViewModel> {
constructor(value: RootViewModel) {
Expand Down
60 changes: 60 additions & 0 deletions frontend/iframe/views/SessionView.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { StaticView } from "hydrogen-web/src/platform/web/ui/general/StaticView";
import { CreateRoomView } from "hydrogen-web/src/platform/web/ui/session/CreateRoomView";
import { JoinRoomView } from "hydrogen-web/src/platform/web/ui/session/JoinRoomView";
import { LeftPanelView } from "hydrogen-web/src/platform/web/ui/session/leftpanel/LeftPanelView";
import { RightPanelView } from "hydrogen-web/src/platform/web/ui/session/rightpanel/RightPanelView";
import { viewClassForTile } from "hydrogen-web/src/platform/web/ui/session/room/common";
import { InviteView } from "hydrogen-web/src/platform/web/ui/session/room/InviteView";
import { LightboxView } from "hydrogen-web/src/platform/web/ui/session/room/LightboxView";
import { RoomBeingCreatedView } from "hydrogen-web/src/platform/web/ui/session/room/RoomBeingCreatedView";
import { UnknownRoomView } from "hydrogen-web/src/platform/web/ui/session/room/UnknownRoomView";
import { RoomGridView } from "hydrogen-web/src/platform/web/ui/session/RoomGridView";
import { SessionStatusView } from "hydrogen-web/src/platform/web/ui/session/SessionStatusView";
import { SessionView as BaseSessionView } from "hydrogen-web/src/platform/web/ui/session/SessionView";
import { SettingsView } from "hydrogen-web/src/platform/web/ui/session/settings/SettingsView";
import { SessionViewModel } from "../viewmodels/SessionViewModel";
import { RoomView } from "./RoomView";

export class SessionView extends BaseSessionView {
constructor(value?: SessionViewModel) {
super(value);
}

render(t, vm: SessionViewModel) {
return t.div({
className: {
"SessionView": true,
"middle-shown": (vm: SessionViewModel) => !!vm.activeMiddleViewModel,
"right-shown": (vm: SessionViewModel) => !!vm.rightPanelViewModel,
},
}, [
t.view(new SessionStatusView(vm.sessionStatusViewModel)),
t.view(new LeftPanelView(vm.leftPanelViewModel)),
t.mapView(vm => vm.activeMiddleViewModel, () => {
if (vm.roomGridViewModel) {
return new RoomGridView(vm.roomGridViewModel, viewClassForTile);
} else if (vm.settingsViewModel) {
return new SettingsView(vm.settingsViewModel);
} else if (vm.createRoomViewModel) {
return new CreateRoomView(vm.createRoomViewModel);
} else if (vm.joinRoomViewModel) {
return new JoinRoomView(vm.joinRoomViewModel);
} else if (vm.currentRoomViewModel) {
if (vm.currentRoomViewModel.kind === "invite") {
return new InviteView(vm.currentRoomViewModel);
} else if (vm.currentRoomViewModel.kind === "room") {
return new RoomView(vm.currentRoomViewModel, viewClassForTile);
} else if (vm.currentRoomViewModel.kind === "roomBeingCreated") {
return new RoomBeingCreatedView(vm.currentRoomViewModel);
} else {
return new UnknownRoomView(vm.currentRoomViewModel);
}
} else {
return new StaticView(t => t.div({className: "room-placeholder"}, t.h2(vm.i18n`Choose a room on the left side.`)));
}
}),
t.mapView(vm => vm.lightboxViewModel, lightboxViewModel => lightboxViewModel ? new LightboxView(lightboxViewModel) : null),
t.mapView(vm => vm.rightPanelViewModel, rightPanelViewModel => rightPanelViewModel ? new RightPanelView(rightPanelViewModel) : null)
]);
}
}