implement better timeline navigations with fades

This commit is contained in:
Nolan Lawson 2018-03-29 23:16:53 -07:00
parent 5426c5a0ef
commit 3b8f551477
19 changed files with 259 additions and 141 deletions

View File

@ -66,19 +66,6 @@ async function fetchTimelineItemsAndPossiblyFallBack () {
stop('fetchTimelineItemsAndPossiblyFallBack') stop('fetchTimelineItemsAndPossiblyFallBack')
} }
export function initializeTimeline () {
mark('initializeTimeline')
let instanceName = store.get('currentInstance')
let timeline = store.get('currentTimeline')
requestAnimationFrame(() => {
requestAnimationFrame(() => {
console.log('initialized')
store.setForTimeline(instanceName, timeline, {initialized: true})
})
})
stop('initializeTimeline')
}
export async function setupTimeline () { export async function setupTimeline () {
mark('setupTimeline') mark('setupTimeline')
// If we don't have any item ids, or if the current item ids are stale // If we don't have any item ids, or if the current item ids are stale

View File

@ -0,0 +1,54 @@
<!--
Same as TimelinePage.html, but needs to manage visibility of ComposeBox itself
without a div wrapper due to sticky-positioned compose button.
TODO: this is a bit hacky due to code duplication
-->
<div class="timeline-home-page" aria-busy="{{hideTimeline}}">
{{#if hidePage}}
<LoadingPage />
{{/if}}
{{#if $currentVerifyCredentials }}
<ComposeBox realm="home" hidden="{{hidePage}}"/>
{{/if}}
<div class="timeline-home-anchor-container">
{{#if !hidePage && hideTimeline}}
<LoadingPage />
{{/if}}
<div class="timeline-home-reveal-container {{hideTimeline ? 'hidden' : ''}}">
<LazyTimeline timeline="home" />
</div>
</div>
</div>
<style>
.timeline-home-page, .timeline-home-anchor-container {
position: relative;
}
.timeline-home-reveal-container {
transition: opacity 0.2s linear; /* main page reveal */
}
</style>
<script>
import LazyTimeline from '.././_components/timeline/LazyTimeline.html'
import { store } from '.././_store/store.js'
import LoadingPage from '../_components/LoadingPage.html'
import ComposeBox from '../_components/compose/ComposeBox.html'
export default {
oncreate () {
this.store.set({
timelineInitialized: false,
timelinePreinitialized: false
})
},
computed: {
hidePage: ($timelineInitialized, $timelinePreinitialized) => !$timelineInitialized && !$timelinePreinitialized,
hideTimeline: ($timelineInitialized) => !$timelineInitialized,
},
store: () => store,
components: {
LazyTimeline,
LoadingPage,
ComposeBox
}
}
</script>

View File

@ -0,0 +1,47 @@
<div class="timeline-page" aria-busy="{{hideTimeline}}">
{{#if hidePage}}
<LoadingPage />
{{/if}}
<div class="timeline-slot-reveal-container {{hidePage ? 'hidden' : ''}}">
<slot></slot>
</div>
<div class="timeline-anchor-container">
{{#if !hidePage && hideTimeline}}
<LoadingPage />
{{/if}}
<div class="timeline-reveal-container {{hideTimeline ? 'hidden' : ''}}">
<LazyTimeline :timeline />
</div>
</div>
</div>
<style>
.timeline-page, .timeline-anchor-container {
position: relative;
}
.timeline-reveal-container, .timeline-slot-reveal-container {
transition: opacity 0.2s linear; /* main page reveal */
}
</style>
<script>
import LazyTimeline from '.././_components/timeline/LazyTimeline.html'
import { store } from '.././_store/store.js'
import LoadingPage from '../_components/LoadingPage.html'
export default {
oncreate () {
this.store.set({
timelineInitialized: false,
timelinePreinitialized: false
})
},
computed: {
hidePage: ($timelineInitialized, $timelinePreinitialized) => !$timelineInitialized && !$timelinePreinitialized,
hideTimeline: ($timelineInitialized) => !$timelineInitialized,
},
store: () => store,
components: {
LazyTimeline,
LoadingPage
}
}
</script>

View File

@ -1,4 +1,4 @@
<div class="compose-box {{overLimit ? 'over-char-limit' : ''}} {{realm === 'dialog' ? 'dialog-size' : '' }}"> <div class="{{className}} {{hideAndFadeIn}}">
<ComposeAuthor /> <ComposeAuthor />
{{#if contentWarningShown}} {{#if contentWarningShown}}
<div class="compose-content-warning-wrapper" <div class="compose-content-warning-wrapper"
@ -12,11 +12,11 @@
<ComposeLengthIndicator :length :overLimit /> <ComposeLengthIndicator :length :overLimit />
<ComposeMedia :realm :media /> <ComposeMedia :realm :media />
</div> </div>
<div class="compose-box-button-sentinel" ref:sentinel></div> <div class="compose-box-button-sentinel {{hideAndFadeIn}}" ref:sentinel></div>
<div class="compose-box-button-wrapper" > <div class="compose-box-button-wrapper {{hideAndFadeIn}}" >
<ComposeButton :length :overLimit :sticky on:click="onClickPostButton()" /> <ComposeButton :length :overLimit :sticky on:click="onClickPostButton()" />
</div> </div>
<div class="compose-box-border-bottom"></div> <div class="compose-box-border-bottom {{hideAndFadeIn}}"></div>
<style> <style>
.compose-box { .compose-box {
border-radius: 4px; border-radius: 4px;
@ -40,6 +40,10 @@
max-width: calc(100vw - 60px); max-width: calc(100vw - 60px);
} }
.compose-box-fade-in {
transition: opacity 0.2s linear; /* main page reveal */
}
.compose-box-border-bottom { .compose-box-border-bottom {
height: 1px; height: 1px;
background: var(--main-border); background: var(--main-border);
@ -91,6 +95,7 @@
import { slide } from 'svelte-transitions' import { slide } from 'svelte-transitions'
import { postStatus, insertHandleForReply } from '../../_actions/compose' import { postStatus, insertHandleForReply } from '../../_actions/compose'
import { importDialogs } from '../../_utils/asyncModules' import { importDialogs } from '../../_utils/asyncModules'
import { classname } from '../../_utils/classname'
export default { export default {
oncreate() { oncreate() {
@ -133,6 +138,19 @@
}, },
store: () => store, store: () => store,
computed: { computed: {
className: (overLimit, realm) => {
return classname(
'compose-box',
overLimit && 'over-char-limit',
realm === 'dialog' && 'dialog-size'
)
},
hideAndFadeIn: (hidden) => {
return classname(
'compose-box-fade-in',
hidden && 'hidden'
)
},
composeData: ($currentComposeData, realm) => $currentComposeData[realm] || {}, composeData: ($currentComposeData, realm) => $currentComposeData[realm] || {},
text: (composeData) => composeData.text || '', text: (composeData) => composeData.text || '',
media: (composeData) => composeData.media || [], media: (composeData) => composeData.media || [],

View File

@ -1,4 +1,4 @@
<div class="pseudo-virtual-list {{shown ? '' : 'hidden'}}" on:initializedVisibleItems ref:node> <div class="pseudo-virtual-list" on:initialized ref:node>
{{#if wrappedItems}} {{#if wrappedItems}}
{{#each wrappedItems as wrappedItem, i @item}} {{#each wrappedItems as wrappedItem, i @item}}
<PseudoVirtualListLazyItem <PseudoVirtualListLazyItem
@ -18,7 +18,6 @@
<style> <style>
.pseudo-virtual-list { .pseudo-virtual-list {
position: relative; position: relative;
transition: opacity 0.25s linear;
} }
</style> </style>
<script> <script>
@ -51,8 +50,8 @@
console.log('allItemsHaveHeight', allItemsHaveHeight) console.log('allItemsHaveHeight', allItemsHaveHeight)
if (allItemsHaveHeight && !this.get('initialized')) { if (allItemsHaveHeight && !this.get('initialized')) {
this.set({initialized: true}) this.set({initialized: true})
console.log('initializedVisibleItems') console.log('initialized PseudoVirtualList')
this.fire('initializedVisibleItems') this.fire('initialized')
} }
}) })
stop('PseudoVirtualList oncreate()') stop('PseudoVirtualList oncreate()')

View File

@ -4,17 +4,13 @@
on:focusWithCapture="saveFocus(event)" on:focusWithCapture="saveFocus(event)"
on:blurWithCapture="clearFocus(event)" on:blurWithCapture="clearFocus(event)"
> >
{{#if !$initialized}}
<LoadingPage />
{{/if}}
{{#if virtual}} {{#if virtual}}
<VirtualList component="{{VirtualListComponent}}" <VirtualList component="{{VirtualListComponent}}"
realm="{{$currentInstance + '/' + timeline}}" realm="{{$currentInstance + '/' + timeline}}"
containerQuery=".container" containerQuery=".container"
:makeProps :makeProps
items="{{$timelineItemIds}}" items="{{$timelineItemIds}}"
shown="{{$initialized}}" showFooter="{{$timelineInitialized && $runningUpdate}}"
showFooter="{{$initialized && $runningUpdate}}"
footerComponent="{{LoadingFooter}}" footerComponent="{{LoadingFooter}}"
showHeader="{{$showHeader}}" showHeader="{{$showHeader}}"
headerComponent="{{MoreHeaderVirtualWrapper}}" headerComponent="{{MoreHeaderVirtualWrapper}}"
@ -22,7 +18,8 @@
on:scrollToBottom="onScrollToBottom()" on:scrollToBottom="onScrollToBottom()"
on:scrollToTop="onScrollToTop()" on:scrollToTop="onScrollToTop()"
on:scrollTopChanged="onScrollTopChanged(event)" on:scrollTopChanged="onScrollTopChanged(event)"
on:initializedVisibleItems="initialize()" on:initialized="initialize()"
on:noNeedToScroll="onNoNeedToScroll()"
/> />
{{else}} {{else}}
{{#await importPseudoVirtualList}} {{#await importPseudoVirtualList}}
@ -35,20 +32,14 @@
containerQuery=".container" containerQuery=".container"
:makeProps :makeProps
items="{{$timelineItemIds}}" items="{{$timelineItemIds}}"
shown="{{$initialized}}"
scrollToItem="{{scrollToItem}}" scrollToItem="{{scrollToItem}}"
on:initializedVisibleItems="initialize()" on:initialized="initialize()"
/> />
{{catch error}} {{catch error}}
<div>Component failed to load. Try refreshing! {{error}}</div> <div>Component failed to load. Try refreshing! {{error}}</div>
{{/await}} {{/await}}
{{/if}} {{/if}}
</div> </div>
<style>
.timeline {
position: relative;
}
</style>
<script> <script>
import { store } from '../../_store/store' import { store } from '../../_store/store'
import StatusVirtualListItem from './StatusVirtualListItem.html' import StatusVirtualListItem from './StatusVirtualListItem.html'
@ -60,19 +51,18 @@
import { timelines } from '../../_static/timelines' import { timelines } from '../../_static/timelines'
import { database } from '../../_database/database' import { database } from '../../_database/database'
import { import {
initializeTimeline,
fetchTimelineItemsOnScrollToBottom, fetchTimelineItemsOnScrollToBottom,
setupTimeline, setupTimeline,
showMoreItemsForTimeline, showMoreItemsForTimeline,
showMoreItemsForThread, showMoreItemsForThread,
showMoreItemsForCurrentTimeline showMoreItemsForCurrentTimeline
} from '../../_actions/timeline' } from '../../_actions/timeline'
import LoadingPage from '../LoadingPage.html'
import { focusWithCapture, blurWithCapture } from '../../_utils/events' import { focusWithCapture, blurWithCapture } from '../../_utils/events'
import { scheduleIdleTask } from '../../_utils/scheduleIdleTask' import { scheduleIdleTask } from '../../_utils/scheduleIdleTask'
import { mark, stop } from '../../_utils/marks' import { mark, stop } from '../../_utils/marks'
import { importPseudoVirtualList } from '../../_utils/asyncModules' import { importPseudoVirtualList } from '../../_utils/asyncModules'
import isEqual from 'lodash/isEqual' import isEqual from 'lodash/isEqual'
import { doubleRAF } from '../../_utils/doubleRAF'
export default { export default {
oncreate() { oncreate() {
@ -154,8 +144,7 @@
}, },
store: () => store, store: () => store,
components: { components: {
VirtualList, VirtualList
LoadingPage
}, },
events: { events: {
focusWithCapture, focusWithCapture,
@ -167,14 +156,18 @@
return return
} }
this.set({initializeStarted: true}) this.set({initializeStarted: true})
console.log('timeline initialize()') mark('initializeTimeline')
initializeTimeline() doubleRAF(() => {
console.log('timeline initialized')
this.store.set({timelineInitialized: true})
stop('initializeTimeline')
})
}, },
onScrollTopChanged(scrollTop) { onScrollTopChanged(scrollTop) {
this.set({scrollTop: scrollTop}) this.set({scrollTop: scrollTop})
}, },
onScrollToBottom() { onScrollToBottom() {
if (!this.store.get('initialized') || if (!this.store.get('timelineInitialized') ||
this.store.get('runningUpdate') || this.store.get('runningUpdate') ||
this.get('timelineType') === 'status') { // for status contexts, we've already fetched the whole thread this.get('timelineType') === 'status') { // for status contexts, we've already fetched the whole thread
return return
@ -289,6 +282,13 @@
}) })
}) })
}, },
onNoNeedToScroll() {
// If the timeline doesn't need to scroll, then we can safely "preinitialize,"
// i.e. render anything above the fold of the timeline. This avoids the affect
// where the scrollable content appears to jump around if we need to scroll it.
console.log('timeline preinitialized')
this.store.set({timelinePreinitialized: true})
}
} }
} }
</script> </script>

View File

@ -1,5 +1,5 @@
<VirtualListContainer :realm :containerQuery > <VirtualListContainer :realm :containerQuery on:initialized on:noNeedToScroll >
<div class="virtual-list {{shown ? '' : 'hidden'}}" <div class="virtual-list"
style="height: {{$height}}px;" style="height: {{$height}}px;"
ref:node > ref:node >
<VirtualListHeader component="{{headerComponent}}" virtualProps="{{headerProps}}" shown="{{$showHeader}}"/> <VirtualListHeader component="{{headerComponent}}" virtualProps="{{headerProps}}" shown="{{$showHeader}}"/>
@ -21,7 +21,6 @@
<style> <style>
.virtual-list { .virtual-list {
position: relative; position: relative;
transition: opacity 0.25s linear;
} }
</style> </style>
<script> <script>

View File

@ -6,6 +6,7 @@
import { mark, stop } from '../../_utils/marks' import { mark, stop } from '../../_utils/marks'
import { scheduleIdleTask } from '../../_utils/scheduleIdleTask' import { scheduleIdleTask } from '../../_utils/scheduleIdleTask'
import { isMobile } from '../../_utils/isMobile' import { isMobile } from '../../_utils/isMobile'
import { doubleRAF } from '../../_utils/doubleRAF'
const SCROLL_EVENT_DELAY = 300 const SCROLL_EVENT_DELAY = 300
@ -26,9 +27,20 @@
console.log('forcing scroll top to ', scrollTop) console.log('forcing scroll top to ', scrollTop)
node.scrollTop = scrollTop node.scrollTop = scrollTop
stop('set scrollTop') stop('set scrollTop')
doubleRAF(() => {
console.log('initialized VirtualList')
this.fire('initialized')
})
} }
}) })
} else { } else {
this.fire('noNeedToScroll')
this.observe('allVisibleItemsHaveHeight', allVisibleItemsHaveHeight => {
if (allVisibleItemsHaveHeight) {
console.log('initialized VirtualList')
this.fire('initialized')
}
})
this.store.setForRealm({ this.store.setForRealm({
scrollHeight: node.scrollHeight, scrollHeight: node.scrollHeight,
offsetHeight: node.offsetHeight offsetHeight: node.offsetHeight

View File

@ -1,24 +1,25 @@
{{#if $isUserLoggedIn}} {{#if $isUserLoggedIn}}
<DynamicPageBanner title="" /> <TimelinePage timeline="account/{{params.accountId}}">
<DynamicPageBanner title="" />
{{#if $currentAccountProfile && $currentVerifyCredentials}} {{#if $currentAccountProfile && $currentVerifyCredentials}}
<AccountProfile account="{{$currentAccountProfile}}" <AccountProfile account="{{$currentAccountProfile}}"
relationship="{{$currentAccountRelationship}}" relationship="{{$currentAccountRelationship}}"
verifyCredentials="{{$currentVerifyCredentials}}" verifyCredentials="{{$currentVerifyCredentials}}"
/> />
{{/if}} {{/if}}
<PinnedStatuses accountId="{{params.accountId}}" /> <PinnedStatuses accountId="{{params.accountId}}" />
<LazyTimeline timeline='account/{{params.accountId}}' /> </TimelinePage>
{{else}} {{else}}
<HiddenFromSSR> <HiddenFromSSR>
<FreeTextLayout> <FreeTextLayout>
<h1>Profile</h1> <h1>Profile</h1>
<p>A user timeline will appear here when logged in.</p> <p>A user timeline will appear here when logged in.</p>
</FreeTextLayout> </FreeTextLayout>
</HiddenFromSSR> </HiddenFromSSR>
{{/if}} {{/if}}
<script> <script>
import LazyTimeline from '../../_components/timeline/LazyTimeline.html' import TimelinePage from '../../_components/TimelinePage.html'
import FreeTextLayout from '../../_components/FreeTextLayout.html' import FreeTextLayout from '../../_components/FreeTextLayout.html'
import { store } from '../../_store/store.js' import { store } from '../../_store/store.js'
import HiddenFromSSR from '../../_components/HiddenFromSSR' import HiddenFromSSR from '../../_components/HiddenFromSSR'
@ -42,7 +43,7 @@
} }
}, },
components: { components: {
LazyTimeline, TimelinePage,
FreeTextLayout, FreeTextLayout,
HiddenFromSSR, HiddenFromSSR,
DynamicPageBanner, DynamicPageBanner,

View File

@ -1,19 +1,20 @@
{{#if $isUserLoggedIn}} {{#if $isUserLoggedIn}}
{{#if $pinnedPage !== '/favorites'}} <TimelinePage timeline="favorites">
{{#if $pinnedPage !== '/favorites'}}
<DynamicPageBanner title="Favorites" icon="#fa-star"/> <DynamicPageBanner title="Favorites" icon="#fa-star"/>
{{/if}} {{/if}}
<LazyTimeline timeline='favorites' /> </TimelinePage>
{{else}} {{else}}
<HiddenFromSSR> <HiddenFromSSR>
<FreeTextLayout> <FreeTextLayout>
<h1>Favorites</h1> <h1>Favorites</h1>
<p>Your favorites will appear here when logged in.</p> <p>Your favorites will appear here when logged in.</p>
</FreeTextLayout> </FreeTextLayout>
</HiddenFromSSR> </HiddenFromSSR>
{{/if}} {{/if}}
<script> <script>
import LazyTimeline from '.././_components/timeline/LazyTimeline.html' import TimelinePage from '.././_components/TimelinePage.html'
import FreeTextLayout from '.././_components/FreeTextLayout.html' import FreeTextLayout from '.././_components/FreeTextLayout.html'
import { store } from '.././_store/store.js' import { store } from '.././_store/store.js'
import HiddenFromSSR from '.././_components/HiddenFromSSR' import HiddenFromSSR from '.././_components/HiddenFromSSR'
@ -22,7 +23,7 @@
export default { export default {
store: () => store, store: () => store,
components: { components: {
LazyTimeline, TimelinePage,
FreeTextLayout, FreeTextLayout,
HiddenFromSSR, HiddenFromSSR,
DynamicPageBanner DynamicPageBanner

View File

@ -1,19 +1,20 @@
{{#if $isUserLoggedIn}} {{#if $isUserLoggedIn}}
{{#if $pinnedPage !== '/federated'}} <TimelinePage timeline="federated">
{{#if $pinnedPage !== '/federated'}}
<DynamicPageBanner title="Federated Timeline" icon="#fa-globe"/> <DynamicPageBanner title="Federated Timeline" icon="#fa-globe"/>
{{/if}} {{/if}}
<LazyTimeline timeline='federated' /> </TimelinePage>
{{else}} {{else}}
<HiddenFromSSR> <HiddenFromSSR>
<FreeTextLayout> <FreeTextLayout>
<h1>Federated</h1> <h1>Federated</h1>
<p>Your federated timeline will appear here when logged in.</p> <p>Your federated timeline will appear here when logged in.</p>
</FreeTextLayout> </FreeTextLayout>
</HiddenFromSSR> </HiddenFromSSR>
{{/if}} {{/if}}
<script> <script>
import LazyTimeline from '.././_components/timeline/LazyTimeline.html' import TimelinePage from '.././_components/TimelinePage.html'
import FreeTextLayout from '.././_components/FreeTextLayout.html' import FreeTextLayout from '.././_components/FreeTextLayout.html'
import { store } from '.././_store/store.js' import { store } from '.././_store/store.js'
import HiddenFromSSR from '.././_components/HiddenFromSSR' import HiddenFromSSR from '.././_components/HiddenFromSSR'
@ -22,7 +23,7 @@
export default { export default {
store: () => store, store: () => store,
components: { components: {
LazyTimeline, TimelinePage,
FreeTextLayout, FreeTextLayout,
HiddenFromSSR, HiddenFromSSR,
DynamicPageBanner DynamicPageBanner

View File

@ -1,25 +1,18 @@
{{#if $isUserLoggedIn}} {{#if $isUserLoggedIn}}
{{#if $currentVerifyCredentials}} <TimelineHomePage/>
<ComposeBox realm="home" />
{{/if}}
<LazyTimeline timeline='home' />
{{else}} {{else}}
<NotLoggedInHome/> <NotLoggedInHome/>
{{/if}} {{/if}}
<style>
</style>
<script> <script>
import NotLoggedInHome from '.././_components/NotLoggedInHome.html' import NotLoggedInHome from '.././_components/NotLoggedInHome.html'
import LazyTimeline from '.././_components/timeline/LazyTimeline.html'
import ComposeBox from '.././_components/compose/ComposeBox.html'
import { store } from '.././_store/store.js' import { store } from '.././_store/store.js'
import TimelineHomePage from '../_components/TimelineHomePage.html'
export default { export default {
store: () => store, store: () => store,
components: { components: {
LazyTimeline,
NotLoggedInHome, NotLoggedInHome,
ComposeBox TimelineHomePage
} }
} }
</script> </script>

View File

@ -1,19 +1,20 @@
{{#if $isUserLoggedIn}} {{#if $isUserLoggedIn}}
{{#if $pinnedPage !== `/lists/${params.listId}`}} <TimelinePage timeline="list/{{params.listId}}">
{{#if $pinnedPage !== `/lists/${params.listId}`}}
<DynamicPageBanner title="{{listTitle}}" icon="#fa-bars"/> <DynamicPageBanner title="{{listTitle}}" icon="#fa-bars"/>
{{/if}} {{/if}}
<LazyTimeline timeline='list/{{params.listId}}' /> </TimelinePage>
{{else}} {{else}}
<HiddenFromSSR> <HiddenFromSSR>
<FreeTextLayout> <FreeTextLayout>
<h1>List</h1> <h1>List</h1>
<p>A list will appear here when logged in.</p> <p>A list will appear here when logged in.</p>
</FreeTextLayout> </FreeTextLayout>
</HiddenFromSSR> </HiddenFromSSR>
{{/if}} {{/if}}
<script> <script>
import LazyTimeline from '../../_components/timeline/LazyTimeline.html' import TimelinePage from '../../_components/TimelinePage.html'
import FreeTextLayout from '../../_components/FreeTextLayout.html' import FreeTextLayout from '../../_components/FreeTextLayout.html'
import { store } from '../../_store/store.js' import { store } from '../../_store/store.js'
import HiddenFromSSR from '../../_components/HiddenFromSSR' import HiddenFromSSR from '../../_components/HiddenFromSSR'
@ -26,7 +27,7 @@
}, },
store: () => store, store: () => store,
components: { components: {
LazyTimeline, TimelinePage,
FreeTextLayout, FreeTextLayout,
HiddenFromSSR, HiddenFromSSR,
DynamicPageBanner DynamicPageBanner

View File

@ -1,19 +1,20 @@
{{#if $isUserLoggedIn}} {{#if $isUserLoggedIn}}
{{#if $pinnedPage !== '/local'}} <TimelinePage timeline="local">
{{#if $pinnedPage !== '/local'}}
<DynamicPageBanner title="Local Timeline" icon="#fa-users"/> <DynamicPageBanner title="Local Timeline" icon="#fa-users"/>
{{/if}} {{/if}}
<LazyTimeline timeline='local' /> </TimelinePage>
{{else}} {{else}}
<HiddenFromSSR> <HiddenFromSSR>
<FreeTextLayout> <FreeTextLayout>
<h1>Local</h1> <h1>Local</h1>
<p>Your local timeline will appear here when logged in.</p> <p>Your local timeline will appear here when logged in.</p>
</FreeTextLayout> </FreeTextLayout>
</HiddenFromSSR> </HiddenFromSSR>
{{/if}} {{/if}}
<script> <script>
import LazyTimeline from '.././_components/timeline/LazyTimeline.html' import TimelinePage from '.././_components/TimelinePage.html'
import FreeTextLayout from '.././_components/FreeTextLayout.html' import FreeTextLayout from '.././_components/FreeTextLayout.html'
import { store } from '.././_store/store.js' import { store } from '.././_store/store.js'
import HiddenFromSSR from '.././_components/HiddenFromSSR' import HiddenFromSSR from '.././_components/HiddenFromSSR'
@ -22,7 +23,7 @@
export default { export default {
store: () => store, store: () => store,
components: { components: {
LazyTimeline, TimelinePage,
FreeTextLayout, FreeTextLayout,
HiddenFromSSR, HiddenFromSSR,
DynamicPageBanner DynamicPageBanner

View File

@ -1,5 +1,5 @@
{{#if $isUserLoggedIn}} {{#if $isUserLoggedIn}}
<LazyTimeline timeline='notifications' /> <TimelinePage timeline="notifications" />
{{else}} {{else}}
<HiddenFromSSR> <HiddenFromSSR>
<FreeTextLayout> <FreeTextLayout>
@ -10,17 +10,17 @@
</HiddenFromSSR> </HiddenFromSSR>
{{/if}} {{/if}}
<script> <script>
import LazyTimeline from '.././_components/timeline/LazyTimeline.html'
import FreeTextLayout from '.././_components/FreeTextLayout.html' import FreeTextLayout from '.././_components/FreeTextLayout.html'
import { store } from '.././_store/store.js' import { store } from '.././_store/store.js'
import HiddenFromSSR from '.././_components/HiddenFromSSR' import HiddenFromSSR from '.././_components/HiddenFromSSR'
import TimelinePage from '../_components/TimelinePage.html'
export default { export default {
store: () => store, store: () => store,
components: { components: {
LazyTimeline,
FreeTextLayout, FreeTextLayout,
HiddenFromSSR HiddenFromSSR,
TimelinePage
} }
}; };
</script> </script>

View File

@ -1,29 +1,30 @@
{{#if $isUserLoggedIn}} {{#if $isUserLoggedIn}}
<DynamicPageBanner title=""/> <TimelinePage timeline="status/{{params.statusId}}">
<LazyTimeline timeline='status/{{params.statusId}}' /> <DynamicPageBanner title=""/>
</TimelinePage>
{{else}} {{else}}
<HiddenFromSSR> <HiddenFromSSR>
<FreeTextLayout> <FreeTextLayout>
<h1>Status</h1> <h1>Status</h1>
<p>A status thread will appear here when logged in.</p> <p>A status thread will appear here when logged in.</p>
</FreeTextLayout> </FreeTextLayout>
</HiddenFromSSR> </HiddenFromSSR>
{{/if}} {{/if}}
<script> <script>
import LazyTimeline from '../../../_components/timeline/LazyTimeline.html'
import FreeTextLayout from '../../../_components/FreeTextLayout.html' import FreeTextLayout from '../../../_components/FreeTextLayout.html'
import { store } from '../../../_store/store.js' import { store } from '../../../_store/store.js'
import HiddenFromSSR from '../../../_components/HiddenFromSSR' import HiddenFromSSR from '../../../_components/HiddenFromSSR'
import DynamicPageBanner from '../../../_components/DynamicPageBanner.html' import DynamicPageBanner from '../../../_components/DynamicPageBanner.html'
import TimelinePage from '../../../_components/TimelinePage.html'
export default { export default {
store: () => store, store: () => store,
components: { components: {
LazyTimeline,
FreeTextLayout, FreeTextLayout,
HiddenFromSSR, HiddenFromSSR,
DynamicPageBanner DynamicPageBanner,
TimelinePage
} }
} }
</script> </script>

View File

@ -1,17 +1,18 @@
{{#if $isUserLoggedIn}} {{#if $isUserLoggedIn}}
<DynamicPageBanner title="{{'#' + params.tagName}}"/> <TimelinePage timeline="tag/{{params.tagName}}">
<LazyTimeline timeline='tag/{{params.tagName}}' /> <DynamicPageBanner title="{{'#' + params.tagName}}"/>
</TimelinePage>
{{else}} {{else}}
<HiddenFromSSR> <HiddenFromSSR>
<FreeTextLayout> <FreeTextLayout>
<h1>#{{params.tagName}}</h1> <h1>#{{params.tagName}}</h1>
<p>A hashtag timeline will appear here when logged in.</p> <p>A hashtag timeline will appear here when logged in.</p>
</FreeTextLayout> </FreeTextLayout>
</HiddenFromSSR> </HiddenFromSSR>
{{/if}} {{/if}}
<script> <script>
import LazyTimeline from '../../_components/timeline/LazyTimeline.html' import TimelinePage from '../../_components/TimelinePage.html'
import FreeTextLayout from '../../_components/FreeTextLayout.html' import FreeTextLayout from '../../_components/FreeTextLayout.html'
import { store } from '../../_store/store.js' import { store } from '../../_store/store.js'
import HiddenFromSSR from '../../_components/HiddenFromSSR' import HiddenFromSSR from '../../_components/HiddenFromSSR'
@ -20,7 +21,7 @@
export default { export default {
store: () => store, store: () => store,
components: { components: {
LazyTimeline, TimelinePage,
FreeTextLayout, FreeTextLayout,
HiddenFromSSR, HiddenFromSSR,
DynamicPageBanner DynamicPageBanner

View File

@ -11,7 +11,6 @@ function computeForTimeline (store, key, defaultValue) {
export function timelineComputations (store) { export function timelineComputations (store) {
computeForTimeline(store, 'timelineItemIds', null) computeForTimeline(store, 'timelineItemIds', null)
computeForTimeline(store, 'runningUpdate', false) computeForTimeline(store, 'runningUpdate', false)
computeForTimeline(store, 'initialized', false)
computeForTimeline(store, 'lastFocusedElementSelector', null) computeForTimeline(store, 'lastFocusedElementSelector', null)
computeForTimeline(store, 'ignoreBlurEvents', false) computeForTimeline(store, 'ignoreBlurEvents', false)
computeForTimeline(store, 'itemIdsToAdd', null) computeForTimeline(store, 'itemIdsToAdd', null)

View File

@ -0,0 +1,3 @@
export function doubleRAF (fn) {
requestAnimationFrame(() => requestAnimationFrame(fn))
}