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:
parent
b9d2da736a
commit
99ff387dec
3 changed files with 56 additions and 30 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Reference in a new issue