From 8aa7ba43ccc5171ccb8b4f1ee5ee55774f3a67c6 Mon Sep 17 00:00:00 2001 From: Midhun Suresh <midhunr@element.io> Date: Wed, 19 Jan 2022 13:40:06 +0530 Subject: [PATCH] Implement UI --- src/style.css | 63 ++++++++++++++++++++++----- src/ui/res/chevron-down.svg | 36 +++++++++++++++ src/ui/res/matrix-logo.svg | 5 +++ src/ui/views/ChatterboxView.ts | 18 +++++++- src/viewmodels/ChatterboxViewModel.ts | 21 ++++++--- src/viewmodels/RootViewModel.ts | 26 ++++++----- 6 files changed, 137 insertions(+), 32 deletions(-) create mode 100644 src/ui/res/chevron-down.svg create mode 100644 src/ui/res/matrix-logo.svg diff --git a/src/style.css b/src/style.css index ffaf7aa..a8d8a4c 100644 --- a/src/style.css +++ b/src/style.css @@ -3,14 +3,11 @@ bottom: 10px; right: 10px; max-width: 375px; + border-radius: 5px; } #chatterbox .Timeline { - height: 500px; -} - -#chatterbox>div { - border-radius: 5px; + height: 450px; } /* @@ -26,7 +23,6 @@ todo: this style should actually be in hydrogen-web width: 32px; height: 32px; border: none; - margin: 5px; background: no-repeat center url('./ui/res/chat-bubbles.svg'), #295dbd; border-radius: 2px; cursor: pointer; @@ -40,8 +36,8 @@ todo: this style should actually be in hydrogen-web justify-content: space-evenly; height: 80px; width: 320px; - border-radius: 5px; } + .PolicyAgreementView-text { padding-bottom: 10px; } @@ -67,15 +63,58 @@ todo: this style should actually be in hydrogen-web .ChatterboxView { width: 375px; - height: 570px; + height: 595px; +} + +.RoomHeaderView { + display: grid; + grid-template-columns: 1fr 6fr 1fr; + align-items: center; + padding: 10px 15px; + height: 35px; + background-color: #295dbd; + border-radius: 5px 5px 0 0; + color: white; + font-weight: 600; + font-size: 1.5rem; +} + +.RoomHeaderView_menu { + display: flex; + justify-content: end; } -.hydrogen { - background-color: transparent !important; +.RoomHeaderView_menu_minimize { + background: url("./ui/res/chevron-down.svg") no-repeat; + height: 20px; + width: 20px; + border: none; + cursor: pointer; +} + +.RoomHeaderView .avatar { + border-radius: 2px; +} + +.ChatterboxView_footer { + display: flex; + align-items: center; + justify-content: end; + font-size: 1.0rem; + font-weight: 600; + box-sizing: border-box; + padding-right: 53px; + color: #9b9797; } -.hydrogen :not(.StartChat) { - background-color: rgba(245, 245, 245, 0.90); +.ChatterboxView_footer>img { + width: 35px; + padding-left: 4px; +} + +.ChatterboxView .MessageComposer_input>textarea { + border-radius: 5px; + border: #c2bebe 1.5px solid; } body { diff --git a/src/ui/res/chevron-down.svg b/src/ui/res/chevron-down.svg new file mode 100644 index 0000000..12c9e04 --- /dev/null +++ b/src/ui/res/chevron-down.svg @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + width="17" + height="9" + viewBox="0 0 17 9" + fill="none" + version="1.1" + id="svg839" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"> + <g + clip-path="url(#clip0)" + id="g832" + transform="rotate(-90,4.3001277,4.8826258)"> + <path + fill-rule="evenodd" + clip-rule="evenodd" + d="M 8.20723,2.70711 C 8.59775,3.09763 8.59878,3.73182 8.20952,4.1236 L 3.27581,9.08934 8.22556,14.0391 c 0.39052,0.3905 0.39155,1.0247 0.00229,1.4165 -0.38926,0.3918 -1.0214,0.3928 -1.41192,0.0023 L 1.15907,9.80101 C 0.768549,9.41049 0.767523,8.7763 1.15678,8.38452 L 6.79531,2.70939 C 7.18457,2.31761 7.8167,2.31658 8.20723,2.70711 Z" + fill="#fff" + id="path830" /> + </g> + <defs + id="defs837"> + <clipPath + id="clip0"> + <rect + width="8" + height="17" + fill="#ffffff" + transform="rotate(180,4.25,8.5)" + id="rect834" + x="0" + y="0" /> + </clipPath> + </defs> +</svg> diff --git a/src/ui/res/matrix-logo.svg b/src/ui/res/matrix-logo.svg new file mode 100644 index 0000000..d24a428 --- /dev/null +++ b/src/ui/res/matrix-logo.svg @@ -0,0 +1,5 @@ +<svg width="75" height="32" xmlns="http://www.w3.org/2000/svg"> + <g fill="#9b9797" fill-rule="nonzero"> + <path d="M.936.732V31.25H3.13v.732H.095V0h3.034v.732zM9.386 10.407v1.544h.044a4.461 4.461 0 0 1 1.487-1.368c.58-.323 1.245-.485 1.993-.485.72 0 1.377.14 1.972.42.595.279 1.047.771 1.355 1.477.338-.5.796-.941 1.377-1.323.58-.383 1.266-.574 2.06-.574.602 0 1.16.074 1.674.22.514.148.954.383 1.322.707.366.323.653.746.859 1.268.205.522.308 1.15.308 1.887v7.633H20.71v-6.464c0-.383-.015-.743-.044-1.082a2.305 2.305 0 0 0-.242-.882 1.473 1.473 0 0 0-.584-.596c-.257-.146-.606-.22-1.047-.22-.44 0-.796.085-1.068.253-.272.17-.485.39-.639.662a2.654 2.654 0 0 0-.308.927 7.074 7.074 0 0 0-.078 1.048v6.354h-3.128v-6.398c0-.338-.007-.673-.021-1.004a2.825 2.825 0 0 0-.188-.916 1.411 1.411 0 0 0-.55-.673c-.258-.168-.636-.253-1.135-.253a2.33 2.33 0 0 0-.584.1 1.94 1.94 0 0 0-.705.374c-.228.184-.422.449-.584.794-.161.346-.242.798-.242 1.357v6.619H6.434V10.407h2.952zM25.842 12.084a3.751 3.751 0 0 1 1.233-1.17 5.37 5.37 0 0 1 1.685-.629 9.579 9.579 0 0 1 1.884-.187c.573 0 1.153.04 1.74.121.588.081 1.124.24 1.609.475.484.235.88.562 1.19.981.308.42.462.975.462 1.666v5.934c0 .516.03 1.008.088 1.478.058.471.161.824.308 1.06H32.87a4.435 4.435 0 0 1-.22-1.104c-.5.515-1.087.876-1.762 1.081a7.084 7.084 0 0 1-2.071.31c-.544 0-1.05-.067-1.52-.2a3.472 3.472 0 0 1-1.234-.617 2.87 2.87 0 0 1-.826-1.059c-.199-.426-.298-.934-.298-1.522 0-.647.114-1.18.342-1.6.227-.419.52-.753.881-1.004.36-.25.771-.437 1.234-.562.462-.125.929-.224 1.399-.298.47-.073.932-.132 1.387-.176.456-.044.86-.11 1.212-.199.353-.088.631-.217.837-.386.206-.169.301-.415.287-.74 0-.337-.055-.606-.166-.804a1.217 1.217 0 0 0-.44-.464 1.737 1.737 0 0 0-.639-.22 5.292 5.292 0 0 0-.782-.055c-.617 0-1.101.132-1.454.397-.352.264-.558.706-.617 1.323h-3.128c.044-.735.227-1.345.55-1.83zm6.179 4.423a5.095 5.095 0 0 1-.639.165 9.68 9.68 0 0 1-.716.11c-.25.03-.5.067-.749.11a5.616 5.616 0 0 0-.694.177 2.057 2.057 0 0 0-.594.298c-.17.125-.305.284-.408.474-.103.192-.154.434-.154.728 0 .28.051.515.154.706.103.192.242.342.419.453.176.11.381.187.617.231.234.044.477.066.726.066.617 0 1.094-.102 1.432-.309.338-.205.587-.452.75-.739.16-.286.26-.576.297-.87.036-.295.055-.53.055-.707v-1.17a1.4 1.4 0 0 1-.496.277zM43.884 10.407v2.096h-2.291v5.647c0 .53.088.883.264 1.059.176.177.529.265 1.057.265.177 0 .345-.007.507-.022.161-.015.316-.037.463-.066v2.426a7.49 7.49 0 0 1-.882.089 21.67 21.67 0 0 1-.947.022c-.484 0-.944-.034-1.377-.1a3.233 3.233 0 0 1-1.145-.386 2.04 2.04 0 0 1-.782-.816c-.191-.353-.287-.816-.287-1.39v-6.728H36.57v-2.096h1.894v-3.42h3.129v3.42h2.29zM48.355 10.407v2.118h.044a3.907 3.907 0 0 1 1.454-1.754 4.213 4.213 0 0 1 1.036-.497 3.734 3.734 0 0 1 1.145-.176c.206 0 .433.037.683.11v2.912a5.862 5.862 0 0 0-.528-.077 5.566 5.566 0 0 0-.595-.033c-.573 0-1.058.096-1.454.287a2.52 2.52 0 0 0-.958.783 3.143 3.143 0 0 0-.518 1.158 6.32 6.32 0 0 0-.154 1.434v5.14h-3.128V10.407h2.973zM54.039 8.642V6.06h3.128v2.582H54.04zm3.128 1.765v11.405H54.04V10.407h3.128zM58.797 10.407h3.569l2.005 2.978 1.982-2.978h3.459l-3.745 5.339 4.208 6.067h-3.57l-2.378-3.596-2.38 3.596h-3.502l4.097-6.001zM74.094 31.25V.732H71.9V0h3.035v31.982H71.9v-.732z"/> + </g> +</svg> diff --git a/src/ui/views/ChatterboxView.ts b/src/ui/views/ChatterboxView.ts index 632bd0b..9d40096 100644 --- a/src/ui/views/ChatterboxView.ts +++ b/src/ui/views/ChatterboxView.ts @@ -1,4 +1,4 @@ -import { TemplateView, TimelineView, LoadingView } from "hydrogen-view-sdk"; +import { TemplateView, TimelineView, LoadingView, AvatarView, RoomViewModel } from "hydrogen-view-sdk"; import { Builder } from "hydrogen-view-sdk/types/platform/web/ui/general/TemplateView"; import { MessageComposer } from "hydrogen-view-sdk"; import { ChatterboxViewModel } from "../../viewmodels/ChatterboxViewModel"; @@ -6,8 +6,22 @@ import { ChatterboxViewModel } from "../../viewmodels/ChatterboxViewModel"; export class ChatterboxView extends TemplateView<ChatterboxViewModel> { render(t: Builder<ChatterboxViewModel>) { return t.div({className: "ChatterboxView"}, [ + t.mapView(vm => vm.roomViewModel? vm: null, vm => vm ? new RoomHeaderView(vm) : null), t.mapView(vm => vm.timelineViewModel, vm => vm ? new TimelineView(vm) : new LoadingView()), - t.mapView(vm => vm.messageComposerViewModel, vm => vm ? new MessageComposer(vm) : null) + t.mapView(vm => vm.messageComposerViewModel, vm => vm ? new MessageComposer(vm) : null), + t.div({className: "ChatterboxView_footer"}, ["Powered by", t.img({src:"./src/ui/res/matrix-logo.svg"})]), + ]); + } +} + +class RoomHeaderView extends TemplateView<ChatterboxViewModel> { + render(t: Builder<ChatterboxViewModel>, vm) { + return t.div({ className: "RoomHeaderView" }, [ + t.view(new AvatarView(vm.roomViewModel, 30)), + t.div({ className: "RoomHeaderView_name" }, vm => vm.roomViewModel.name), + t.div({ className: "RoomHeaderView_menu" }, [ + t.button({ className: "RoomHeaderView_menu_minimize", onClick: () => vm.minimize() }) + ]), ]); } } diff --git a/src/viewmodels/ChatterboxViewModel.ts b/src/viewmodels/ChatterboxViewModel.ts index b3c3d36..342b4b7 100644 --- a/src/viewmodels/ChatterboxViewModel.ts +++ b/src/viewmodels/ChatterboxViewModel.ts @@ -1,14 +1,16 @@ import { RoomViewModel, ViewModel, TimelineViewModel, ComposerViewModel} from "hydrogen-view-sdk"; export class ChatterboxViewModel extends ViewModel { - private _timelineViewModel?: TimelineViewModel; private _messageComposerViewModel?: ComposerViewModel; + private _roomViewModel?: RoomViewModel; private _loginPromise: Promise<void>; + private _applySegment: (segment) => void; constructor(options) { super(options); this._client = options.client; this._loginPromise = options.loginPromise; + this._applySegment = options.applySegment; } async loadRoom() { @@ -16,16 +18,15 @@ export class ChatterboxViewModel extends ViewModel { await this._loginPromise; const roomId = this._options.config["auto_join_room"]; const room = this._session.rooms.get(roomId) ?? await this._joinRoom(roomId); - const roomVm = new RoomViewModel({ + this._roomViewModel = new RoomViewModel({ room, ownUserId: this._session.userId, platform: this.platform, urlCreator: this.urlCreator, navigation: this.navigation, }); - await roomVm.load(); - this._timelineViewModel = roomVm.timelineViewModel; - this._messageComposerViewModel = new ComposerViewModel(roomVm); + await this._roomViewModel.load(); + this._messageComposerViewModel = new ComposerViewModel(this._roomViewModel); this.emitChange("timelineViewModel"); } @@ -52,13 +53,21 @@ export class ChatterboxViewModel extends ViewModel { return promise; } + minimize() { + this._applySegment("start"); + } + get timelineViewModel() { - return this._timelineViewModel; + return this._roomViewModel?.timelineViewModel; } get messageComposerViewModel() { return this._messageComposerViewModel; } + + get roomViewModel() { + return this._roomViewModel; + } private get _session() { return this._client.session; diff --git a/src/viewmodels/RootViewModel.ts b/src/viewmodels/RootViewModel.ts index 7957949..fa7a999 100644 --- a/src/viewmodels/RootViewModel.ts +++ b/src/viewmodels/RootViewModel.ts @@ -39,29 +39,31 @@ export class RootViewModel extends ViewModel { private async _showTimeline(loginPromise: Promise<void>) { this._activeSection = "timeline"; - this._chatterBoxViewModel = new ChatterboxViewModel( - this.childOptions({ - client: this._client, - config: this._config, - state: this._state, - applySegment: this._applySegment, - loginPromise, - }) - ); - this._chatterBoxViewModel.loadRoom(); + if (!this._chatterBoxViewModel) { + this._chatterBoxViewModel = this.track(new ChatterboxViewModel( + this.childOptions({ + client: this._client, + config: this._config, + state: this._state, + applySegment: this._applySegment, + loginPromise, + }) + )); + this._chatterBoxViewModel.loadRoom(); + } this.emitChange("activeSection"); } private _showAccountSetup() { this._activeSection = "account-setup"; - this._accountSetupViewModel = new AccountSetupViewModel( + this._accountSetupViewModel = this.track(new AccountSetupViewModel( this.childOptions({ client: this._client, config: this._config, state: this._state, applySegment: this._applySegment, }) - ); + )); this.emitChange("activeSection"); } -- GitLab