index the room by x,y instead of index from the view

so it is easier to implement a focus-ring as a separate dom node
This commit is contained in:
Bruno Windels 2020-10-07 14:18:35 +02:00
parent b9d2da736a
commit 99ff387dec
3 changed files with 56 additions and 30 deletions

View file

@ -25,15 +25,39 @@ export class RoomGridViewModel extends ViewModel {
this._viewModels = [];
}
roomViewModelAt(idx) {
return this._viewModels[idx]?.vm;
_posToIdx(x, y) {
return (y * this.width) + x;
}
get focusedIndex() {
return this._selectedIndex;
_idxToX(idx) {
return idx % this.width;
}
setFocusedIndex(idx) {
_idxToY(idx) {
return Math.floor(idx / this.width);
}
roomViewModelAt(x, y) {
return this._viewModels[this._posToIdx(x, y)]?.vm;
}
get focusX() {
return this._idxToX(this._selectedIndex);
}
get focusY() {
return this._idxToY(this._selectedIndex);
}
isFocusAt(x, y) {
return this._posToIdx(x, y) === this._selectedIndex;
}
setFocusAt(x, y) {
this._setFocusedIndex(this._posToIdx(x, y));
}
_setFocusedIndex(idx) {
if (idx === this._selectedIndex) {
return;
}
@ -72,8 +96,13 @@ export class RoomGridViewModel extends ViewModel {
/**
* @package
*/
roomIndex(roomId) {
return this._viewModels.findIndex(vms => vms?.vm._room.id === roomId);
tryFocusRoom(roomId) {
const index = this._viewModels.findIndex(vms => vms?.vm._room.id === roomId);
if (index >= 0) {
this._setFocusedIndex(index);
return true;
}
return false;
}
/**

View file

@ -109,14 +109,8 @@ export class SessionViewModel extends ViewModel {
}
_openRoom(room, roomTileVM) {
// for now, we don't support having the same room opened more than once,
// so bail out if we already have the room open
if (this._gridViewModel) {
const roomIndex = this._gridViewModel.roomIndex(room.id);
if (roomIndex >= 0) {
this._gridViewModel.setFocusedIndex(roomIndex);
return;
}
if (this._gridViewModel?.tryFocusRoom(room.id)) {
return;
} else if (this._currentRoomViewModel?._room.id === room.id) {
return;
}

View file

@ -20,24 +20,27 @@ import {TemplateView} from "../general/TemplateView.js";
export class RoomGridView extends TemplateView {
render(t, vm) {
const roomViews = [];
const len = vm.width * vm.height;
for (let i = 0; i < len; i+=1) {
roomViews[i] = t.div({
onClick: () => vm.setFocusedIndex(i),
onFocusin: () => vm.setFocusedIndex(i),
className: {focused: vm => vm.focusedIndex === i},
},t.mapView(vm => vm.roomViewModelAt(i), roomVM => {
if (roomVM) {
return new RoomView(roomVM);
} else {
return new RoomPlaceholderView();
}
}))
const children = [];
for (let y = 0; y < vm.height; y+=1) {
for (let x = 0; x < vm.width; x+=1) {
children.push(t.div({
onClick: () => vm.setFocusAt(x, y),
onFocusin: () => vm.setFocusAt(x, y),
className: "container",
style: `--column: ${x + 1}; --row: ${y + 1}`
},t.mapView(vm => vm.roomViewModelAt(x, y), roomVM => {
if (roomVM) {
return new RoomView(roomVM);
} else {
return new RoomPlaceholderView();
}
})));
}
}
children.push(t.div({className: "focus-ring", style: vm => `--column: ${vm.focusX + 1}; --row: ${vm.focusY + 1}`}));
return t.div({
className: "RoomGridView",
style: `--columns: ${vm.width}; --rows: ${vm.height}`
}, roomViews);
}, children);
}
}