From 820d77a78ffaef2ad2579324d3dd8a022bbe11e0 Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Sat, 10 Feb 2018 12:12:05 -0800 Subject: [PATCH] start on trying to save focus for timeline feels like this isn't really working because I can't distinguish between blur events because the timeline is being destroyed and blur events because the user clicked and we lost focus... not sure how important this feature is, and it adds a lot of complexity in the form of extra attributes to track the focused element --- routes/_components/status/Status.html | 19 +++---- routes/_components/timeline/Timeline.html | 62 +++++++++++++++++++++-- routes/_store/timelineComputations.js | 14 +++-- routes/_utils/events.js | 18 +++++++ 4 files changed, 98 insertions(+), 15 deletions(-) diff --git a/routes/_components/status/Status.html b/routes/_components/status/Status.html index 5c3262c3..7996f06b 100644 --- a/routes/_components/status/Status.html +++ b/routes/_components/status/Status.html @@ -1,7 +1,8 @@
status.reblog ? status.reblog : status, statusId: (originalStatus) => originalStatus.id, - delegateKey: (statusId, timelineType, timelineValue) => `status-${timelineType}-${timelineValue}-${statusId}`, + elementKey: (statusId, timelineType, timelineValue) => `status-${timelineType}-${timelineValue}-${statusId}`, contextualStatusId: ($currentInstance, timelineType, timelineValue, status, notification) => { return `${$currentInstance}/${timelineType}/${timelineValue}/${notification ? notification.id : ''}/${status.id}` }, diff --git a/routes/_components/timeline/Timeline.html b/routes/_components/timeline/Timeline.html index 0fc2aef9..62f98498 100644 --- a/routes/_components/timeline/Timeline.html +++ b/routes/_components/timeline/Timeline.html @@ -1,4 +1,9 @@ -
+
{{#if !$initialized}} {{/if}} @@ -55,11 +60,19 @@ import { database } from '../../_database/database' import { initializeTimeline, fetchTimelineItemsOnScrollToBottom, setupTimeline } from '../../_actions/timeline' import LoadingPage from '../LoadingPage.html' + import { focusWithCapture, blurWithCapture } from '../../_utils/events' export default { - async oncreate() { + oncreate() { console.log('timeline oncreate()') setupTimeline() + if (this.store.get('initialized')) { + console.log('initialized!!!!') + this.restoreFocus() + } + }, + ondestroy() { + console.log('ondestroy') }, data: () => ({ StatusVirtualListItem, @@ -109,6 +122,10 @@ PseudoVirtualList, LoadingPage }, + events: { + focusWithCapture, + blurWithCapture + }, methods: { initialize() { if (this.store.get('initialized') || !this.store.get('timelineItemIds')) { @@ -124,7 +141,46 @@ return } fetchTimelineItemsOnScrollToBottom() - } + }, + saveFocus(e) { + let instanceName = this.store.get('currentInstance') + let timelineName = this.get('timeline') + let lastFocusedElementSelector + let activeElement = e.target + if (activeElement) { + let focusKey = activeElement.getAttribute('focus-key') + if (focusKey) { + lastFocusedElementSelector = `[focus-key=${focusKey}]` + } + } + console.log('saving focus to ', lastFocusedElementSelector) + this.store.setForTimeline(instanceName, timelineName, { + lastFocusedElementSelector + }) + }, + clearFocus() { + /*console.log('clearing focus') + let instanceName = this.store.get('currentInstance') + let timelineName = this.get('timeline') + 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/_store/timelineComputations.js b/routes/_store/timelineComputations.js index 2cfc2c23..dbff7cfe 100644 --- a/routes/_store/timelineComputations.js +++ b/routes/_store/timelineComputations.js @@ -1,11 +1,19 @@ + +function computeForTimeline(store, key) { + store.compute(key, ['currentTimelineData'], (currentTimelineData) => currentTimelineData[key]) +} + + export function timelineComputations (store) { store.compute('currentTimelineData', ['currentInstance', 'currentTimeline', 'timelines'], (currentInstance, currentTimeline, timelines) => { return ((timelines && timelines[currentInstance]) || {})[currentTimeline] || {} }) - store.compute('timelineItemIds', ['currentTimelineData'], (currentTimelineData) => currentTimelineData.timelineItemIds) - store.compute('runningUpdate', ['currentTimelineData'], (currentTimelineData) => currentTimelineData.runningUpdate) - store.compute('initialized', ['currentTimelineData'], (currentTimelineData) => currentTimelineData.initialized) + computeForTimeline(store, 'timelineItemIds') + computeForTimeline(store, 'runningUpdate') + computeForTimeline(store, 'initialized') + computeForTimeline(store, 'lastFocusedElementSelector') + store.compute('lastTimelineItemId', ['timelineItemIds'], (timelineItemIds) => timelineItemIds && timelineItemIds.length && timelineItemIds[timelineItemIds.length - 1]) } diff --git a/routes/_utils/events.js b/routes/_utils/events.js index fc9b144f..1b02ba53 100644 --- a/routes/_utils/events.js +++ b/routes/_utils/events.js @@ -34,3 +34,21 @@ export function mouseover (node, callback) { } } } + +export function focusWithCapture (node, callback) { + node.addEventListener('focus', callback, true) + return { + teardown () { + node.removeEventListener('focus', callback, true) + } + } +} + +export function blurWithCapture (node, callback) { + node.addEventListener('blur', callback, true) + return { + teardown () { + node.removeEventListener('blur', callback, true) + } + } +} \ No newline at end of file