diff --git a/routes/_components/status/Notification.html b/routes/_components/status/Notification.html index 64e57b9..10b8bf1 100644 --- a/routes/_components/status/Notification.html +++ b/routes/_components/status/Notification.html @@ -1,5 +1,5 @@ {{#if notification.type === 'mention' || notification.type === 'reblog' || notification.type === 'favourite'}} - + ref:node >
@@ -37,8 +37,15 @@ import Status from './Status.html' import StatusHeader from './StatusHeader.html' import { store } from '../../_store/store' + import { restoreFocus } from '../../_utils/restoreFocus' export default { + oncreate() { + let focusSelector = this.get('focusSelector') + if (this.refs.node && focusSelector) { + restoreFocus(this.refs.node, focusSelector) + } + }, components: { Status, StatusHeader diff --git a/routes/_components/status/Status.html b/routes/_components/status/Status.html index 135b892..0d1f252 100644 --- a/routes/_components/status/Status.html +++ b/routes/_components/status/Status.html @@ -5,7 +5,8 @@ aria-posinset="{{index}}" aria-setsize="{{length}}" aria-label="{{ariaLabel}}" - on:recalculateHeight> + on:recalculateHeight + ref:node > {{#if showHeader}} @@ -102,6 +103,7 @@ import { goto } from 'sapper/runtime.js' import { registerClickDelegate, unregisterClickDelegate } from '../../_utils/delegate' import { classname } from '../../_utils/classname' + import { restoreFocus } from '../../_utils/restoreFocus' export default { oncreate() { @@ -110,6 +112,10 @@ // the whole
is clickable in this case registerClickDelegate(delegateKey, (e) => this.onClickOrKeydown(e)) } + let focusSelector = this.get('focusSelector') + if (this.refs.node && focusSelector) { + restoreFocus(this.refs.node, focusSelector) + } }, ondestroy() { let delegateKey = this.get('delegateKey') diff --git a/routes/_components/timeline/NotificationVirtualListItem.html b/routes/_components/timeline/NotificationVirtualListItem.html index 0549361..04bd5b8 100644 --- a/routes/_components/timeline/NotificationVirtualListItem.html +++ b/routes/_components/timeline/NotificationVirtualListItem.html @@ -2,6 +2,7 @@ notification="{{virtualProps.notification}}" timelineType="{{virtualProps.timelineType}}" timelineValue="{{virtualProps.timelineValue}}" + focusSelector="{{virtualProps.focusSelector}}" index="{{virtualIndex}}" length="{{virtualLength}}" on:recalculateHeight /> diff --git a/routes/_components/timeline/StatusVirtualListItem.html b/routes/_components/timeline/StatusVirtualListItem.html index 6b9635e..64a14a5 100644 --- a/routes/_components/timeline/StatusVirtualListItem.html +++ b/routes/_components/timeline/StatusVirtualListItem.html @@ -1,6 +1,7 @@ diff --git a/routes/_components/timeline/Timeline.html b/routes/_components/timeline/Timeline.html index 1253555..c9782d4 100644 --- a/routes/_components/timeline/Timeline.html +++ b/routes/_components/timeline/Timeline.html @@ -79,9 +79,6 @@ console.log('timeline oncreate()') this.setupFocus() setupTimeline() - if (this.store.get('initialized')) { - this.restoreFocus() - } this.setupStreaming() }, ondestroy() { @@ -101,13 +98,22 @@ VirtualListComponent: (timelineType) => { return timelineType === 'notifications' ? NotificationVirtualListItem : StatusVirtualListItem }, - makeProps: ($currentInstance, timelineType, timelineValue) => async (itemId) => { - let res = { timelineType, timelineValue } + makeProps: ($currentInstance, timelineType, timelineValue, $lastFocusedElementSelector) => async (itemId) => { + let res = { + timelineType, + timelineValue + } if (timelineType === 'notifications') { res.notification = await database.getNotification($currentInstance, itemId) } else { res.status = await database.getStatus($currentInstance, itemId) } + if ($lastFocusedElementSelector && $lastFocusedElementSelector.includes(itemId)) { + // this selector is guaranteed to contain the statusId. false positives + // (e.g. notification id "1" matches notification id "11") are okay + // because Status.html won't be able to find the selector which is fine. + res.focusSelector = $lastFocusedElementSelector + } return res }, label: (timeline, $currentInstance, timelineType, timelineValue) => { @@ -262,22 +268,7 @@ this.store.setForTimeline(instanceName, timelineName, { lastFocusedElementSelector: null }) - }, - restoreFocus() { - let lastFocusedElementSelector = this.store.get('lastFocusedElementSelector') - console.log('lastFocused', lastFocusedElementSelector) - if (lastFocusedElementSelector) { - requestAnimationFrame(() => { - requestAnimationFrame(() => { - let element = document.querySelector(lastFocusedElementSelector) - console.log('el', element) - if (element) { - element.focus() - } - }) - }) - } - }, + } } } \ No newline at end of file diff --git a/routes/_components/virtualList/VirtualList.html b/routes/_components/virtualList/VirtualList.html index 8cf0b02..1061b76 100644 --- a/routes/_components/virtualList/VirtualList.html +++ b/routes/_components/virtualList/VirtualList.html @@ -32,7 +32,7 @@ import { mark, stop } from '../../_utils/marks' import isEqual from 'lodash/isEqual' - const DISTANCE_FROM_BOTTOM_TO_FIRE = 400 + const DISTANCE_FROM_BOTTOM_TO_FIRE = 800 const SCROLL_EVENT_THROTTLE = 1000 export default { diff --git a/routes/_components/virtualList/VirtualListContainer.html b/routes/_components/virtualList/VirtualListContainer.html index a10e95c..ddeefeb 100644 --- a/routes/_components/virtualList/VirtualListContainer.html +++ b/routes/_components/virtualList/VirtualListContainer.html @@ -4,6 +4,7 @@ import throttle from 'lodash/throttle' import { isFullscreen, attachFullscreenListener, detachFullscreenListener } from '../../_utils/fullscreen' import { mark, stop } from '../../_utils/marks' + import { scheduleIdleTask } from '../../_utils/scheduleIdleTask' const SCROLL_EVENT_DELAY = 300 @@ -20,20 +21,16 @@ console.log('allVisibleItemsHaveHeight', allVisibleItemsHaveHeight) if (!this.get('initializedScrollTop') && allVisibleItemsHaveHeight && node) { this.set({'initializedScrollTop': true}) - requestAnimationFrame(() => { - mark('set scrollTop') - console.log('forcing scroll top to ', scrollTop) - node.scrollTop = scrollTop - stop('set scrollTop') - }) + mark('set scrollTop') + console.log('forcing scroll top to ', scrollTop) + node.scrollTop = scrollTop + stop('set scrollTop') } }) } else { - requestAnimationFrame(() => { - this.store.setForRealm({ - scrollHeight: node.scrollHeight, - offsetHeight: node.offsetHeight - }) + this.store.setForRealm({ + scrollHeight: node.scrollHeight, + offsetHeight: node.offsetHeight }) } stop('onCreate VirtualListContainer') @@ -75,7 +72,7 @@ }, onScroll(event) { let { scrollTop, scrollHeight } = event.target - requestAnimationFrame(() => { // delay slightly to improve scroll perf + scheduleIdleTask(() => { // delay slightly to improve scroll perf mark('onScroll -> setForRealm()') this.store.setForRealm({scrollTop, scrollHeight}) stop('onScroll -> setForRealm()') diff --git a/routes/_components/virtualList/VirtualListLazyItem.html b/routes/_components/virtualList/VirtualListLazyItem.html index 873db8b..828796a 100644 --- a/routes/_components/virtualList/VirtualListLazyItem.html +++ b/routes/_components/virtualList/VirtualListLazyItem.html @@ -9,6 +9,7 @@