use standard to lint HTML too (#186)
This commit is contained in:
parent
ef80919269
commit
bfc3c46462
|
@ -32,6 +32,7 @@ Lint:
|
|||
Automatically fix most linting issues:
|
||||
|
||||
npx standard --fix
|
||||
npx standard --fix --plugin html 'routes/**/*.html'
|
||||
|
||||
## Testing
|
||||
|
||||
|
|
9
package-lock.json
generated
9
package-lock.json
generated
|
@ -3084,6 +3084,15 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"eslint-plugin-html": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-html/-/eslint-plugin-html-4.0.3.tgz",
|
||||
"integrity": "sha512-ArFnlfQxwYSz/CP0zvk8Cy3MUhcDpT3o6jgO8eKD/b8ezcLVBrgkYzmMv+7S/ya+Yl9pN+Cz2tsgYp/zElkQzA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"htmlparser2": "3.9.2"
|
||||
}
|
||||
},
|
||||
"eslint-plugin-import": {
|
||||
"version": "2.9.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.9.0.tgz",
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"description": "Alternative web client for Mastodon",
|
||||
"version": "0.2.2",
|
||||
"scripts": {
|
||||
"lint": "standard",
|
||||
"lint": "standard && standard --plugin html 'routes/**/*.html'",
|
||||
"dev": "run-s build-svg build-inline-script serve-dev",
|
||||
"serve-dev": "run-p --race build-sass-watch serve",
|
||||
"serve": "node server.js",
|
||||
|
@ -83,6 +83,7 @@
|
|||
"yargs": "11.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint-plugin-html": "4.0.3",
|
||||
"now": "11.1.7",
|
||||
"standard": "11.0.1",
|
||||
"testcafe": "0.19.1"
|
||||
|
@ -117,7 +118,8 @@
|
|||
"atob",
|
||||
"btoa",
|
||||
"Blob",
|
||||
"Element"
|
||||
"Element",
|
||||
"Image"
|
||||
],
|
||||
"ignore": [
|
||||
"dist",
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
import { toast } from '../_utils/toast'
|
||||
|
||||
export default {
|
||||
async oncreate() {
|
||||
async oncreate () {
|
||||
let { accountsFetcher } = this.get()
|
||||
try {
|
||||
// TODO: paginate
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
<script>
|
||||
export default {
|
||||
methods: {
|
||||
onGoBack(e) {
|
||||
onGoBack (e) {
|
||||
e.preventDefault()
|
||||
window.history.back()
|
||||
}
|
||||
|
|
|
@ -105,7 +105,7 @@
|
|||
import { store } from '../_store/store'
|
||||
|
||||
export default {
|
||||
oncreate() {
|
||||
oncreate () {
|
||||
this.observe('animation', animation => {
|
||||
let reduceMotion = this.store.get()
|
||||
if (!animation || reduceMotion) {
|
||||
|
|
|
@ -9,19 +9,19 @@
|
|||
{{/if}}
|
||||
</div>
|
||||
<script>
|
||||
import Nav from './Nav.html';
|
||||
import Nav from './Nav.html'
|
||||
import { store } from '../_store/store'
|
||||
import InformationalFooter from './InformationalFooter.html'
|
||||
|
||||
// Only focus the `.container` div on first load so it does not intefere
|
||||
// Only focus the `.container` div on first load so it does not intefere
|
||||
// with other desired behaviours (e.g. you click a toot, you navigate from
|
||||
// a timeline view to a thread view, you press the back button, and now
|
||||
// you're still focused on the toot).
|
||||
let firstTime = true
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Nav,
|
||||
export default {
|
||||
components: {
|
||||
Nav,
|
||||
InformationalFooter
|
||||
},
|
||||
oncreate () {
|
||||
|
@ -31,5 +31,5 @@
|
|||
}
|
||||
},
|
||||
store: () => store
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -21,11 +21,10 @@
|
|||
}
|
||||
</style>
|
||||
<script>
|
||||
|
||||
import { mark, stop } from '../_utils/marks'
|
||||
|
||||
export default {
|
||||
oncreate() {
|
||||
oncreate () {
|
||||
mark('LazyImage oncreate()')
|
||||
let img = new Image()
|
||||
let { src } = this.get()
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
let firstTime = true
|
||||
|
||||
export default {
|
||||
oncreate() {
|
||||
oncreate () {
|
||||
firstTime = false
|
||||
requestAnimationFrame(() => {
|
||||
requestAnimationFrame(() => {
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
const SPINNER_DELAY = 700
|
||||
|
||||
export default {
|
||||
oncreate() {
|
||||
oncreate () {
|
||||
setTimeout(() => {
|
||||
this.set({shown: true})
|
||||
}, SPINNER_DELAY)
|
||||
|
|
|
@ -135,7 +135,7 @@
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
onClick(e) {
|
||||
onClick (e) {
|
||||
let { selected } = this.get()
|
||||
if (!selected) {
|
||||
return
|
||||
|
@ -146,5 +146,4 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
|
@ -43,7 +43,7 @@
|
|||
|
||||
export default {
|
||||
methods: {
|
||||
onMouseOver(mouseOver) {
|
||||
onMouseOver (mouseOver) {
|
||||
this.set({playing: mouseOver})
|
||||
}
|
||||
},
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
import { imgLoadError, mouseover } from '../_utils/events'
|
||||
export default {
|
||||
methods: {
|
||||
onMouseOver(mouseOver) {
|
||||
onMouseOver (mouseOver) {
|
||||
let { src, staticSrc } = this.get()
|
||||
this.refs.node.src = mouseOver ? src : staticSrc
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
},
|
||||
computed: {
|
||||
hidePage: ($timelineInitialized, $timelinePreinitialized) => !$timelineInitialized && !$timelinePreinitialized,
|
||||
hideTimeline: ($timelineInitialized) => !$timelineInitialized,
|
||||
hideTimeline: ($timelineInitialized) => !$timelineInitialized
|
||||
},
|
||||
store: () => store,
|
||||
components: {
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
},
|
||||
computed: {
|
||||
hidePage: ($timelineInitialized, $timelinePreinitialized) => !$timelineInitialized && !$timelinePreinitialized,
|
||||
hideTimeline: ($timelineInitialized) => !$timelineInitialized,
|
||||
hideTimeline: ($timelineInitialized) => !$timelineInitialized
|
||||
},
|
||||
store: () => store,
|
||||
components: {
|
||||
|
|
|
@ -67,10 +67,10 @@
|
|||
methods: {
|
||||
push,
|
||||
splice,
|
||||
say(text) {
|
||||
say (text) {
|
||||
this.push('messages', text)
|
||||
},
|
||||
onNewToast(text) {
|
||||
onNewToast (text) {
|
||||
this._queue = this._queue.then(() => {
|
||||
this.set({
|
||||
'text': text,
|
||||
|
|
|
@ -73,7 +73,7 @@
|
|||
IconButton
|
||||
},
|
||||
methods: {
|
||||
onPinClick(e) {
|
||||
onPinClick (e) {
|
||||
e.preventDefault()
|
||||
let { currentInstance, pinnedPages } = this.store.get()
|
||||
let { href } = this.get()
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
const EMOJI_SEARCH_REGEX = new RegExp(`(?:\\s|^)(:[^:]{${MIN_PREFIX_LENGTH},})$`)
|
||||
|
||||
export default {
|
||||
oncreate() {
|
||||
oncreate () {
|
||||
// perf improves for input responsiveness
|
||||
this.observe('composeSelectionStart', () => {
|
||||
scheduleIdleTask(() => {
|
||||
|
@ -94,7 +94,7 @@
|
|||
composeAutosuggestionSelected: 0,
|
||||
composeAutosuggestionSearchText: searchText,
|
||||
composeAutosuggestionSearchResults: results,
|
||||
composeAutosuggestionType: type,
|
||||
composeAutosuggestionType: type
|
||||
})
|
||||
})
|
||||
this.observe('shown', shown => {
|
||||
|
@ -103,7 +103,7 @@
|
|||
},
|
||||
methods: {
|
||||
once: once,
|
||||
onClick(item) {
|
||||
onClick (item) {
|
||||
this.fire('autosuggestItemSelected')
|
||||
let { realm } = this.get()
|
||||
let { composeSelectionStart, composeAutosuggestionSearchText } = this.store.get()
|
||||
|
@ -114,16 +114,15 @@
|
|||
} else {
|
||||
/* no await */ insertEmojiAtPosition(realm, item, startIndex, endIndex)
|
||||
}
|
||||
|
||||
},
|
||||
async searchAccounts(searchText) {
|
||||
async searchAccounts (searchText) {
|
||||
searchText = searchText.substring(1)
|
||||
let { currentInstance } = this.store.get()
|
||||
let results = await searchAccountsByUsernameInDatabase(
|
||||
currentInstance, searchText, DATABASE_SEARCH_RESULTS_LIMIT)
|
||||
return results.slice(0, SEARCH_RESULTS_LIMIT)
|
||||
},
|
||||
searchEmoji(searchText) {
|
||||
searchEmoji (searchText) {
|
||||
searchText = searchText.toLowerCase().substring(1)
|
||||
let { currentCustomEmoji } = this.store.get()
|
||||
let results = currentCustomEmoji.filter(emoji => emoji.shortcode.toLowerCase().startsWith(searchText))
|
||||
|
|
|
@ -117,7 +117,7 @@
|
|||
import { classname } from '../../_utils/classname'
|
||||
|
||||
export default {
|
||||
oncreate() {
|
||||
oncreate () {
|
||||
let { realm } = this.get()
|
||||
if (realm === 'home') {
|
||||
this.setupStickyObserver()
|
||||
|
@ -138,7 +138,7 @@
|
|||
setReplyVisibility(realm, replyVisibility)
|
||||
}
|
||||
},
|
||||
ondestroy() {
|
||||
ondestroy () {
|
||||
this.teardownStickyObserver()
|
||||
},
|
||||
components: {
|
||||
|
@ -188,7 +188,7 @@
|
|||
slide
|
||||
},
|
||||
methods: {
|
||||
async onClickPostButton() {
|
||||
async onClickPostButton () {
|
||||
let { sticky } = this.get()
|
||||
if (sticky) {
|
||||
// when the button is sticky, we're scrolled down the home timeline,
|
||||
|
@ -197,10 +197,10 @@
|
|||
dialogs.showComposeDialog()
|
||||
} else {
|
||||
// else we're actually posting a new toot
|
||||
this.doPostStatus();
|
||||
this.doPostStatus()
|
||||
}
|
||||
},
|
||||
doPostStatus() {
|
||||
doPostStatus () {
|
||||
let {
|
||||
text,
|
||||
media,
|
||||
|
@ -224,7 +224,7 @@
|
|||
sensitive, contentWarning, postPrivacyKey,
|
||||
mediaDescriptions, inReplyToUuid)
|
||||
},
|
||||
setupStickyObserver() {
|
||||
setupStickyObserver () {
|
||||
this.__stickyObserver = new IntersectionObserver(entries => {
|
||||
this.set({sticky: !entries[0].isIntersecting})
|
||||
})
|
||||
|
@ -243,7 +243,7 @@
|
|||
}
|
||||
}, {init: false})
|
||||
},
|
||||
teardownStickyObserver() {
|
||||
teardownStickyObserver () {
|
||||
if (this.__stickyObserver) {
|
||||
this.__stickyObserver.disconnect()
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
import { scheduleIdleTask } from '../../_utils/scheduleIdleTask'
|
||||
|
||||
export default {
|
||||
oncreate() {
|
||||
oncreate () {
|
||||
this.setupSyncFromStore()
|
||||
this.setupSyncToStore()
|
||||
},
|
||||
|
@ -28,12 +28,12 @@
|
|||
rawText: ''
|
||||
}),
|
||||
methods: {
|
||||
setupSyncFromStore() {
|
||||
setupSyncFromStore () {
|
||||
this.observe('contentWarning', contentWarning => {
|
||||
this.set({rawText: contentWarning})
|
||||
})
|
||||
},
|
||||
setupSyncToStore() {
|
||||
setupSyncToStore () {
|
||||
const saveText = debounce(() => scheduleIdleTask(() => this.store.save()), 1000)
|
||||
|
||||
this.observe('rawText', rawText => {
|
||||
|
|
|
@ -37,16 +37,16 @@
|
|||
import { clickSelectedAutosuggestionEmoji } from '../../_actions/emoji'
|
||||
|
||||
export default {
|
||||
oncreate() {
|
||||
oncreate () {
|
||||
this.setupSyncFromStore()
|
||||
this.setupSyncToStore()
|
||||
this.setupAutosize()
|
||||
},
|
||||
ondestroy() {
|
||||
ondestroy () {
|
||||
this.teardownAutosize()
|
||||
},
|
||||
methods: {
|
||||
setupSyncFromStore() {
|
||||
setupSyncFromStore () {
|
||||
let textarea = this.refs.textarea
|
||||
let firstTime = true
|
||||
this.observe('text', text => {
|
||||
|
@ -68,7 +68,7 @@
|
|||
}
|
||||
})
|
||||
},
|
||||
setupSyncToStore() {
|
||||
setupSyncToStore () {
|
||||
const saveStore = debounce(() => scheduleIdleTask(() => this.store.save()), 1000)
|
||||
|
||||
this.observe('rawText', rawText => {
|
||||
|
@ -79,7 +79,7 @@
|
|||
stop('observe rawText')
|
||||
}, {init: false})
|
||||
},
|
||||
setupAutosize() {
|
||||
setupAutosize () {
|
||||
let textarea = this.refs.textarea
|
||||
requestAnimationFrame(() => {
|
||||
mark('autosize()')
|
||||
|
@ -87,21 +87,21 @@
|
|||
stop('autosize()')
|
||||
})
|
||||
},
|
||||
teardownAutosize() {
|
||||
teardownAutosize () {
|
||||
mark('autosize.destroy()')
|
||||
autosize.destroy(this.refs.textarea)
|
||||
stop('autosize.destroy()')
|
||||
},
|
||||
onBlur() {
|
||||
onBlur () {
|
||||
this.store.set({composeFocused: false})
|
||||
},
|
||||
onFocus() {
|
||||
onFocus () {
|
||||
this.store.set({composeFocused: true})
|
||||
},
|
||||
onSelectionChange(selectionStart) {
|
||||
onSelectionChange (selectionStart) {
|
||||
this.store.set({composeSelectionStart: selectionStart})
|
||||
},
|
||||
onKeydown(e) {
|
||||
onKeydown (e) {
|
||||
let { keyCode } = e
|
||||
// ctrl or cmd (on macs) was pressed; ctrl-enter means post a toot
|
||||
const ctrlPressed = e.getModifierState('Control') || e.getModifierState('Meta')
|
||||
|
@ -109,7 +109,7 @@
|
|||
case 9: // tab
|
||||
this.clickSelectedAutosuggestion(e)
|
||||
break
|
||||
case 13: //enter
|
||||
case 13: // enter
|
||||
const autosuggestionClicked = this.clickSelectedAutosuggestion(e)
|
||||
if (!autosuggestionClicked && ctrlPressed) {
|
||||
this.fire('postAction')
|
||||
|
@ -127,7 +127,7 @@
|
|||
default:
|
||||
}
|
||||
},
|
||||
clickSelectedAutosuggestion(event) {
|
||||
clickSelectedAutosuggestion (event) {
|
||||
let {
|
||||
composeAutosuggestionShown,
|
||||
composeAutosuggestionType
|
||||
|
@ -145,7 +145,7 @@
|
|||
event.stopPropagation()
|
||||
return true
|
||||
},
|
||||
incrementAutosuggestSelected(increment, event) {
|
||||
incrementAutosuggestSelected (increment, event) {
|
||||
let {
|
||||
composeAutosuggestionShown,
|
||||
composeAutosuggestionSelected,
|
||||
|
@ -166,7 +166,7 @@
|
|||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
},
|
||||
clearAutosuggestions(event) {
|
||||
clearAutosuggestions (event) {
|
||||
let { composeAutosuggestionShown } = this.store.get()
|
||||
if (!composeAutosuggestionShown) {
|
||||
return
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
import { scheduleIdleTask } from '../../_utils/scheduleIdleTask'
|
||||
|
||||
export default {
|
||||
oncreate() {
|
||||
oncreate () {
|
||||
let { lengthAsFraction } = this.get()
|
||||
this.set({lengthAsFractionDeferred: lengthAsFraction})
|
||||
// perf improvement for keyboard input latency
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
import { scheduleIdleTask } from '../../_utils/scheduleIdleTask'
|
||||
|
||||
export default {
|
||||
oncreate() {
|
||||
oncreate () {
|
||||
let { lengthToDisplay } = this.get()
|
||||
this.set({lengthToDisplayDeferred: lengthToDisplay})
|
||||
// perf improvement for keyboard input latency
|
||||
|
|
|
@ -81,7 +81,7 @@
|
|||
import { scheduleIdleTask } from '../../_utils/scheduleIdleTask'
|
||||
|
||||
export default {
|
||||
oncreate() {
|
||||
oncreate () {
|
||||
this.setupSyncFromStore()
|
||||
this.setupSyncToStore()
|
||||
},
|
||||
|
@ -90,7 +90,7 @@
|
|||
}),
|
||||
store: () => store,
|
||||
methods: {
|
||||
setupSyncFromStore() {
|
||||
setupSyncFromStore () {
|
||||
this.observe('mediaDescriptions', mediaDescriptions => {
|
||||
mediaDescriptions = mediaDescriptions || []
|
||||
let { index, rawText } = this.get()
|
||||
|
@ -100,7 +100,7 @@
|
|||
}
|
||||
})
|
||||
},
|
||||
setupSyncToStore() {
|
||||
setupSyncToStore () {
|
||||
const saveStore = debounce(() => scheduleIdleTask(() => this.store.save()), 1000)
|
||||
|
||||
this.observe('rawText', rawText => {
|
||||
|
@ -118,7 +118,7 @@
|
|||
saveStore()
|
||||
}, {init: false})
|
||||
},
|
||||
onDeleteMedia() {
|
||||
onDeleteMedia () {
|
||||
let {
|
||||
realm,
|
||||
index
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
import ComposeAutosuggest from './ComposeAutosuggest.html'
|
||||
|
||||
export default {
|
||||
oncreate() {
|
||||
oncreate () {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
window.__fakeFileInput = (file) => {
|
||||
this.onFileChange({
|
||||
|
@ -69,25 +69,25 @@
|
|||
},
|
||||
store: () => store,
|
||||
methods: {
|
||||
async onEmojiClick() {
|
||||
async onEmojiClick () {
|
||||
let dialogs = await importDialogs()
|
||||
let { realm } = this.get()
|
||||
dialogs.showEmojiDialog(realm)
|
||||
},
|
||||
onMediaClick() {
|
||||
onMediaClick () {
|
||||
this.refs.input.click()
|
||||
},
|
||||
onFileChange(e) {
|
||||
onFileChange (e) {
|
||||
let file = e.target.files[0]
|
||||
let { realm } = this.get()
|
||||
doMediaUpload(realm, file)
|
||||
},
|
||||
async onPostPrivacyClick() {
|
||||
async onPostPrivacyClick () {
|
||||
let dialogs = await importDialogs()
|
||||
let { realm } = this.get()
|
||||
dialogs.showPostPrivacyDialog(realm)
|
||||
},
|
||||
onContentWarningClick() {
|
||||
onContentWarningClick () {
|
||||
let { realm } = this.get()
|
||||
toggleContentWarningShown(realm)
|
||||
}
|
||||
|
|
|
@ -55,8 +55,8 @@ export default {
|
|||
muteIcon: (muting) => muting ? '#fa-volume-up' : '#fa-volume-off',
|
||||
// end account data copypasta
|
||||
items: (blockLabel, blocking, blockIcon, muteLabel, muteIcon,
|
||||
followLabel, followIcon, following, followRequested,
|
||||
accountId, verifyCredentialsId, acct) => {
|
||||
followLabel, followIcon, following, followRequested,
|
||||
accountId, verifyCredentialsId, acct) => {
|
||||
let isUser = accountId === verifyCredentialsId
|
||||
return [
|
||||
!isUser && {
|
||||
|
@ -86,7 +86,7 @@ export default {
|
|||
methods: {
|
||||
show,
|
||||
close,
|
||||
onClick(item) {
|
||||
onClick (item) {
|
||||
switch (item.key) {
|
||||
case 'mention':
|
||||
return this.onMentionClicked()
|
||||
|
@ -98,7 +98,7 @@ export default {
|
|||
return this.onMuteClicked()
|
||||
}
|
||||
},
|
||||
async onMentionClicked() {
|
||||
async onMentionClicked () {
|
||||
let { acct } = this.get()
|
||||
this.store.setComposeData('dialog', {
|
||||
text: `@${acct} `
|
||||
|
@ -107,17 +107,17 @@ export default {
|
|||
dialogs.showComposeDialog()
|
||||
this.close()
|
||||
},
|
||||
async onFollowClicked() {
|
||||
async onFollowClicked () {
|
||||
let { accountId, following } = this.get()
|
||||
this.close()
|
||||
await setAccountFollowed(accountId, !following, true)
|
||||
},
|
||||
async onBlockClicked() {
|
||||
async onBlockClicked () {
|
||||
let { accountId, blocking } = this.get()
|
||||
this.close()
|
||||
await setAccountBlocked(accountId, !blocking, true)
|
||||
},
|
||||
async onMuteClicked() {
|
||||
async onMuteClicked () {
|
||||
let { accountId, muting } = this.get()
|
||||
this.close()
|
||||
await setAccountMuted(accountId, !muting, true)
|
||||
|
@ -126,6 +126,6 @@ export default {
|
|||
components: {
|
||||
ModalDialog,
|
||||
GenericDialogList
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -15,14 +15,14 @@
|
|||
import { close } from '../helpers/closeDialog'
|
||||
|
||||
export default {
|
||||
oncreate() {
|
||||
oncreate () {
|
||||
on('postedStatus', this, this.onPostedStatus)
|
||||
onCreateDialog.call(this)
|
||||
},
|
||||
methods: {
|
||||
show,
|
||||
close,
|
||||
onPostedStatus(realm) {
|
||||
onPostedStatus (realm) {
|
||||
if (realm !== 'dialog') {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -40,14 +40,14 @@
|
|||
import { oncreate as onCreateDialog } from '../helpers/onCreateDialog'
|
||||
|
||||
export default {
|
||||
oncreate() {
|
||||
oncreate () {
|
||||
on('destroyDialog', this, this.onDestroyDialog)
|
||||
onCreateDialog.call(this)
|
||||
},
|
||||
methods: {
|
||||
show,
|
||||
close,
|
||||
onDestroyDialog(thisId) {
|
||||
onDestroyDialog (thisId) {
|
||||
let {
|
||||
id,
|
||||
positiveResult,
|
||||
|
@ -67,11 +67,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
onPositive() {
|
||||
onPositive () {
|
||||
this.set({positiveResult: true})
|
||||
this.close()
|
||||
},
|
||||
onNegative() {
|
||||
onNegative () {
|
||||
this.close()
|
||||
}
|
||||
},
|
||||
|
|
|
@ -81,7 +81,7 @@
|
|||
methods: {
|
||||
show,
|
||||
close,
|
||||
onClickEmoji(emoji) {
|
||||
onClickEmoji (emoji) {
|
||||
let { realm } = this.get()
|
||||
insertEmoji(realm, emoji)
|
||||
this.close()
|
||||
|
|
|
@ -127,7 +127,7 @@
|
|||
import { on, emit } from '../../../_utils/eventBus'
|
||||
|
||||
export default {
|
||||
oncreate() {
|
||||
oncreate () {
|
||||
let dialogElement = this.refs.node.parentElement
|
||||
this._a11yDialog = new A11yDialog(dialogElement)
|
||||
this._a11yDialog.on('hide', () => {
|
||||
|
@ -162,7 +162,7 @@
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
showDialog(thisId) {
|
||||
showDialog (thisId) {
|
||||
let { id } = this.get()
|
||||
if (id !== thisId) {
|
||||
return
|
||||
|
@ -172,7 +172,7 @@
|
|||
this.set({ fadedIn: true })
|
||||
})
|
||||
},
|
||||
closeDialog(thisId) {
|
||||
closeDialog (thisId) {
|
||||
let { id } = this.get()
|
||||
if (id !== thisId) {
|
||||
return
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
methods: {
|
||||
show,
|
||||
close,
|
||||
onClick(item) {
|
||||
onClick (item) {
|
||||
let { realm } = this.get()
|
||||
setPostPrivacy(realm, item.key)
|
||||
this.close()
|
||||
|
|
|
@ -53,8 +53,8 @@ export default {
|
|||
muteIcon: (muting) => muting ? '#fa-volume-up' : '#fa-volume-off',
|
||||
// end account data copypasta
|
||||
items: (blockLabel, blocking, blockIcon, muteLabel, muteIcon,
|
||||
followLabel, followIcon, following, followRequested,
|
||||
accountId, verifyCredentialsId) => {
|
||||
followLabel, followIcon, following, followRequested,
|
||||
accountId, verifyCredentialsId) => {
|
||||
let isUser = accountId === verifyCredentialsId
|
||||
return [
|
||||
isUser && {
|
||||
|
@ -89,7 +89,7 @@ export default {
|
|||
methods: {
|
||||
show,
|
||||
close,
|
||||
onClick(item) {
|
||||
onClick (item) {
|
||||
switch (item.key) {
|
||||
case 'delete':
|
||||
return this.onDeleteClicked()
|
||||
|
@ -101,22 +101,22 @@ export default {
|
|||
return this.onMuteClicked()
|
||||
}
|
||||
},
|
||||
async onDeleteClicked() {
|
||||
async onDeleteClicked () {
|
||||
let { statusId } = this.get()
|
||||
this.close()
|
||||
await doDeleteStatus(statusId)
|
||||
},
|
||||
async onFollowClicked() {
|
||||
async onFollowClicked () {
|
||||
let { accountId, following } = this.get()
|
||||
this.close()
|
||||
await setAccountFollowed(accountId, !following, true)
|
||||
},
|
||||
async onBlockClicked() {
|
||||
async onBlockClicked () {
|
||||
let { accountId, blocking } = this.get()
|
||||
this.close()
|
||||
await setAccountBlocked(accountId, !blocking, true)
|
||||
},
|
||||
async onMuteClicked() {
|
||||
async onMuteClicked () {
|
||||
let { accountId, muting } = this.get()
|
||||
this.close()
|
||||
await setAccountMuted(accountId, !muting, true)
|
||||
|
|
|
@ -120,7 +120,7 @@
|
|||
numFollowersDisplay: numFollowers => numberFormat.format(numFollowers)
|
||||
},
|
||||
methods: {
|
||||
async onMoreOptionsClick() {
|
||||
async onMoreOptionsClick () {
|
||||
let { account, relationship, verifyCredentials } = this.get()
|
||||
let dialogs = await importDialogs()
|
||||
dialogs.showAccountProfileOptionsDialog(account, relationship, verifyCredentials)
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
export default {
|
||||
methods: {
|
||||
async onFollowButtonClick(e) {
|
||||
async onFollowButtonClick (e) {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
let {
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
note = `<p>${note}</p>`
|
||||
}
|
||||
return note
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -19,14 +19,13 @@
|
|||
}
|
||||
</style>
|
||||
<script>
|
||||
|
||||
import PseudoVirtualListLazyItem from './PseudoVirtualListLazyItem.html'
|
||||
import { getRectFromEntry } from '../../_utils/getRectFromEntry'
|
||||
import { mark, stop } from '../../_utils/marks'
|
||||
import { pseudoVirtualListStore } from './pseudoVirtualListStore'
|
||||
|
||||
export default {
|
||||
oncreate() {
|
||||
oncreate () {
|
||||
mark('PseudoVirtualList oncreate()')
|
||||
let { realm } = this.get()
|
||||
this.store.setCurrentRealm(realm)
|
||||
|
@ -57,7 +56,7 @@
|
|||
})
|
||||
stop('PseudoVirtualList oncreate()')
|
||||
},
|
||||
ondestroy() {
|
||||
ondestroy () {
|
||||
let { intersectionObserver } = this.get()
|
||||
if (intersectionObserver) {
|
||||
intersectionObserver.disconnect()
|
||||
|
@ -65,18 +64,18 @@
|
|||
this.store.setCurrentRealm(null)
|
||||
},
|
||||
helpers: {
|
||||
isIntersecting(key, $intersectionStates) {
|
||||
isIntersecting (key, $intersectionStates) {
|
||||
return !!($intersectionStates[key] && $intersectionStates[key].isIntersecting)
|
||||
},
|
||||
isCached(key, $intersectionStates) {
|
||||
isCached (key, $intersectionStates) {
|
||||
return !!($intersectionStates[key] && $intersectionStates[key].isCached)
|
||||
},
|
||||
getHeight(key, $intersectionStates) {
|
||||
getHeight (key, $intersectionStates) {
|
||||
return $intersectionStates[key] && $intersectionStates[key].height
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
scrollToPosition(element) {
|
||||
scrollToPosition (element) {
|
||||
let { scrolledToPosition } = this.get()
|
||||
if (scrolledToPosition) {
|
||||
return
|
||||
|
@ -87,7 +86,7 @@
|
|||
element.scrollIntoView(true)
|
||||
})
|
||||
},
|
||||
onIntersection(entries) {
|
||||
onIntersection (entries) {
|
||||
mark('onIntersection')
|
||||
let newIntersectionStates = {}
|
||||
let { scrollToItem } = this.get()
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
import { mark, stop } from '../../_utils/marks'
|
||||
|
||||
export default {
|
||||
oncreate() {
|
||||
oncreate () {
|
||||
this.observe('isIntersecting', isIntersecting => {
|
||||
if (isIntersecting) {
|
||||
mark('render')
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
import { mark, stop } from '../../_utils/marks'
|
||||
|
||||
export default {
|
||||
async oncreate() {
|
||||
async oncreate () {
|
||||
// TODO: there appears to be a bug in {{#await}} that means we have to do this manually.
|
||||
// Some items may appear on top of other items because their offset is 0 and never updated.
|
||||
let { makeProps, key } = this.get()
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
}
|
||||
</style>
|
||||
<script>
|
||||
import SettingsNav from './SettingsNav.html';
|
||||
import SettingsNav from './SettingsNav.html'
|
||||
import FreeTextLayout from '../../_components/FreeTextLayout'
|
||||
|
||||
export default {
|
||||
|
@ -30,5 +30,5 @@
|
|||
FreeTextLayout,
|
||||
SettingsNav
|
||||
}
|
||||
};
|
||||
}
|
||||
</script>
|
|
@ -13,10 +13,10 @@
|
|||
<script>
|
||||
export default {
|
||||
helpers: {
|
||||
getCurrentClass(page, name) {
|
||||
return page === name ? "selected" : ""
|
||||
getCurrentClass (page, name) {
|
||||
return page === name ? 'selected' : ''
|
||||
},
|
||||
getAriaLabel(page, name, label) {
|
||||
getAriaLabel (page, name, label) {
|
||||
return page === name ? `${label} (current page)` : label
|
||||
}
|
||||
}
|
||||
|
|
|
@ -98,19 +98,18 @@
|
|||
}
|
||||
</style>
|
||||
<script>
|
||||
import { DEFAULT_MEDIA_WIDTH, DEFAULT_MEDIA_HEIGHT } from '../../_static/media'
|
||||
import { DEFAULT_MEDIA_WIDTH, DEFAULT_MEDIA_HEIGHT, ONE_TRANSPARENT_PIXEL } from '../../_static/media'
|
||||
import { importDialogs } from '../../_utils/asyncModules'
|
||||
import { mouseover } from '../../_utils/events'
|
||||
import NonAutoplayGifv from '../NonAutoplayGifv.html'
|
||||
import PlayVideoIcon from '../PlayVideoIcon.html'
|
||||
import { ONE_TRANSPARENT_PIXEL } from '../../_static/media'
|
||||
import { store } from '../../_store/store'
|
||||
import LazyImage from '../LazyImage.html'
|
||||
import AutoplayVideo from '../AutoplayVideo.html'
|
||||
import { registerClickDelegate } from '../../_utils/delegate'
|
||||
|
||||
export default {
|
||||
oncreate() {
|
||||
oncreate () {
|
||||
let { delegateKey } = this.get()
|
||||
registerClickDelegate(this, delegateKey, () => {
|
||||
let { media } = this.get()
|
||||
|
@ -139,13 +138,13 @@
|
|||
delegateKey: (media, uuid) => `media-${uuid}-${media.id}`
|
||||
},
|
||||
methods: {
|
||||
async onClickPlayVideoButton() {
|
||||
async onClickPlayVideoButton () {
|
||||
let { media, modalWidth, modalHeight } = this.get()
|
||||
let dialogs = await importDialogs()
|
||||
dialogs.showVideoDialog(media.preview_url, media.url,
|
||||
modalWidth, modalHeight, media.description)
|
||||
},
|
||||
async onClickShowImageButton() {
|
||||
async onClickShowImageButton () {
|
||||
let { media, modalWidth, modalHeight } = this.get()
|
||||
let dialogs = await importDialogs()
|
||||
dialogs.showImageDialog(media.preview_url, media.url, media.type,
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
computed: {
|
||||
maxMediaWidth: (mediaAttachments) => {
|
||||
return Math.max.apply(Math, mediaAttachments.map(media => {
|
||||
return media.meta && media.meta.small && typeof media.meta.small.width === 'number' ? media.meta.small.width : DEFAULT_MEDIA_WIDTH
|
||||
return media.meta && media.meta.small && typeof media.meta.small.width === 'number' ? media.meta.small.width : DEFAULT_MEDIA_WIDTH
|
||||
}))
|
||||
}
|
||||
},
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
statusId: (status) => status && status.id,
|
||||
uuid: ($currentInstance, timelineType, timelineValue, notificationId, statusId) => {
|
||||
return `${$currentInstance}/${timelineType}/${timelineValue}/${notificationId}/${statusId || ''}`
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -122,7 +122,7 @@
|
|||
const isStatusArticle = node => node.classList.contains('status-article')
|
||||
|
||||
export default {
|
||||
oncreate() {
|
||||
oncreate () {
|
||||
let { delegateKey, isStatusInOwnThread, showContent } = this.get()
|
||||
if (!isStatusInOwnThread) {
|
||||
// the whole <article> is clickable in this case
|
||||
|
@ -151,7 +151,7 @@
|
|||
},
|
||||
store: () => store,
|
||||
methods: {
|
||||
onClickOrKeydown(e) {
|
||||
onClickOrKeydown (e) {
|
||||
let { type, keyCode, target } = e
|
||||
|
||||
let isClick = type === 'click'
|
||||
|
@ -202,18 +202,18 @@
|
|||
spoilerShown: ($spoilersShown, uuid) => !!$spoilersShown[uuid],
|
||||
replyShown: ($repliesShown, uuid) => !!$repliesShown[uuid],
|
||||
showMedia: (originalStatus, isStatusInNotification) => {
|
||||
return !isStatusInNotification
|
||||
&& originalStatus.media_attachments
|
||||
&& originalStatus.media_attachments.length
|
||||
return !isStatusInNotification &&
|
||||
originalStatus.media_attachments &&
|
||||
originalStatus.media_attachments.length
|
||||
},
|
||||
ariaLabel: (originalAccount, originalStatus, visibility) => {
|
||||
return (visibility === 'direct' ? 'Direct message' : 'Status') +
|
||||
` by ${originalAccount.display_name || originalAccount.username}`
|
||||
},
|
||||
showHeader: (notification, status, timelineType) => {
|
||||
return (notification && (notification.type === 'reblog' || notification.type === 'favourite'))
|
||||
|| status.reblog
|
||||
|| timelineType === 'pinned'
|
||||
return (notification && (notification.type === 'reblog' || notification.type === 'favourite')) ||
|
||||
status.reblog ||
|
||||
timelineType === 'pinned'
|
||||
},
|
||||
className: (visibility, timelineType, isStatusInOwnThread) => {
|
||||
return classname(
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
const THROTTLE_DELAY = 150
|
||||
|
||||
export default {
|
||||
oncreate() {
|
||||
oncreate () {
|
||||
on('postedStatus', this, this.onPostedStatus)
|
||||
this.setupRecalculateHeightListener()
|
||||
},
|
||||
|
@ -34,7 +34,7 @@
|
|||
composeData: ($currentComposeData, originalStatusId) => $currentComposeData[originalStatusId] || {}
|
||||
},
|
||||
methods: {
|
||||
onPostedStatus(realm) {
|
||||
onPostedStatus (realm) {
|
||||
let { originalStatusId } = this.get()
|
||||
if (realm !== originalStatusId) {
|
||||
return
|
||||
|
@ -47,7 +47,7 @@
|
|||
this.fire('recalculateHeight')
|
||||
})
|
||||
},
|
||||
setupRecalculateHeightListener() {
|
||||
setupRecalculateHeightListener () {
|
||||
const recalc = () => requestAnimationFrame(() => this.fire('recalculateHeight'))
|
||||
// debounce AND throttle due to 333ms content warning animation
|
||||
const debounced = debounce(recalc, DEBOUNCE_DELAY)
|
||||
|
|
|
@ -64,7 +64,7 @@
|
|||
import { emojifyText } from '../../_utils/emojifyText'
|
||||
|
||||
export default {
|
||||
oncreate() {
|
||||
oncreate () {
|
||||
this.hydrateContent()
|
||||
},
|
||||
store: () => store,
|
||||
|
@ -90,7 +90,7 @@
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
hydrateContent() {
|
||||
hydrateContent () {
|
||||
if (!this.refs.node) {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -81,7 +81,6 @@
|
|||
}
|
||||
</style>
|
||||
<script>
|
||||
|
||||
import Avatar from '../Avatar.html'
|
||||
|
||||
export default {
|
||||
|
|
|
@ -129,7 +129,7 @@
|
|||
import { registerClickDelegate } from '../../_utils/delegate'
|
||||
|
||||
export default {
|
||||
oncreate() {
|
||||
oncreate () {
|
||||
let { delegateKey } = this.get()
|
||||
registerClickDelegate(this, delegateKey, () => this.onClickSensitiveMediaButton())
|
||||
},
|
||||
|
@ -141,10 +141,10 @@
|
|||
mediaAttachments: (originalStatus) => originalStatus.media_attachments,
|
||||
sensitiveShown: ($sensitivesShown, uuid) => !!$sensitivesShown[uuid],
|
||||
sensitive: (originalStatus, $markMediaAsSensitive) => originalStatus.sensitive || $markMediaAsSensitive,
|
||||
delegateKey: (uuid) => `sensitive-${uuid}`,
|
||||
delegateKey: (uuid) => `sensitive-${uuid}`
|
||||
},
|
||||
methods: {
|
||||
onClickSensitiveMediaButton() {
|
||||
onClickSensitiveMediaButton () {
|
||||
let { uuid } = this.get()
|
||||
let { sensitivesShown } = this.store.get()
|
||||
sensitivesShown[uuid] = !sensitivesShown[uuid]
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
import escapeHtml from 'escape-html'
|
||||
|
||||
export default {
|
||||
oncreate() {
|
||||
oncreate () {
|
||||
let { delegateKey } = this.get()
|
||||
registerClickDelegate(this, delegateKey, () => this.onClickSpoilerButton())
|
||||
},
|
||||
|
@ -67,7 +67,7 @@
|
|||
delegateKey: (uuid) => `spoiler-${uuid}`
|
||||
},
|
||||
methods: {
|
||||
onClickSpoilerButton() {
|
||||
onClickSpoilerButton () {
|
||||
requestAnimationFrame(() => {
|
||||
mark('clickSpoilerButton')
|
||||
let { uuid } = this.get()
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
import { on } from '../../_utils/eventBus'
|
||||
|
||||
export default {
|
||||
oncreate() {
|
||||
oncreate () {
|
||||
let {
|
||||
favoriteKey,
|
||||
reblogKey,
|
||||
|
@ -73,21 +73,21 @@
|
|||
},
|
||||
store: () => store,
|
||||
methods: {
|
||||
onFavoriteClick(e) {
|
||||
onFavoriteClick (e) {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
let { originalStatusId, favorited } = this.get()
|
||||
/* no await */ setFavorited(originalStatusId, !favorited)
|
||||
this.set({animateFavorite: !favorited})
|
||||
},
|
||||
onReblogClick(e) {
|
||||
onReblogClick (e) {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
let { originalStatusId, reblogged } = this.get()
|
||||
/* no await */ setReblogged(originalStatusId, !reblogged)
|
||||
this.set({animateReblog: !reblogged})
|
||||
},
|
||||
onReplyClick(e) {
|
||||
onReplyClick (e) {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
requestAnimationFrame(() => {
|
||||
|
@ -98,7 +98,7 @@
|
|||
this.fire('recalculateHeight')
|
||||
})
|
||||
},
|
||||
async onOptionsClick(e) {
|
||||
async onOptionsClick (e) {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
let { originalStatusId, originalAccountId } = this.get()
|
||||
|
@ -107,7 +107,7 @@
|
|||
await updateRelationshipPromise
|
||||
dialogs.showStatusOptionsDialog(originalStatusId)
|
||||
},
|
||||
onPostedStatus(realm, inReplyToUuid) {
|
||||
onPostedStatus (realm, inReplyToUuid) {
|
||||
let {
|
||||
originalStatusId,
|
||||
uuid
|
||||
|
@ -166,7 +166,7 @@
|
|||
favoriteKey: (uuid) => `fav-${uuid}`,
|
||||
reblogKey: (uuid) => `reblog-${uuid}`,
|
||||
replyKey: (uuid) => `reply-${uuid}`,
|
||||
optionsKey: (uuid) => `options-${uuid}`,
|
||||
optionsKey: (uuid) => `options-${uuid}`
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -16,7 +16,7 @@
|
|||
import { store } from '../../_store/store'
|
||||
|
||||
export default {
|
||||
oncreate() {
|
||||
oncreate () {
|
||||
let { currentInstance } = this.store.get()
|
||||
let { timeline } = this.get()
|
||||
this.store.set({currentTimeline: timeline})
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<script>
|
||||
export default {
|
||||
methods: {
|
||||
onClick(event) {
|
||||
onClick (event) {
|
||||
let { onClick } = this.get()
|
||||
if (onClick) {
|
||||
onClick(event)
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
import { updatePinnedStatusesForAccount } from '../../_actions/pinnedStatuses'
|
||||
|
||||
export default {
|
||||
async oncreate() {
|
||||
async oncreate () {
|
||||
let { accountId } = this.get()
|
||||
await updatePinnedStatusesForAccount(accountId)
|
||||
},
|
||||
|
|
|
@ -63,14 +63,14 @@
|
|||
import { doubleRAF } from '../../_utils/doubleRAF'
|
||||
|
||||
export default {
|
||||
oncreate() {
|
||||
oncreate () {
|
||||
console.log('timeline oncreate()')
|
||||
this.setupFocus()
|
||||
setupTimeline()
|
||||
this.restoreFocus()
|
||||
this.setupStreaming()
|
||||
},
|
||||
ondestroy() {
|
||||
ondestroy () {
|
||||
console.log('ondestroy')
|
||||
this.teardownFocus()
|
||||
},
|
||||
|
@ -122,15 +122,13 @@
|
|||
},
|
||||
// for threads, it's simpler to just render all items as a pseudo-virtual list
|
||||
// due to need to scroll to the right item and thus calculate all item heights up-front
|
||||
virtual: (timelineType) => timelineType !=='status',
|
||||
scrollToItem: (timelineType, timelineValue, $firstTimelineItemId) => {
|
||||
// Scroll to the first item if this is a "status in own thread" timeline.
|
||||
// Don't scroll to the first item because it obscures the "back" button.
|
||||
return timelineType === 'status'
|
||||
&& $firstTimelineItemId
|
||||
&& timelineValue !== $firstTimelineItemId
|
||||
&& timelineValue
|
||||
},
|
||||
virtual: (timelineType) => timelineType !== 'status',
|
||||
// Scroll to the first item if this is a "status in own thread" timeline.
|
||||
// Don't scroll to the first item because it obscures the "back" button.
|
||||
scrollToItem: (timelineType, timelineValue, $firstTimelineItemId) => (
|
||||
timelineType === 'status' && $firstTimelineItemId &&
|
||||
timelineValue !== $firstTimelineItemId && timelineValue
|
||||
),
|
||||
itemIdsToAdd: ($itemIdsToAdd) => $itemIdsToAdd,
|
||||
headerProps: (itemIdsToAdd) => {
|
||||
return {
|
||||
|
@ -149,7 +147,7 @@
|
|||
blurWithCapture
|
||||
},
|
||||
methods: {
|
||||
initialize() {
|
||||
initialize () {
|
||||
let { initializeStarted } = this.get()
|
||||
if (initializeStarted) {
|
||||
return
|
||||
|
@ -162,10 +160,10 @@
|
|||
stop('initializeTimeline')
|
||||
})
|
||||
},
|
||||
onScrollTopChanged(scrollTop) {
|
||||
onScrollTopChanged (scrollTop) {
|
||||
this.set({scrollTop: scrollTop})
|
||||
},
|
||||
onScrollToBottom() {
|
||||
onScrollToBottom () {
|
||||
let {
|
||||
timelineInitialized,
|
||||
runningUpdate
|
||||
|
@ -185,7 +183,7 @@
|
|||
timeline
|
||||
)
|
||||
},
|
||||
onScrollToTop() {
|
||||
onScrollToTop () {
|
||||
let { shouldShowHeader } = this.store.get()
|
||||
if (shouldShowHeader) {
|
||||
this.store.setForCurrentTimeline({
|
||||
|
@ -194,7 +192,7 @@
|
|||
})
|
||||
}
|
||||
},
|
||||
setupStreaming() {
|
||||
setupStreaming () {
|
||||
let { currentInstance } = this.store.get()
|
||||
let { timeline } = this.get()
|
||||
let handleItemIdsToAdd = () => {
|
||||
|
@ -230,20 +228,20 @@
|
|||
scheduleIdleTask(handleItemIdsToAdd)
|
||||
})
|
||||
},
|
||||
setupFocus() {
|
||||
setupFocus () {
|
||||
this.onPushState = this.onPushState.bind(this)
|
||||
this.store.setForCurrentTimeline({
|
||||
ignoreBlurEvents: false
|
||||
})
|
||||
window.addEventListener('pushState', this.onPushState)
|
||||
},
|
||||
teardownFocus() {
|
||||
teardownFocus () {
|
||||
window.removeEventListener('pushState', this.onPushState)
|
||||
},
|
||||
onPushState() {
|
||||
onPushState () {
|
||||
this.store.setForCurrentTimeline({ ignoreBlurEvents: true })
|
||||
},
|
||||
saveFocus(e) {
|
||||
saveFocus (e) {
|
||||
try {
|
||||
let { currentInstance } = this.store.get()
|
||||
let { timeline } = this.get()
|
||||
|
@ -263,7 +261,7 @@
|
|||
console.error('unable to save focus', err)
|
||||
}
|
||||
},
|
||||
clearFocus() {
|
||||
clearFocus () {
|
||||
try {
|
||||
let { ignoreBlurEvents } = this.store.get()
|
||||
if (ignoreBlurEvents) {
|
||||
|
@ -279,7 +277,7 @@
|
|||
console.error('unable to clear focus', err)
|
||||
}
|
||||
},
|
||||
restoreFocus() {
|
||||
restoreFocus () {
|
||||
let { lastFocusedElementSelector } = this.store.get()
|
||||
if (!lastFocusedElementSelector) {
|
||||
return
|
||||
|
@ -294,7 +292,7 @@
|
|||
})
|
||||
})
|
||||
},
|
||||
onNoNeedToScroll() {
|
||||
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.
|
||||
|
|
|
@ -105,10 +105,10 @@
|
|||
},
|
||||
scrollTop: ($scrollTop) => $scrollTop,
|
||||
// TODO: bug in svelte store, shouldn't need to do this
|
||||
allVisibleItemsHaveHeight: ($allVisibleItemsHaveHeight) => $allVisibleItemsHaveHeight,
|
||||
allVisibleItemsHaveHeight: ($allVisibleItemsHaveHeight) => $allVisibleItemsHaveHeight
|
||||
},
|
||||
methods: {
|
||||
calculateListOffset() {
|
||||
calculateListOffset () {
|
||||
// TODO: better way to get the offset top?
|
||||
let node = this.refs.node
|
||||
if (!node) {
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
const SCROLL_EVENT_DELAY = 300
|
||||
|
||||
export default {
|
||||
oncreate() {
|
||||
oncreate () {
|
||||
mark('onCreate VirtualListContainer')
|
||||
let {
|
||||
realm,
|
||||
|
@ -53,14 +53,14 @@
|
|||
}
|
||||
stop('onCreate VirtualListContainer')
|
||||
},
|
||||
ondestroy() {
|
||||
ondestroy () {
|
||||
this.teardownScroll()
|
||||
this.teardownFullscreen()
|
||||
this.store.setCurrentRealm(null)
|
||||
},
|
||||
store: () => virtualListStore,
|
||||
methods: {
|
||||
setupScroll(node) {
|
||||
setupScroll (node) {
|
||||
if (!node) {
|
||||
return
|
||||
}
|
||||
|
@ -76,21 +76,21 @@
|
|||
})
|
||||
node.addEventListener('scroll', this.scrollListener)
|
||||
},
|
||||
teardownScroll() {
|
||||
teardownScroll () {
|
||||
let { containerQuery } = this.get()
|
||||
let node = document.querySelector(containerQuery)
|
||||
if (node) {
|
||||
node.removeEventListener('scroll', this.scrollListener)
|
||||
}
|
||||
},
|
||||
setupFullscreen() {
|
||||
setupFullscreen () {
|
||||
this.onFullscreenChange = this.onFullscreenChange.bind(this)
|
||||
attachFullscreenListener(this.onFullscreenChange)
|
||||
},
|
||||
teardownFullscreen() {
|
||||
teardownFullscreen () {
|
||||
detachFullscreenListener(this.onFullscreenChange)
|
||||
},
|
||||
onScroll(event) {
|
||||
onScroll (event) {
|
||||
let { scrollTop, scrollHeight } = event.target
|
||||
|
||||
// On mobile devices, this can make scrolling more responsive. On
|
||||
|
@ -104,7 +104,7 @@
|
|||
stop('onScroll -> setForRealm()')
|
||||
})
|
||||
},
|
||||
onFullscreenChange() {
|
||||
onFullscreenChange () {
|
||||
mark('onFullscreenChange')
|
||||
console.log('is fullscreen? ', isFullscreen())
|
||||
this.set({ fullscreen: isFullscreen() })
|
||||
|
@ -115,5 +115,5 @@
|
|||
// TODO: bug in svelte/store – the observer in oncreate() never get removed without this hack
|
||||
allVisibleItemsHaveHeight: ($allVisibleItemsHaveHeight) => $allVisibleItemsHaveHeight
|
||||
}
|
||||
};
|
||||
}
|
||||
</script>
|
|
@ -15,13 +15,13 @@
|
|||
import { AsyncLayout } from '../../_utils/AsyncLayout'
|
||||
|
||||
export default {
|
||||
oncreate() {
|
||||
oncreate () {
|
||||
const asyncLayout = new AsyncLayout(() => '__footer__')
|
||||
asyncLayout.observe('__footer__', this.refs.node, (rect) => {
|
||||
asyncLayout.disconnect()
|
||||
this.store.setForRealm({footerHeight: rect.height})
|
||||
})
|
||||
},
|
||||
store: () => virtualListStore,
|
||||
store: () => virtualListStore
|
||||
}
|
||||
</script>
|
|
@ -26,7 +26,7 @@
|
|||
import { doubleRAF } from '../../_utils/doubleRAF'
|
||||
|
||||
export default {
|
||||
oncreate() {
|
||||
oncreate () {
|
||||
this.observe('shown', shown => {
|
||||
if (shown) {
|
||||
this.doCalculateHeight()
|
||||
|
@ -38,7 +38,7 @@
|
|||
},
|
||||
store: () => virtualListStore,
|
||||
methods: {
|
||||
doCalculateHeight() {
|
||||
doCalculateHeight () {
|
||||
let { heightCalculated } = this.get()
|
||||
if (heightCalculated) { // only need to calculate once, it never changes
|
||||
return
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
import { registerResizeListener, unregisterResizeListener } from '../../_utils/resize'
|
||||
|
||||
export default {
|
||||
oncreate() {
|
||||
oncreate () {
|
||||
let asyncLayout = new AsyncLayout(node => node.getAttribute('virtual-list-key'))
|
||||
let { key } = this.get()
|
||||
asyncLayout.observe(key, this.refs.node, (rect) => {
|
||||
|
@ -39,7 +39,7 @@
|
|||
this.doRecalculateHeight = this.doRecalculateHeight.bind(this)
|
||||
registerResizeListener(this.doRecalculateHeight)
|
||||
},
|
||||
ondestroy() {
|
||||
ondestroy () {
|
||||
unregisterResizeListener(this.doRecalculateHeight)
|
||||
},
|
||||
store: () => virtualListStore,
|
||||
|
@ -47,7 +47,7 @@
|
|||
'shown': ($itemHeights, key) => $itemHeights[key] > 0
|
||||
},
|
||||
methods: {
|
||||
doRecalculateHeight() {
|
||||
doRecalculateHeight () {
|
||||
// Recalculate immediately because this is done on-demand, e.g.
|
||||
// when clicking the "More" button on a spoiler.
|
||||
let rect = this.refs.node.getBoundingClientRect()
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
import { mark, stop } from '../../_utils/marks'
|
||||
|
||||
export default {
|
||||
async oncreate() {
|
||||
async oncreate () {
|
||||
// TODO: there appears to be a bug in {{#await}} that means we have to do this manually.
|
||||
// Some items may appear on top of other items because their offset is 0 and never updated.
|
||||
let { makeProps, key } = this.get()
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
import PinnedStatuses from '../../_components/timeline/PinnedStatuses.html'
|
||||
|
||||
export default {
|
||||
oncreate() {
|
||||
oncreate () {
|
||||
let { params } = this.get()
|
||||
let { accountId } = params
|
||||
clearProfileAndRelationship()
|
||||
|
|
|
@ -95,7 +95,7 @@
|
|||
import { updateLists } from '../../_actions/lists'
|
||||
|
||||
export default {
|
||||
async oncreate() {
|
||||
async oncreate () {
|
||||
let { currentInstance } = this.store.get()
|
||||
if (currentInstance) {
|
||||
await updateLists()
|
||||
|
@ -111,5 +111,5 @@
|
|||
computed: {
|
||||
isLockedAccount: ($currentVerifyCredentials) => $currentVerifyCredentials && $currentVerifyCredentials.locked
|
||||
}
|
||||
};
|
||||
}
|
||||
</script>
|
|
@ -8,11 +8,11 @@
|
|||
import { store } from '.././_store/store.js'
|
||||
import TimelineHomePage from '../_components/TimelineHomePage.html'
|
||||
|
||||
export default {
|
||||
store: () => store,
|
||||
components: {
|
||||
NotLoggedInHome,
|
||||
export default {
|
||||
store: () => store,
|
||||
components: {
|
||||
NotLoggedInHome,
|
||||
TimelineHomePage
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -22,5 +22,5 @@
|
|||
HiddenFromSSR,
|
||||
TimelinePage
|
||||
}
|
||||
};
|
||||
}
|
||||
</script>
|
|
@ -37,7 +37,7 @@
|
|||
import { updateVerifyCredentialsForInstance } from '.././_actions/instances'
|
||||
|
||||
export default {
|
||||
async oncreate() {
|
||||
async oncreate () {
|
||||
try {
|
||||
let { currentInstance } = this.store.get()
|
||||
await updateVerifyCredentialsForInstance(currentInstance)
|
||||
|
|
|
@ -27,5 +27,5 @@
|
|||
data: () => ({
|
||||
version
|
||||
})
|
||||
};
|
||||
}
|
||||
</script>
|
|
@ -42,5 +42,5 @@
|
|||
SettingsLayout
|
||||
},
|
||||
store: () => store
|
||||
};
|
||||
}
|
||||
</script>
|
|
@ -19,5 +19,5 @@
|
|||
SettingsList,
|
||||
SettingsListItem
|
||||
}
|
||||
};
|
||||
}
|
||||
</script>
|
|
@ -112,9 +112,9 @@
|
|||
},
|
||||
store: () => store,
|
||||
data: () => ({
|
||||
themes: themes,
|
||||
themes: themes
|
||||
}),
|
||||
async oncreate() {
|
||||
async oncreate () {
|
||||
let { instanceName } = this.get()
|
||||
await updateVerifyCredentialsForInstance(instanceName)
|
||||
},
|
||||
|
@ -124,23 +124,23 @@
|
|||
verifyCredentials: ($verifyCredentials, instanceName) => $verifyCredentials && $verifyCredentials[instanceName]
|
||||
},
|
||||
methods: {
|
||||
onThemeChange() {
|
||||
onThemeChange () {
|
||||
let { newTheme, instanceName } = this.get()
|
||||
changeTheme(instanceName, newTheme)
|
||||
changeTheme(instanceName, newTheme)
|
||||
},
|
||||
onSwitchToThisInstance(e) {
|
||||
onSwitchToThisInstance (e) {
|
||||
e.preventDefault()
|
||||
let { instanceName } = this.get()
|
||||
switchToInstance(instanceName)
|
||||
},
|
||||
async onLogOut(e) {
|
||||
async onLogOut (e) {
|
||||
e.preventDefault()
|
||||
let { instanceName } = this.get()
|
||||
|
||||
let dialogs = await importDialogs()
|
||||
dialogs.showConfirmationDialog({
|
||||
text: `Log out of ${instanceName}?`,
|
||||
onPositive() {
|
||||
onPositive () {
|
||||
logOutOfInstance(instanceName)
|
||||
}
|
||||
})
|
||||
|
|
|
@ -75,7 +75,7 @@
|
|||
},
|
||||
store: () => store,
|
||||
methods: {
|
||||
onSubmit(event) {
|
||||
onSubmit (event) {
|
||||
event.preventDefault()
|
||||
logInToInstance()
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue