preload content in CW (#110)

* preload content in CW

Fixes #63

* fix test
This commit is contained in:
Nolan Lawson 2018-04-14 10:47:53 -07:00 committed by GitHub
parent 707e89e899
commit ff8e92df6c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 30 additions and 9 deletions

View File

@ -23,9 +23,9 @@
:originalStatus :uuid :spoilerShown
on:recalculateHeight />
{{/if}}
{{#if !spoilerText || spoilerShown}}
{{#if showContent || contentPreloaded}}
<StatusContent :isStatusInOwnThread :isStatusInNotification
:originalStatus :uuid />
:originalStatus :uuid shown="{{showContent}}"/>
{{/if}}
{{#if originalStatus.media_attachments && originalStatus.media_attachments.length}}
<StatusMediaAttachments :originalStatus :uuid
@ -114,6 +114,7 @@
import { registerClickDelegate, unregisterClickDelegate } from '../../_utils/delegate'
import { classname } from '../../_utils/classname'
import { checkDomAncestors } from '../../_utils/checkDomAncestors'
import { scheduleIdleTask } from '../../_utils/scheduleIdleTask'
const INPUT_TAGS = new Set(['a', 'button', 'input', 'textarea'])
const isUserInputElement = node => INPUT_TAGS.has(node.localName)
@ -127,6 +128,13 @@
// the whole <article> is clickable in this case
registerClickDelegate(delegateKey, (e) => this.onClickOrKeydown(e))
}
if (!this.get('showContent')) {
scheduleIdleTask(() => {
// Perf optimization: lazily load the StatusContent when the user is idle so that
// it's fast when they click the "show more" button
this.set({contentPreloaded: true})
})
}
},
ondestroy() {
let delegateKey = this.get('delegateKey')
@ -214,7 +222,8 @@
timelineType !== 'search' && 'status-in-timeline',
isStatusInOwnThread && 'status-in-own-thread'
)
}
},
showContent: (spoilerText, spoilerShown) => !spoilerText || spoilerShown
}
}
</script>

View File

@ -1,7 +1,4 @@
<div
class="status-content {{isStatusInOwnThread ? 'status-in-own-thread' : ''}} {{isStatusInNotification ? 'status-in-notification' : ''}}"
ref:node
>
<div class="{{computedClass}}" ref:node>
{{{massagedContent}}}
</div>
<style>
@ -12,6 +9,7 @@
overflow: hidden;
white-space: pre-wrap;
font-size: 0.9em;
display: none;
}
.status-content.status-in-own-thread {
@ -19,6 +17,10 @@
margin: 20px 10px 20px 5px;
}
.status-content.shown {
display: block;
}
:global(.status-content .status-emoji) {
width: 20px;
height: 20px;
@ -59,6 +61,7 @@
import { replaceAll } from '../../_utils/strings'
import { mark, stop } from '../../_utils/marks'
import { store } from '../../_store/store'
import { classname } from '../../_utils/classname'
export default {
oncreate() {
@ -66,6 +69,14 @@
},
store: () => store,
computed: {
computedClass: (isStatusInOwnThread, isStatusInNotification, shown) => {
return classname(
'status-content',
isStatusInOwnThread && 'status-in-own-thread',
isStatusInNotification && 'status-in-notification',
shown && 'shown'
)
},
massagedContent: (originalStatus, $autoplayGifs) => {
let content = originalStatus.content
// emojify

View File

@ -17,7 +17,7 @@ test('content warnings are posted', async t => {
.click(getNthShowOrHideButton(0))
.expect(getNthStatus(0).find('.status-content').innerText).contains('hello this is a toot')
.click(getNthShowOrHideButton(0))
.expect(getNthStatus(0).find('.status-content').exists).notOk()
.expect(getNthStatus(0).innerText).notContains('hello this is a toot')
})
test('content warnings are not posted if removed', async t => {
@ -28,6 +28,7 @@ test('content warnings are not posted if removed', async t => {
.click(contentWarningButton)
.expect(composeContentWarning.exists).notOk()
.click(composeButton)
.expect(getNthStatus(0).find('.status-spoiler').exists).notOk({timeout: 30000})
.expect(getNthStatus(0).innerText).contains('hi this is another toot', {timeout: 30000})
.expect(getNthStatus(0).innerText).notContains('content warning!')
.expect(getNthStatus(0).find('.status-content').innerText).contains('hi this is another toot')
})