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 = []; this._viewModels = [];
} }
roomViewModelAt(idx) { _posToIdx(x, y) {
return this._viewModels[idx]?.vm; return (y * this.width) + x;
} }
get focusedIndex() { _idxToX(idx) {
return this._selectedIndex; 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) { if (idx === this._selectedIndex) {
return; return;
} }
@ -72,8 +96,13 @@ export class RoomGridViewModel extends ViewModel {
/** /**
* @package * @package
*/ */
roomIndex(roomId) { tryFocusRoom(roomId) {
return this._viewModels.findIndex(vms => vms?.vm._room.id === 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) { _openRoom(room, roomTileVM) {
// for now, we don't support having the same room opened more than once, if (this._gridViewModel?.tryFocusRoom(room.id)) {
// so bail out if we already have the room open return;
if (this._gridViewModel) {
const roomIndex = this._gridViewModel.roomIndex(room.id);
if (roomIndex >= 0) {
this._gridViewModel.setFocusedIndex(roomIndex);
return;
}
} else if (this._currentRoomViewModel?._room.id === room.id) { } else if (this._currentRoomViewModel?._room.id === room.id) {
return; return;
} }

View file

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