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 = [];
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue