mirror of
https://github.com/vector-im/hydrogen-web.git
synced 2024-12-23 03:25:12 +01:00
add LeftPanelView(Model) with room filtering
This commit is contained in:
parent
c8125595a7
commit
cac3daca72
@ -1,5 +1,6 @@
|
||||
/*
|
||||
Copyright 2020 Bruno Windels <bruno@windels.cloud>
|
||||
Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -14,7 +15,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import {RoomTileViewModel} from "./roomlist/RoomTileViewModel.js";
|
||||
import {LeftPanelViewModel} from "./leftpanel/LeftPanelViewModel.js";
|
||||
import {RoomViewModel} from "./room/RoomViewModel.js";
|
||||
import {SessionStatusViewModel} from "./SessionStatusViewModel.js";
|
||||
import {ViewModel} from "../ViewModel.js";
|
||||
@ -29,22 +30,22 @@ export class SessionViewModel extends ViewModel {
|
||||
reconnector: sessionContainer.reconnector,
|
||||
session: sessionContainer.session,
|
||||
})));
|
||||
this._leftPanelViewModel = new LeftPanelViewModel(this.childOptions({
|
||||
rooms: this._session.rooms,
|
||||
openRoom: this._openRoom.bind(this)
|
||||
}));
|
||||
this._currentRoomTileViewModel = null;
|
||||
this._currentRoomViewModel = null;
|
||||
const roomTileVMs = this._session.rooms.mapValues((room, emitChange) => {
|
||||
return new RoomTileViewModel({
|
||||
room,
|
||||
emitChange,
|
||||
emitOpen: this._openRoom.bind(this)
|
||||
});
|
||||
});
|
||||
this._roomList = roomTileVMs.sortValues((a, b) => a.compare(b));
|
||||
}
|
||||
|
||||
start() {
|
||||
this._sessionStatusViewModel.start();
|
||||
}
|
||||
|
||||
get leftPanelViewModel() {
|
||||
return this._leftPanelViewModel;
|
||||
}
|
||||
|
||||
get sessionStatusViewModel() {
|
||||
return this._sessionStatusViewModel;
|
||||
}
|
||||
|
58
src/domain/session/leftpanel/LeftPanelViewModel.js
Normal file
58
src/domain/session/leftpanel/LeftPanelViewModel.js
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
Copyright 2020 Bruno Windels <bruno@windels.cloud>
|
||||
Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import {ViewModel} from "../../ViewModel.js";
|
||||
import {RoomTileViewModel} from "./RoomTileViewModel.js";
|
||||
import {RoomFilter} from "./RoomFilter.js";
|
||||
import {ApplyMap} from "../../../observable/map/ApplyMap.js";
|
||||
|
||||
export class LeftPanelViewModel extends ViewModel {
|
||||
constructor(options) {
|
||||
super(options);
|
||||
const {rooms, openRoom} = options;
|
||||
const roomTileVMs = rooms.mapValues((room, emitChange) => {
|
||||
return new RoomTileViewModel({
|
||||
room,
|
||||
emitChange,
|
||||
emitOpen: openRoom
|
||||
});
|
||||
});
|
||||
this._roomListFilterMap = new ApplyMap(roomTileVMs);
|
||||
this._roomList = this._roomListFilterMap.sortValues((a, b) => a.compare(b));
|
||||
}
|
||||
|
||||
get roomList() {
|
||||
return this._roomList;
|
||||
}
|
||||
|
||||
clearFilter() {
|
||||
this._roomListFilterMap.setApply(null);
|
||||
this._roomListFilterMap.applyOnce((roomId, vm) => vm.hidden = false);
|
||||
}
|
||||
|
||||
setFilter(query) {
|
||||
query = query.trim();
|
||||
if (query.length === 0) {
|
||||
this.clearFilter();
|
||||
} else {
|
||||
const filter = new RoomFilter(query);
|
||||
this._roomListFilterMap.setApply((roomId, vm) => {
|
||||
vm.hidden = !filter.matches(vm);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
26
src/domain/session/leftpanel/RoomFilter.js
Normal file
26
src/domain/session/leftpanel/RoomFilter.js
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
export class RoomFilter {
|
||||
constructor(query) {
|
||||
this._parts = query.split(" ").map(s => s.toLowerCase().trim());
|
||||
}
|
||||
|
||||
matches(roomTileVM) {
|
||||
const name = roomTileVM.name.toLowerCase();
|
||||
return this._parts.every(p => name.includes(p));
|
||||
}
|
||||
}
|
@ -14,10 +14,20 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
.LeftPanel {
|
||||
overflow-y: auto;
|
||||
overscroll-behavior: contain;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.LeftPanel .filter {
|
||||
flex: 0;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.LeftPanel .filter input {
|
||||
display: block;
|
||||
flex: 1;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.LeftPanel ul {
|
||||
@ -26,19 +36,24 @@ limitations under the License.
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.LeftPanel li {
|
||||
.RoomList {
|
||||
overflow-y: auto;
|
||||
overscroll-behavior: contain;
|
||||
}
|
||||
|
||||
.RoomList li {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.LeftPanel div.description {
|
||||
.RoomList .description {
|
||||
margin: 0;
|
||||
flex: 1 1 0;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.LeftPanel .description > .name {
|
||||
.RoomList .description > .name {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
|
49
src/ui/web/session/leftpanel/LeftPanelView.js
Normal file
49
src/ui/web/session/leftpanel/LeftPanelView.js
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
Copyright 2020 Bruno Windels <bruno@windels.cloud>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import {ListView} from "../../general/ListView.js";
|
||||
import {TemplateView} from "../../general/TemplateView.js";
|
||||
import {RoomTileView} from "./RoomTileView.js";
|
||||
|
||||
export class LeftPanelView extends TemplateView {
|
||||
render(t, vm) {
|
||||
const filterInput = t.input({
|
||||
type: "text",
|
||||
placeholder: vm.i18n`Filter rooms…`,
|
||||
"aria-label": vm.i18n`Filter rooms by name`,
|
||||
autocomplete: true,
|
||||
name: "room-filter",
|
||||
onInput: event => vm.setFilter(event.target.value),
|
||||
});
|
||||
return t.div({className: "LeftPanel"}, [
|
||||
t.div({className: "filter"}, [
|
||||
filterInput,
|
||||
t.button({onClick: () => {
|
||||
filterInput.value = "";
|
||||
vm.clearFilter();
|
||||
}}, vm.i18n`Clear`)
|
||||
]),
|
||||
t.view(new ListView(
|
||||
{
|
||||
className: "RoomList",
|
||||
list: vm.roomList,
|
||||
onItemClick: (roomTile, event) => roomTile.clicked(event)
|
||||
},
|
||||
roomTileVM => new RoomTileView(roomTileVM)
|
||||
))
|
||||
]);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user