Skip to content

Commit

Permalink
Add a way to highlight tiles
Browse files Browse the repository at this point in the history
  • Loading branch information
MadLittleMods committed Nov 3, 2022
1 parent 7602825 commit dc6ab45
Show file tree
Hide file tree
Showing 10 changed files with 47 additions and 56 deletions.
2 changes: 1 addition & 1 deletion doc/SDK.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ async function main() {
navigation,
});
await vm.load();
const view = new TimelineView(vm.timelineViewModel, { viewClassForTile });
const view = new TimelineView(vm.timelineViewModel, viewClassForTile);
app.appendChild(view.mount());
}
}
Expand Down
7 changes: 7 additions & 0 deletions src/domain/session/room/timeline/TimelineViewModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,13 @@ export class TimelineViewModel extends ViewModel {
}
}

setEventHighlight(eventId, newHighlightValue) {
const eventEntry = this._timeline.getByEventId(eventId);
if(eventEntry) {
eventEntry.setIsHighlighted(newHighlightValue);
}
}

get tiles() {
return this._tiles;
}
Expand Down
4 changes: 4 additions & 0 deletions src/domain/session/room/timeline/tiles/BaseMessageTile.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ export class BaseMessageTile extends SimpleTile {
return this._isContinuation;
}

get isHighlighted() {
return this._entry.isHighlighted;
}

get isUnverified() {
return this._entry.isUnverified;
}
Expand Down
4 changes: 4 additions & 0 deletions src/domain/session/room/timeline/tiles/SimpleTile.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ export class SimpleTile extends ViewModel {
return false;
}

get isHighlighted() {
return false;
}

get hasDateSeparator() {
return false;
}
Expand Down
9 changes: 9 additions & 0 deletions src/matrix/room/timeline/entries/EventEntry.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export class EventEntry extends BaseEventEntry {
constructor(eventEntry, fragmentIdComparer) {
super(fragmentIdComparer);
this._eventEntry = eventEntry;
this._isHighlighted = false;
this._decryptionError = null;
this._decryptionResult = null;
}
Expand Down Expand Up @@ -96,6 +97,14 @@ export class EventEntry extends BaseEventEntry {
return this._eventEntry.event.event_id;
}

get isHighlighted() {
return this._isHighlighted;
}

setIsHighlighted(newValue) {
this._isHighlighted = newValue;
}

setDecryptionResult(result) {
this._decryptionResult = result;
}
Expand Down
7 changes: 6 additions & 1 deletion src/platform/web/ui/css/themes/element/timeline.css
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ limitations under the License.
/* TODO: check whether this is needed for .media to maintain aspect ratio (on IE11) like the 100% above */
/* width: 100%; */
box-sizing: border-box;
border-radius: 4px;
}

.Timeline_message.highlighted,
.AnnouncementView.highlighted {
background-color: #ffff8a;
}

.Timeline_message:not(.continuation) {
Expand Down Expand Up @@ -79,7 +85,6 @@ limitations under the License.
.Timeline_message:hover:not(.disabled), .Timeline_message.selected, .Timeline_message.menuOpen {
/* needs transparency support */
background-color: rgba(141, 151, 165, 0.1);
border-radius: 4px;
}

.Timeline_message:hover > .Timeline_messageOptions,
Expand Down
2 changes: 1 addition & 1 deletion src/platform/web/ui/session/room/RoomView.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export class RoomView extends TemplateView {
)]),
t.mapView(vm => vm.timelineViewModel, timelineViewModel => {
return timelineViewModel ?
new TimelineView(timelineViewModel, { viewClassForTile: this._viewClassForTile }) :
new TimelineView(timelineViewModel, this._viewClassForTile) :
new TimelineLoadingView(vm); // vm is just needed for i18n
}),
t.mapView(vm => vm.composerViewModel,
Expand Down
62 changes: 10 additions & 52 deletions src/platform/web/ui/session/room/TimelineView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,10 @@ export interface TimelineViewModel extends IObservableValue {
setVisibleTileRange(start?: SimpleTile, end?: SimpleTile);
}

function top(node: HTMLElement): number {
return node.offsetTop;
}

function bottom(node: HTMLElement): number {
return node.offsetTop + node.clientHeight;
}


function findFirstNodeIndexAtOrBelow(tiles: HTMLElement, top: number, startIndex: number = (tiles.children.length - 1)): number {
for (var i = startIndex; i >= 0; i--) {
const node = tiles.children[i] as HTMLElement;
Expand All @@ -62,39 +57,16 @@ function findFirstNodeIndexAtOrBelow(tiles: HTMLElement, top: number, startIndex
return 0;
}

type AnchorPosition = "bottom" | "top";

interface TimelineViewOpts {
viewClassForTile: ViewClassForEntryFn
initialAnchorEventId?: string
stickToBottom?: boolean
anchorPosition?: AnchorPosition
}

export class TimelineView extends TemplateView<TimelineViewModel> {

private initialAnchorEventId?: string;
private anchoredNode?: HTMLElement;
private anchoredOffset: number = 0;
private anchorPosition: AnchorPosition = 'bottom';
private anchoredBottom: number = 0;
private stickToBottom: boolean = true;
private tilesView?: TilesListView;
private resizeObserver?: ResizeObserver;
private viewClassForTile: ViewClassForEntryFn;

constructor(vm: TimelineViewModel, {
viewClassForTile,
initialAnchorEventId,
stickToBottom = true,
// TODO: This should default to 'bottom'
anchorPosition= 'top',
}: TimelineViewOpts) {
constructor(vm: TimelineViewModel, private readonly viewClassForTile: ViewClassForEntryFn) {
super(vm);

this.viewClassForTile = viewClassForTile;
this.stickToBottom = stickToBottom;
this.anchorPosition = anchorPosition;
this.initialAnchorEventId = initialAnchorEventId;
}

render(t: Builder<TimelineViewModel>, vm: TimelineViewModel) {
Expand Down Expand Up @@ -152,19 +124,7 @@ export class TimelineView extends TemplateView<TimelineViewModel> {
}

private restoreScrollPosition() {
console.log('restoreScrollPosition', new Error().stack);
const {scrollNode, tilesNode, initialAnchorEventId} = this;

// If there is an initial eventId to anchor to, set this once to scroll to first.
// We have to handle this here after render when the HTML nodes are available.
if (initialAnchorEventId) {
const eventTile = tilesNode.querySelector(`[data-event-id="${initialAnchorEventId}"]`);
if (eventTile) {
this.anchoredNode = eventTile as HTMLElement;
}
// Clear this out after we set the `anchoredNode` once
this.initialAnchorEventId = undefined;
}
const {scrollNode, tilesNode} = this;

const missingTilesHeight = scrollNode.clientHeight - tilesNode.clientHeight;
if (missingTilesHeight > 0) {
Expand All @@ -177,19 +137,18 @@ export class TimelineView extends TemplateView<TimelineViewModel> {
if (this.stickToBottom) {
scrollNode.scrollTop = scrollNode.scrollHeight;
} else if (this.anchoredNode) {
const offsetFunc = this.anchorPosition === 'bottom' ? bottom : top;
const newAnchoredOffset = offsetFunc(this.anchoredNode!);
if (newAnchoredOffset !== this.anchoredOffset) {
const offsetDiff = newAnchoredOffset - this.anchoredOffset;
const newAnchoredBottom = bottom(this.anchoredNode!);
if (newAnchoredBottom !== this.anchoredBottom) {
const bottomDiff = newAnchoredBottom - this.anchoredBottom;
// scrollBy tends to create less scroll jumps than reassigning scrollTop as it does
// not depend on reading scrollTop, which might be out of date as some platforms
// run scrolling off the main thread.
if (typeof scrollNode.scrollBy === "function") {
scrollNode.scrollBy(0, offsetDiff);
scrollNode.scrollBy(0, bottomDiff);
} else {
scrollNode.scrollTop = scrollNode.scrollTop + offsetDiff;
scrollNode.scrollTop = scrollNode.scrollTop + bottomDiff;
}
this.anchoredOffset = newAnchoredOffset;
this.anchoredBottom = newAnchoredBottom;
}
}
// TODO: should we be updating the visible range here as well as the range might have changed even though
Expand All @@ -210,8 +169,7 @@ export class TimelineView extends TemplateView<TimelineViewModel> {
const viewportBottom = scrollTop + clientHeight;
const anchoredNodeIndex = findFirstNodeIndexAtOrBelow(tilesNode, viewportBottom);
this.anchoredNode = tilesNode.childNodes[anchoredNodeIndex] as HTMLElement;
const offsetFunc = this.anchorPosition === 'bottom' ? bottom : top;
this.anchoredOffset = offsetFunc(this.anchoredNode!);
this.anchoredBottom = bottom(this.anchoredNode!);
bottomNodeIndex = anchoredNodeIndex;
}
let topNodeIndex = findFirstNodeIndexAtOrBelow(tilesNode, scrollTop, bottomNodeIndex);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ export class AnnouncementView extends TemplateView {

render(t, vm) {
return t.li({
className: "AnnouncementView",
className: {
"AnnouncementView": true,
"highlighted": vm => vm.isHighlighted,
},
'data-event-id': vm.eventId
}, t.div(vm => vm.announcement));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export class BaseMessageView extends TemplateView {
unverified: vm.isUnverified,
disabled: !this._interactive,
continuation: vm => vm.isContinuation,
"highlighted": vm => vm.isHighlighted,
},
'data-event-id': vm.eventId
}, children);
Expand Down

0 comments on commit dc6ab45

Please sign in to comment.