remove get() with string from Svelte calls (#169)

* remove get() with string pt 1

* remove get() with string pt 2

* fix typo

* fix some null exceptions in get()

* fixup code style
This commit is contained in:
Nolan Lawson 2018-04-19 09:37:05 -07:00 committed by GitHub
parent 18c3064801
commit 8d5690d63d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
70 changed files with 454 additions and 391 deletions

View File

@ -52,11 +52,10 @@ export async function clearProfileAndRelationship () {
} }
export async function updateProfileAndRelationship (accountId) { export async function updateProfileAndRelationship (accountId) {
let instanceName = store.get('currentInstance') let { currentInstance, accessToken } = store.get()
let accessToken = store.get('accessToken')
await Promise.all([ await Promise.all([
updateAccount(accountId, instanceName, accessToken), updateAccount(accountId, currentInstance, accessToken),
updateRelationship(accountId, instanceName, accessToken) updateRelationship(accountId, currentInstance, accessToken)
]) ])
} }

View File

@ -11,24 +11,23 @@ const REDIRECT_URI = (typeof location !== 'undefined'
? location.origin : 'https://pinafore.social') + '/settings/instances/add' ? location.origin : 'https://pinafore.social') + '/settings/instances/add'
async function redirectToOauth () { async function redirectToOauth () {
let instanceName = store.get('instanceNameInSearch') let { instanceNameInSearch, loggedInInstances } = store.get()
let loggedInInstances = store.get('loggedInInstances') instanceNameInSearch = instanceNameInSearch.replace(/^https?:\/\//, '').replace(/\/$/, '').replace('/$', '').toLowerCase()
instanceName = instanceName.replace(/^https?:\/\//, '').replace(/\/$/, '').replace('/$', '').toLowerCase() if (Object.keys(loggedInInstances).includes(instanceNameInSearch)) {
if (Object.keys(loggedInInstances).includes(instanceName)) { store.set({logInToInstanceError: `You've already logged in to ${instanceNameInSearch}`})
store.set({logInToInstanceError: `You've already logged in to ${instanceName}`})
return return
} }
let registrationPromise = registerApplication(instanceName, REDIRECT_URI) let registrationPromise = registerApplication(instanceNameInSearch, REDIRECT_URI)
let instanceInfo = await getInstanceInfo(instanceName) let instanceInfo = await getInstanceInfo(instanceNameInSearch)
await setInstanceInfoInDatabase(instanceName, instanceInfo) // cache for later await setInstanceInfoInDatabase(instanceNameInSearch, instanceInfo) // cache for later
let instanceData = await registrationPromise let instanceData = await registrationPromise
store.set({ store.set({
currentRegisteredInstanceName: instanceName, currentRegisteredInstanceName: instanceNameInSearch,
currentRegisteredInstance: instanceData currentRegisteredInstance: instanceData
}) })
store.save() store.save()
let oauthUrl = generateAuthLink( let oauthUrl = generateAuthLink(
instanceName, instanceNameInSearch,
instanceData.client_id, instanceData.client_id,
REDIRECT_URI REDIRECT_URI
) )
@ -48,9 +47,10 @@ export async function logInToInstance () {
(navigator.onLine (navigator.onLine
? `Is this a valid Mastodon instance? Is a browser extension blocking the request?` ? `Is this a valid Mastodon instance? Is a browser extension blocking the request?`
: `Are you offline?`) : `Are you offline?`)
let { instanceNameInSearch } = store.get()
store.set({ store.set({
logInToInstanceError: error, logInToInstanceError: error,
logInToInstanceErrorForText: store.get('instanceNameInSearch') logInToInstanceErrorForText: instanceNameInSearch
}) })
} finally { } finally {
store.set({logInToInstanceLoading: false}) store.set({logInToInstanceLoading: false})
@ -58,8 +58,7 @@ export async function logInToInstance () {
} }
async function registerNewInstance (code) { async function registerNewInstance (code) {
let currentRegisteredInstanceName = store.get('currentRegisteredInstanceName') let { currentRegisteredInstanceName, currentRegisteredInstance } = store.get()
let currentRegisteredInstance = store.get('currentRegisteredInstance')
let instanceData = await getAccessTokenFromAuthCode( let instanceData = await getAccessTokenFromAuthCode(
currentRegisteredInstanceName, currentRegisteredInstanceName,
currentRegisteredInstance.client_id, currentRegisteredInstance.client_id,
@ -67,9 +66,7 @@ async function registerNewInstance (code) {
code, code,
REDIRECT_URI REDIRECT_URI
) )
let loggedInInstances = store.get('loggedInInstances') let { loggedInInstances, loggedInInstancesInOrder, instanceThemes } = store.get()
let loggedInInstancesInOrder = store.get('loggedInInstancesInOrder')
let instanceThemes = store.get('instanceThemes')
instanceThemes[currentRegisteredInstanceName] = 'default' instanceThemes[currentRegisteredInstanceName] = 'default'
loggedInInstances[currentRegisteredInstanceName] = instanceData loggedInInstances[currentRegisteredInstanceName] = instanceData
if (!loggedInInstancesInOrder.includes(currentRegisteredInstanceName)) { if (!loggedInInstancesInOrder.includes(currentRegisteredInstanceName)) {

View File

@ -4,13 +4,12 @@ import { toast } from '../_utils/toast'
import { updateProfileAndRelationship } from './accounts' import { updateProfileAndRelationship } from './accounts'
export async function setAccountBlocked (accountId, block, toastOnSuccess) { export async function setAccountBlocked (accountId, block, toastOnSuccess) {
let instanceName = store.get('currentInstance') let { currentInstance, accessToken } = store.get()
let accessToken = store.get('accessToken')
try { try {
if (block) { if (block) {
await blockAccount(instanceName, accessToken, accountId) await blockAccount(currentInstance, accessToken, accountId)
} else { } else {
await unblockAccount(instanceName, accessToken, accountId) await unblockAccount(currentInstance, accessToken, accountId)
} }
await updateProfileAndRelationship(accountId) await updateProfileAndRelationship(accountId)
if (toastOnSuccess) { if (toastOnSuccess) {

View File

@ -7,12 +7,12 @@ import { emit } from '../_utils/eventBus'
import { putMediaDescription } from '../_api/media' import { putMediaDescription } from '../_api/media'
export async function insertHandleForReply (statusId) { export async function insertHandleForReply (statusId) {
let instanceName = store.get('currentInstance') let { currentInstance } = store.get()
let status = await getStatusFromDatabase(instanceName, statusId) let status = await getStatusFromDatabase(currentInstance, statusId)
let verifyCredentials = store.get('currentVerifyCredentials') let { currentVerifyCredentials } = store.get()
let originalStatus = status.reblog || status let originalStatus = status.reblog || status
let accounts = [originalStatus.account].concat(originalStatus.mentions || []) let accounts = [originalStatus.account].concat(originalStatus.mentions || [])
.filter(account => account.id !== verifyCredentials.id) .filter(account => account.id !== currentVerifyCredentials.id)
if (!store.getComposeData(statusId, 'text') && accounts.length) { if (!store.getComposeData(statusId, 'text') && accounts.length) {
store.setComposeData(statusId, { store.setComposeData(statusId, {
text: accounts.map(account => `@${account.acct} `).join('') text: accounts.map(account => `@${account.acct} `).join('')
@ -23,9 +23,7 @@ export async function insertHandleForReply (statusId) {
export async function postStatus (realm, text, inReplyToId, mediaIds, export async function postStatus (realm, text, inReplyToId, mediaIds,
sensitive, spoilerText, visibility, sensitive, spoilerText, visibility,
mediaDescriptions = [], inReplyToUuid) { mediaDescriptions = [], inReplyToUuid) {
let instanceName = store.get('currentInstance') let { currentInstance, accessToken, online } = store.get()
let accessToken = store.get('accessToken')
let online = store.get('online')
if (!online) { if (!online) {
toast.say('You cannot post while offline') toast.say('You cannot post while offline')
@ -37,11 +35,11 @@ export async function postStatus (realm, text, inReplyToId, mediaIds,
}) })
try { try {
await Promise.all(mediaDescriptions.map(async (description, i) => { await Promise.all(mediaDescriptions.map(async (description, i) => {
return description && putMediaDescription(instanceName, accessToken, mediaIds[i], description) return description && putMediaDescription(currentInstance, accessToken, mediaIds[i], description)
})) }))
let status = await postStatusToServer(instanceName, accessToken, text, let status = await postStatusToServer(currentInstance, accessToken, text,
inReplyToId, mediaIds, sensitive, spoilerText, visibility) inReplyToId, mediaIds, sensitive, spoilerText, visibility)
addStatusOrNotification(instanceName, 'home', status) addStatusOrNotification(currentInstance, 'home', status)
store.clearComposeData(realm) store.clearComposeData(realm)
emit('postedStatus', realm, inReplyToUuid) emit('postedStatus', realm, inReplyToUuid)
} catch (e) { } catch (e) {
@ -61,12 +59,16 @@ export async function insertUsername (realm, username, startIndex, endIndex) {
} }
export async function clickSelectedAutosuggestionUsername (realm) { export async function clickSelectedAutosuggestionUsername (realm) {
let selectionStart = store.get('composeSelectionStart') let {
let searchText = store.get('composeAutosuggestionSearchText') composeSelectionStart,
let selection = store.get('composeAutosuggestionSelected') || 0 composeAutosuggestionSearchText,
let account = store.get('composeAutosuggestionSearchResults')[selection] composeAutosuggestionSelected,
let startIndex = selectionStart - searchText.length composeAutosuggestionSearchResults
let endIndex = selectionStart } = store.get()
composeAutosuggestionSelected = composeAutosuggestionSelected || 0
let account = composeAutosuggestionSearchResults[composeAutosuggestionSelected]
let startIndex = composeSelectionStart - composeAutosuggestionSearchText.length
let endIndex = composeSelectionStart
await insertUsername(realm, account.acct, startIndex, endIndex) await insertUsername(realm, account.acct, startIndex, endIndex)
} }
@ -96,8 +98,8 @@ export function setReplyVisibility (realm, replyVisibility) {
if (typeof postPrivacy !== 'undefined') { if (typeof postPrivacy !== 'undefined') {
return // user has already set the postPrivacy return // user has already set the postPrivacy
} }
let verifyCredentials = store.get('currentVerifyCredentials') let { currentVerifyCredentials } = store.get()
let defaultVisibility = verifyCredentials.source.privacy let defaultVisibility = currentVerifyCredentials.source.privacy
let visibility = PRIVACY_LEVEL[replyVisibility] < PRIVACY_LEVEL[defaultVisibility] let visibility = PRIVACY_LEVEL[replyVisibility] < PRIVACY_LEVEL[defaultVisibility]
? replyVisibility ? replyVisibility
: defaultVisibility : defaultVisibility

View File

@ -3,10 +3,9 @@ import { deleteStatus } from '../_api/delete'
import { toast } from '../_utils/toast' import { toast } from '../_utils/toast'
export async function doDeleteStatus (statusId) { export async function doDeleteStatus (statusId) {
let instanceName = store.get('currentInstance') let { currentInstance, accessToken } = store.get()
let accessToken = store.get('accessToken')
try { try {
await deleteStatus(instanceName, accessToken, statusId) await deleteStatus(currentInstance, accessToken, statusId)
toast.say('Status deleted.') toast.say('Status deleted.')
} catch (e) { } catch (e) {
console.error(e) console.error(e)

View File

@ -12,7 +12,7 @@ export async function updateCustomEmojiForInstance (instanceName) {
() => getCustomEmojiFromDatabase(instanceName), () => getCustomEmojiFromDatabase(instanceName),
emoji => setCustomEmojiInDatabase(instanceName, emoji), emoji => setCustomEmojiInDatabase(instanceName, emoji),
emoji => { emoji => {
let customEmoji = store.get('customEmoji') let { customEmoji } = store.get()
customEmoji[instanceName] = emoji customEmoji[instanceName] = emoji
store.set({customEmoji: customEmoji}) store.set({customEmoji: customEmoji})
} }
@ -20,7 +20,8 @@ export async function updateCustomEmojiForInstance (instanceName) {
} }
export function insertEmoji (realm, emoji) { export function insertEmoji (realm, emoji) {
let idx = store.get('composeSelectionStart') || 0 let { composeSelectionStart } = store.get()
let idx = composeSelectionStart || 0
let oldText = store.getComposeData(realm, 'text') || '' let oldText = store.getComposeData(realm, 'text') || ''
let pre = oldText.substring(0, idx) let pre = oldText.substring(0, idx)
let post = oldText.substring(idx) let post = oldText.substring(idx)
@ -37,11 +38,15 @@ export function insertEmojiAtPosition (realm, emoji, startIndex, endIndex) {
} }
export async function clickSelectedAutosuggestionEmoji (realm) { export async function clickSelectedAutosuggestionEmoji (realm) {
let selectionStart = store.get('composeSelectionStart') let {
let searchText = store.get('composeAutosuggestionSearchText') composeSelectionStart,
let selection = store.get('composeAutosuggestionSelected') || 0 composeAutosuggestionSearchText,
let emoji = store.get('composeAutosuggestionSearchResults')[selection] composeAutosuggestionSelected,
let startIndex = selectionStart - searchText.length composeAutosuggestionSearchResults
let endIndex = selectionStart } = store.get()
composeAutosuggestionSelected = composeAutosuggestionSelected || 0
let emoji = composeAutosuggestionSearchResults[composeAutosuggestionSelected]
let startIndex = composeSelectionStart - composeAutosuggestionSearchText.length
let endIndex = composeSelectionStart
await insertEmojiAtPosition(realm, emoji, startIndex, endIndex) await insertEmojiAtPosition(realm, emoji, startIndex, endIndex)
} }

View File

@ -6,22 +6,22 @@ import {
} from '../_database/timelines/updateStatus' } from '../_database/timelines/updateStatus'
export async function setFavorited (statusId, favorited) { export async function setFavorited (statusId, favorited) {
if (!store.get('online')) { let { online } = store.get()
if (!online) {
toast.say(`You cannot ${favorited ? 'favorite' : 'unfavorite'} while offline.`) toast.say(`You cannot ${favorited ? 'favorite' : 'unfavorite'} while offline.`)
return return
} }
let instanceName = store.get('currentInstance') let { currentInstance, accessToken } = store.get()
let accessToken = store.get('accessToken')
let networkPromise = favorited let networkPromise = favorited
? favoriteStatus(instanceName, accessToken, statusId) ? favoriteStatus(currentInstance, accessToken, statusId)
: unfavoriteStatus(instanceName, accessToken, statusId) : unfavoriteStatus(currentInstance, accessToken, statusId)
store.setStatusFavorited(instanceName, statusId, favorited) // optimistic update store.setStatusFavorited(currentInstance, statusId, favorited) // optimistic update
try { try {
await networkPromise await networkPromise
await setStatusFavoritedInDatabase(instanceName, statusId, favorited) await setStatusFavoritedInDatabase(currentInstance, statusId, favorited)
} catch (e) { } catch (e) {
console.error(e) console.error(e)
toast.say(`Failed to ${favorited ? 'favorite' : 'unfavorite'}. ` + (e.message || '')) toast.say(`Failed to ${favorited ? 'favorite' : 'unfavorite'}. ` + (e.message || ''))
store.setStatusFavorited(instanceName, statusId, !favorited) // undo optimistic update store.setStatusFavorited(currentInstance, statusId, !favorited) // undo optimistic update
} }
} }

View File

@ -7,17 +7,16 @@ import {
} from '../_database/accountsAndRelationships' } from '../_database/accountsAndRelationships'
export async function setAccountFollowed (accountId, follow, toastOnSuccess) { export async function setAccountFollowed (accountId, follow, toastOnSuccess) {
let instanceName = store.get('currentInstance') let { currentInstance, accessToken } = store.get()
let accessToken = store.get('accessToken')
try { try {
let account let account
if (follow) { if (follow) {
account = await followAccount(instanceName, accessToken, accountId) account = await followAccount(currentInstance, accessToken, accountId)
} else { } else {
account = await unfollowAccount(instanceName, accessToken, accountId) account = await unfollowAccount(currentInstance, accessToken, accountId)
} }
await updateProfileAndRelationship(accountId) await updateProfileAndRelationship(accountId)
let relationship = await getRelationshipFromDatabase(instanceName, accountId) let relationship = await getRelationshipFromDatabase(currentInstance, accountId)
if (toastOnSuccess) { if (toastOnSuccess) {
if (follow) { if (follow) {
if (account.locked && relationship.requested) { if (account.locked && relationship.requested) {

View File

@ -14,17 +14,18 @@ import {
} from '../_database/meta' } from '../_database/meta'
export function changeTheme (instanceName, newTheme) { export function changeTheme (instanceName, newTheme) {
let instanceThemes = store.get('instanceThemes') let { instanceThemes } = store.get()
instanceThemes[instanceName] = newTheme instanceThemes[instanceName] = newTheme
store.set({instanceThemes: instanceThemes}) store.set({instanceThemes: instanceThemes})
store.save() store.save()
if (instanceName === store.get('currentInstance')) { let { currentInstance } = store.get()
if (instanceName === currentInstance) {
switchToTheme(newTheme) switchToTheme(newTheme)
} }
} }
export function switchToInstance (instanceName) { export function switchToInstance (instanceName) {
let instanceThemes = store.get('instanceThemes') let { instanceThemes } = store.get()
store.set({ store.set({
currentInstance: instanceName, currentInstance: instanceName,
searchResults: null, searchResults: null,
@ -35,11 +36,13 @@ export function switchToInstance (instanceName) {
} }
export async function logOutOfInstance (instanceName) { export async function logOutOfInstance (instanceName) {
let loggedInInstances = store.get('loggedInInstances') let {
let instanceThemes = store.get('instanceThemes') loggedInInstances,
let loggedInInstancesInOrder = store.get('loggedInInstancesInOrder') instanceThemes,
let composeData = store.get('composeData') loggedInInstancesInOrder,
let currentInstance = store.get('currentInstance') composeData,
currentInstance
} = store.get()
loggedInInstancesInOrder.splice(loggedInInstancesInOrder.indexOf(instanceName), 1) loggedInInstancesInOrder.splice(loggedInInstancesInOrder.indexOf(instanceName), 1)
let newInstance = instanceName === currentInstance let newInstance = instanceName === currentInstance
? loggedInInstancesInOrder[0] ? loggedInInstancesInOrder[0]
@ -64,13 +67,13 @@ export async function logOutOfInstance (instanceName) {
} }
function setStoreVerifyCredentials (instanceName, thisVerifyCredentials) { function setStoreVerifyCredentials (instanceName, thisVerifyCredentials) {
let verifyCredentials = store.get('verifyCredentials') let { verifyCredentials } = store.get()
verifyCredentials[instanceName] = thisVerifyCredentials verifyCredentials[instanceName] = thisVerifyCredentials
store.set({verifyCredentials: verifyCredentials}) store.set({verifyCredentials: verifyCredentials})
} }
export async function updateVerifyCredentialsForInstance (instanceName) { export async function updateVerifyCredentialsForInstance (instanceName) {
let loggedInInstances = store.get('loggedInInstances') let { loggedInInstances } = store.get()
let accessToken = loggedInInstances[instanceName].access_token let accessToken = loggedInInstances[instanceName].access_token
await cacheFirstUpdateAfter( await cacheFirstUpdateAfter(
() => getVerifyCredentials(instanceName, accessToken), () => getVerifyCredentials(instanceName, accessToken),
@ -81,7 +84,8 @@ export async function updateVerifyCredentialsForInstance (instanceName) {
} }
export async function updateVerifyCredentialsForCurrentInstance () { export async function updateVerifyCredentialsForCurrentInstance () {
await updateVerifyCredentialsForInstance(store.get('currentInstance')) let { currentInstance } = store.get()
await updateVerifyCredentialsForInstance(currentInstance)
} }
export async function updateInstanceInfo (instanceName) { export async function updateInstanceInfo (instanceName) {
@ -90,7 +94,7 @@ export async function updateInstanceInfo (instanceName) {
() => getInstanceInfoFromDatabase(instanceName), () => getInstanceInfoFromDatabase(instanceName),
info => setInstanceInfoInDatabase(instanceName, info), info => setInstanceInfoInDatabase(instanceName, info),
info => { info => {
let instanceInfos = store.get('instanceInfos') let { instanceInfos } = store.get()
instanceInfos[instanceName] = info instanceInfos[instanceName] = info
store.set({instanceInfos: instanceInfos}) store.set({instanceInfos: instanceInfos})
} }

View File

@ -7,16 +7,15 @@ import {
} from '../_database/meta' } from '../_database/meta'
export async function updateLists () { export async function updateLists () {
let instanceName = store.get('currentInstance') let { currentInstance, accessToken } = store.get()
let accessToken = store.get('accessToken')
await cacheFirstUpdateAfter( await cacheFirstUpdateAfter(
() => getLists(instanceName, accessToken), () => getLists(currentInstance, accessToken),
() => getListsFromDatabase(instanceName), () => getListsFromDatabase(currentInstance),
lists => setListsInDatabase(instanceName, lists), lists => setListsInDatabase(currentInstance, lists),
lists => { lists => {
let instanceLists = store.get('instanceLists') let { instanceLists } = store.get()
instanceLists[instanceName] = lists instanceLists[currentInstance] = lists
store.set({instanceLists: instanceLists}) store.set({instanceLists: instanceLists})
} }
) )

View File

@ -4,11 +4,10 @@ import { toast } from '../_utils/toast'
import { scheduleIdleTask } from '../_utils/scheduleIdleTask' import { scheduleIdleTask } from '../_utils/scheduleIdleTask'
export async function doMediaUpload (realm, file) { export async function doMediaUpload (realm, file) {
let instanceName = store.get('currentInstance') let { currentInstance, accessToken } = store.get()
let accessToken = store.get('accessToken')
store.set({uploadingMedia: true}) store.set({uploadingMedia: true})
try { try {
let response = await uploadMedia(instanceName, accessToken, file) let response = await uploadMedia(currentInstance, accessToken, file)
let composeMedia = store.getComposeData(realm, 'media') || [] let composeMedia = store.getComposeData(realm, 'media') || []
composeMedia.push({ composeMedia.push({
data: response, data: response,

View File

@ -4,13 +4,12 @@ import { toast } from '../_utils/toast'
import { updateProfileAndRelationship } from './accounts' import { updateProfileAndRelationship } from './accounts'
export async function setAccountMuted (accountId, mute, toastOnSuccess) { export async function setAccountMuted (accountId, mute, toastOnSuccess) {
let instanceName = store.get('currentInstance') let { currentInstance, accessToken } = store.get()
let accessToken = store.get('accessToken')
try { try {
if (mute) { if (mute) {
await muteAccount(instanceName, accessToken, accountId) await muteAccount(currentInstance, accessToken, accountId)
} else { } else {
await unmuteAccount(instanceName, accessToken, accountId) await unmuteAccount(currentInstance, accessToken, accountId)
} }
await updateProfileAndRelationship(accountId) await updateProfileAndRelationship(accountId)
if (toastOnSuccess) { if (toastOnSuccess) {

View File

@ -9,18 +9,17 @@ import {
} from '../_api/pinnedStatuses' } from '../_api/pinnedStatuses'
export async function updatePinnedStatusesForAccount (accountId) { export async function updatePinnedStatusesForAccount (accountId) {
let instanceName = store.get('currentInstance') let { currentInstance, accessToken } = store.get()
let accessToken = store.get('accessToken')
await cacheFirstUpdateAfter( await cacheFirstUpdateAfter(
() => getPinnedStatuses(instanceName, accessToken, accountId), () => getPinnedStatuses(currentInstance, accessToken, accountId),
() => getPinnedStatusesFromDatabase(instanceName, accountId), () => getPinnedStatusesFromDatabase(currentInstance, accountId),
statuses => insertPinnedStatusesInDatabase(instanceName, accountId, statuses), statuses => insertPinnedStatusesInDatabase(currentInstance, accountId, statuses),
statuses => { statuses => {
let $pinnedStatuses = store.get('pinnedStatuses') let { pinnedStatuses } = store.get()
$pinnedStatuses[instanceName] = $pinnedStatuses[instanceName] || {} pinnedStatuses[currentInstance] = pinnedStatuses[currentInstance] || {}
$pinnedStatuses[instanceName][accountId] = statuses pinnedStatuses[currentInstance][accountId] = statuses
store.set({pinnedStatuses: $pinnedStatuses}) store.set({pinnedStatuses: pinnedStatuses})
} }
) )
} }

View File

@ -4,22 +4,22 @@ import { reblogStatus, unreblogStatus } from '../_api/reblog'
import { setStatusReblogged as setStatusRebloggedInDatabase } from '../_database/timelines/updateStatus' import { setStatusReblogged as setStatusRebloggedInDatabase } from '../_database/timelines/updateStatus'
export async function setReblogged (statusId, reblogged) { export async function setReblogged (statusId, reblogged) {
if (!store.get('online')) { let online = store.get()
if (!online) {
toast.say(`You cannot ${reblogged ? 'boost' : 'unboost'} while offline.`) toast.say(`You cannot ${reblogged ? 'boost' : 'unboost'} while offline.`)
return return
} }
let instanceName = store.get('currentInstance') let { currentInstance, accessToken } = store.get()
let accessToken = store.get('accessToken')
let networkPromise = reblogged let networkPromise = reblogged
? reblogStatus(instanceName, accessToken, statusId) ? reblogStatus(currentInstance, accessToken, statusId)
: unreblogStatus(instanceName, accessToken, statusId) : unreblogStatus(currentInstance, accessToken, statusId)
store.setStatusReblogged(instanceName, statusId, reblogged) // optimistic update store.setStatusReblogged(currentInstance, statusId, reblogged) // optimistic update
try { try {
await networkPromise await networkPromise
await setStatusRebloggedInDatabase(instanceName, statusId, reblogged) await setStatusRebloggedInDatabase(currentInstance, statusId, reblogged)
} catch (e) { } catch (e) {
console.error(e) console.error(e)
toast.say(`Failed to ${reblogged ? 'boost' : 'unboost'}. ` + (e.message || '')) toast.say(`Failed to ${reblogged ? 'boost' : 'unboost'}. ` + (e.message || ''))
store.setStatusReblogged(instanceName, statusId, !reblogged) // undo optimistic update store.setStatusReblogged(currentInstance, statusId, !reblogged) // undo optimistic update
} }
} }

View File

@ -3,14 +3,12 @@ import { toast } from '../_utils/toast'
import { search } from '../_api/search' import { search } from '../_api/search'
export async function doSearch () { export async function doSearch () {
let instanceName = store.get('currentInstance') let { currentInstance, accessToken, queryInSearch } = store.get()
let accessToken = store.get('accessToken')
let queryInSearch = store.get('queryInSearch')
store.set({searchLoading: true}) store.set({searchLoading: true})
try { try {
let results = await search(instanceName, accessToken, queryInSearch) let results = await search(currentInstance, accessToken, queryInSearch)
let currentQueryInSearch = store.get('queryInSearch') // avoid race conditions let { queryInSearch: newQueryInSearch } = store.get() // avoid race conditions
if (currentQueryInSearch === queryInSearch) { if (newQueryInSearch === queryInSearch) {
store.set({ store.set({
searchResultsForQuery: queryInSearch, searchResultsForQuery: queryInSearch,
searchResults: results searchResults: results

View File

@ -60,14 +60,16 @@ export async function addTimelineItemIds (instanceName, timelineName, newIds, ne
async function fetchTimelineItemsAndPossiblyFallBack () { async function fetchTimelineItemsAndPossiblyFallBack () {
mark('fetchTimelineItemsAndPossiblyFallBack') mark('fetchTimelineItemsAndPossiblyFallBack')
let timelineName = store.get('currentTimeline') let {
let instanceName = store.get('currentInstance') currentTimeline,
let accessToken = store.get('accessToken') currentInstance,
let lastTimelineItemId = store.get('lastTimelineItemId') accessToken,
let online = store.get('online') lastTimelineItemId,
online
} = store.get()
let { items, stale } = await fetchTimelineItems(instanceName, accessToken, timelineName, lastTimelineItemId, online) let { items, stale } = await fetchTimelineItems(currentInstance, accessToken, currentTimeline, lastTimelineItemId, online)
addTimelineItems(instanceName, timelineName, items, stale) addTimelineItems(currentInstance, currentTimeline, items, stale)
stop('fetchTimelineItemsAndPossiblyFallBack') stop('fetchTimelineItemsAndPossiblyFallBack')
} }
@ -77,10 +79,11 @@ export async function setupTimeline () {
// (i.e. via offline mode), then we need to re-fetch // (i.e. via offline mode), then we need to re-fetch
// Also do this if it's a thread, because threads change pretty frequently and // Also do this if it's a thread, because threads change pretty frequently and
// we don't have a good way to update them. // we don't have a good way to update them.
let {
let timelineItemIds = store.get('timelineItemIds') timelineItemIds,
let timelineItemIdsAreStale = store.get('timelineItemIdsAreStale') timelineItemIdsAreStale,
let currentTimeline = store.get('currentTimeline') currentTimeline
} = store.get()
if (!timelineItemIds || if (!timelineItemIds ||
timelineItemIdsAreStale || timelineItemIdsAreStale ||
currentTimeline.startsWith('status/')) { currentTimeline.startsWith('status/')) {
@ -109,9 +112,10 @@ export async function showMoreItemsForTimeline (instanceName, timelineName) {
} }
export async function showMoreItemsForCurrentTimeline () { export async function showMoreItemsForCurrentTimeline () {
let { currentInstance, currentTimeline } = store.get()
return showMoreItemsForTimeline( return showMoreItemsForTimeline(
store.get('currentInstance'), currentInstance,
store.get('currentTimeline') currentTimeline
) )
} }

View File

@ -34,7 +34,7 @@
export default { export default {
async oncreate() { async oncreate() {
let accountsFetcher = this.get('accountsFetcher') let { accountsFetcher } = this.get()
try { try {
// TODO: paginate // TODO: paginate
let accounts = await accountsFetcher() let accounts = await accountsFetcher()

View File

@ -107,7 +107,8 @@
export default { export default {
oncreate() { oncreate() {
this.observe('animation', animation => { this.observe('animation', animation => {
if (!animation || this.store.get('reduceMotion')) { let reduceMotion = this.store.get()
if (!animation || reduceMotion) {
return return
} }
let svg = this.refs.svg let svg = this.refs.svg

View File

@ -28,8 +28,8 @@
oncreate() { oncreate() {
mark('LazyImage oncreate()') mark('LazyImage oncreate()')
let img = new Image() let img = new Image()
let src = this.get('src') let { src } = this.get()
let fallback = this.get('fallback') let { fallback } = this.get()
img.onload = () => { img.onload = () => {
requestAnimationFrame(() => { requestAnimationFrame(() => {
this.set({ this.set({

View File

@ -136,7 +136,8 @@
}, },
methods: { methods: {
onClick(e) { onClick(e) {
if (!this.get('selected')) { let { selected } = this.get()
if (!selected) {
return return
} }
e.preventDefault() e.preventDefault()

View File

@ -28,11 +28,8 @@
export default { export default {
methods: { methods: {
onMouseOver(mouseOver) { onMouseOver(mouseOver) {
if (mouseOver) { let { src, staticSrc } = this.get()
this.refs.node.src = this.get('src') this.refs.node.src = mouseOver ? src : staticSrc
} else {
this.refs.node.src = this.get('staticSrc')
}
} }
}, },
events: { events: {

View File

@ -75,9 +75,8 @@
methods: { methods: {
onPinClick(e) { onPinClick(e) {
e.preventDefault() e.preventDefault()
let currentInstance = this.store.get('currentInstance') let { currentInstance, pinnedPages } = this.store.get()
let pinnedPages = this.store.get('pinnedPages') let { href } = this.get()
let href = this.get('href')
pinnedPages[currentInstance] = href pinnedPages[currentInstance] = href
this.store.set({pinnedPages: pinnedPages}) this.store.set({pinnedPages: pinnedPages})
this.store.save() this.store.save()

View File

@ -59,13 +59,15 @@
// perf improves for input responsiveness // perf improves for input responsiveness
this.observe('composeSelectionStart', () => { this.observe('composeSelectionStart', () => {
scheduleIdleTask(() => { scheduleIdleTask(() => {
this.set({composeSelectionStartDeferred: this.get('composeSelectionStart')}) let { composeSelectionStart } = this.get() || {} // TODO: wtf svelte?
this.set({composeSelectionStartDeferred: composeSelectionStart})
}) })
}) })
this.observe('composeFocused', (composeFocused) => { this.observe('composeFocused', (composeFocused) => {
let updateFocusedState = () => { let updateFocusedState = () => {
scheduleIdleTask(() => { scheduleIdleTask(() => {
this.set({composeFocusedDeferred: this.get('composeFocused')}) let { composeFocused } = this.get() || {} // TODO: wtf svelte?
this.set({composeFocusedDeferred: composeFocused})
}) })
} }
@ -103,11 +105,10 @@
once: once, once: once,
onClick(item) { onClick(item) {
this.fire('autosuggestItemSelected') this.fire('autosuggestItemSelected')
let realm = this.get('realm') let { realm } = this.get()
let selectionStart = this.store.get('composeSelectionStart') let { composeSelectionStart, composeAutosuggestionSearchText } = this.store.get()
let searchText = this.store.get('composeAutosuggestionSearchText') let startIndex = composeSelectionStart - composeAutosuggestionSearchText.length
let startIndex = selectionStart - searchText.length let endIndex = composeSelectionStart
let endIndex = selectionStart
if (item.acct) { if (item.acct) {
/* no await */ insertUsername(realm, item.acct, startIndex, endIndex) /* no await */ insertUsername(realm, item.acct, startIndex, endIndex)
} else { } else {
@ -117,15 +118,15 @@
}, },
async searchAccounts(searchText) { async searchAccounts(searchText) {
searchText = searchText.substring(1) searchText = searchText.substring(1)
let currentInstance = this.store.get('currentInstance') let { currentInstance } = this.store.get()
let results = await searchAccountsByUsernameInDatabase( let results = await searchAccountsByUsernameInDatabase(
currentInstance, searchText, DATABASE_SEARCH_RESULTS_LIMIT) currentInstance, searchText, DATABASE_SEARCH_RESULTS_LIMIT)
return results.slice(0, SEARCH_RESULTS_LIMIT) return results.slice(0, SEARCH_RESULTS_LIMIT)
}, },
searchEmoji(searchText) { searchEmoji(searchText) {
searchText = searchText.toLowerCase().substring(1) searchText = searchText.toLowerCase().substring(1)
let customEmoji = this.store.get('currentCustomEmoji') let { currentCustomEmoji } = this.store.get()
let results = customEmoji.filter(emoji => emoji.shortcode.toLowerCase().startsWith(searchText)) let results = currentCustomEmoji.filter(emoji => emoji.shortcode.toLowerCase().startsWith(searchText))
.sort((a, b) => a.shortcode.toLowerCase() < b.shortcode.toLowerCase() ? -1 : 1) .sort((a, b) => a.shortcode.toLowerCase() < b.shortcode.toLowerCase() ? -1 : 1)
.slice(0, SEARCH_RESULTS_LIMIT) .slice(0, SEARCH_RESULTS_LIMIT)
return results return results

View File

@ -118,7 +118,7 @@
export default { export default {
oncreate() { oncreate() {
let realm = this.get('realm') let { realm } = this.get()
if (realm === 'home') { if (realm === 'home') {
this.setupStickyObserver() this.setupStickyObserver()
} else if (realm !== 'dialog') { } else if (realm !== 'dialog') {
@ -126,13 +126,13 @@
insertHandleForReply(realm) insertHandleForReply(realm)
} }
let replySpoiler = this.get('replySpoiler') let { replySpoiler } = this.get()
if (replySpoiler) { if (replySpoiler) {
// default spoiler is same as the replied-to status // default spoiler is same as the replied-to status
setReplySpoiler(realm, replySpoiler) setReplySpoiler(realm, replySpoiler)
} }
let replyVisibility = this.get('replyVisibility') let { replyVisibility } = this.get()
if (replyVisibility) { if (replyVisibility) {
// make sure the visibility is consistent with the replied-to status // make sure the visibility is consistent with the replied-to status
setReplyVisibility(realm, replyVisibility) setReplyVisibility(realm, replyVisibility)
@ -189,7 +189,8 @@
}, },
methods: { methods: {
async onClickPostButton() { async onClickPostButton() {
if (this.get('sticky')) { let { sticky } = this.get()
if (sticky) {
// when the button is sticky, we're scrolled down the home timeline, // when the button is sticky, we're scrolled down the home timeline,
// so we should launch a new compose dialog // so we should launch a new compose dialog
let dialogs = await importDialogs() let dialogs = await importDialogs()
@ -200,17 +201,19 @@
} }
}, },
doPostStatus() { doPostStatus() {
let text = this.get('text') let {
let media = this.get('media') text,
let postPrivacyKey = this.get('postPrivacyKey') media,
let contentWarning = this.get('contentWarning') postPrivacyKey,
contentWarning,
realm,
overLimit,
mediaDescriptions,
inReplyToUuid
} = this.get()
let sensitive = media.length && !!contentWarning let sensitive = media.length && !!contentWarning
let realm = this.get('realm')
let mediaIds = media.map(_ => _.data.id) let mediaIds = media.map(_ => _.data.id)
let inReplyTo = (realm === 'home' || realm === 'dialog') ? null : realm let inReplyTo = (realm === 'home' || realm === 'dialog') ? null : realm
let overLimit = this.get('overLimit')
let mediaDescriptions = this.get('mediaDescriptions')
let inReplyToUuid = this.get('inReplyToUuid')
if (!text || overLimit) { if (!text || overLimit) {
return // do nothing if invalid return // do nothing if invalid

View File

@ -37,7 +37,8 @@
const saveText = debounce(() => scheduleIdleTask(() => this.store.save()), 1000) const saveText = debounce(() => scheduleIdleTask(() => this.store.save()), 1000)
this.observe('rawText', rawText => { this.observe('rawText', rawText => {
this.store.setComposeData(this.get('realm'), { let { realm } = this.get()
this.store.setComposeData(realm, {
contentWarning: rawText contentWarning: rawText
}) })
saveText() saveText()

View File

@ -50,7 +50,8 @@
let textarea = this.refs.textarea let textarea = this.refs.textarea
let firstTime = true let firstTime = true
this.observe('text', text => { this.observe('text', text => {
if (this.get('rawText') !== text) { let { rawText } = this.get()
if (rawText !== text) {
this.set({rawText: text}) this.set({rawText: text})
// this next autosize is required to resize after // this next autosize is required to resize after
// the user clicks the "toot" button // the user clicks the "toot" button
@ -60,7 +61,8 @@
} }
if (firstTime) { if (firstTime) {
firstTime = false firstTime = false
if (this.get('autoFocus')) { let { autoFocus } = this.get()
if (autoFocus) {
requestAnimationFrame(() => textarea.focus()) requestAnimationFrame(() => textarea.focus())
} }
} }
@ -71,7 +73,7 @@
this.observe('rawText', rawText => { this.observe('rawText', rawText => {
mark('observe rawText') mark('observe rawText')
let realm = this.get('realm') let { realm } = this.get()
this.store.setComposeData(realm, {text: rawText}) this.store.setComposeData(realm, {text: rawText})
saveStore() saveStore()
stop('observe rawText') stop('observe rawText')
@ -126,27 +128,34 @@
} }
}, },
clickSelectedAutosuggestion(event) { clickSelectedAutosuggestion(event) {
let autosuggestionShown = this.store.get('composeAutosuggestionShown') let {
if (!autosuggestionShown) { composeAutosuggestionShown,
composeAutosuggestionType
} = this.store.get()
if (!composeAutosuggestionShown) {
return false return false
} }
let type = this.store.get('composeAutosuggestionType') let { realm } = this.get()
if (type === 'account') { if (composeAutosuggestionType === 'account') {
/* no await */ clickSelectedAutosuggestionUsername(this.get('realm')) /* no await */ clickSelectedAutosuggestionUsername(realm)
} else { // emoji } else { // emoji
/* no await */ clickSelectedAutosuggestionEmoji(this.get('realm')) /* no await */ clickSelectedAutosuggestionEmoji(realm)
} }
event.preventDefault() event.preventDefault()
event.stopPropagation() event.stopPropagation()
return true return true
}, },
incrementAutosuggestSelected(increment, event) { incrementAutosuggestSelected(increment, event) {
let autosuggestionShown = this.store.get('composeAutosuggestionShown') let {
if (!autosuggestionShown) { composeAutosuggestionShown,
composeAutosuggestionSelected,
composeAutosuggestionSearchResults
} = this.store.get()
if (!composeAutosuggestionShown) {
return return
} }
let selected = this.store.get('composeAutosuggestionSelected') || 0 let selected = composeAutosuggestionSelected || 0
let searchResults = this.store.get('composeAutosuggestionSearchResults') || [] let searchResults = composeAutosuggestionSearchResults || []
selected += increment selected += increment
if (selected >= 0) { if (selected >= 0) {
selected = selected % searchResults.length selected = selected % searchResults.length
@ -158,8 +167,8 @@
event.stopPropagation() event.stopPropagation()
}, },
clearAutosuggestions(event) { clearAutosuggestions(event) {
let autosuggestionShown = this.store.get('composeAutosuggestionShown') let { composeAutosuggestionShown } = this.store.get()
if (!autosuggestionShown) { if (!composeAutosuggestionShown) {
return return
} }
this.store.set({ this.store.set({

View File

@ -25,12 +25,14 @@
export default { export default {
oncreate() { oncreate() {
this.set({lengthAsFractionDeferred: this.get('lengthAsFraction')}) let { lengthAsFraction } = this.get()
this.set({lengthAsFractionDeferred: lengthAsFraction})
// perf improvement for keyboard input latency // perf improvement for keyboard input latency
this.observe('lengthAsFraction', () => { this.observe('lengthAsFraction', () => {
scheduleIdleTask(() => { scheduleIdleTask(() => {
mark('set lengthAsFractionDeferred') mark('set lengthAsFractionDeferred')
this.set({lengthAsFractionDeferred: this.get('lengthAsFraction')}) let { lengthAsFraction } = this.get() || {} // TODO: wtf svelte?
this.set({lengthAsFractionDeferred: lengthAsFraction})
stop('set lengthAsFractionDeferred') stop('set lengthAsFractionDeferred')
requestAnimationFrame(() => this.set({shouldAnimate: true})) requestAnimationFrame(() => this.set({shouldAnimate: true}))
}) })

View File

@ -23,12 +23,14 @@
export default { export default {
oncreate() { oncreate() {
this.set({lengthToDisplayDeferred: this.get('lengthToDisplay')}) let { lengthToDisplay } = this.get()
this.set({lengthToDisplayDeferred: lengthToDisplay})
// perf improvement for keyboard input latency // perf improvement for keyboard input latency
this.observe('lengthToDisplay', () => { this.observe('lengthToDisplay', () => {
scheduleIdleTask(() => { scheduleIdleTask(() => {
mark('set lengthToDisplayDeferred') mark('set lengthToDisplayDeferred')
this.set({lengthToDisplayDeferred: this.get('lengthToDisplay')}) let { lengthToDisplay } = this.get() || {} // TODO: wtf svelte?
this.set({lengthToDisplayDeferred: lengthToDisplay})
stop('set lengthToDisplayDeferred') stop('set lengthToDisplayDeferred')
}) })
}, {init: false}) }, {init: false})

View File

@ -93,9 +93,9 @@
setupSyncFromStore() { setupSyncFromStore() {
this.observe('mediaDescriptions', mediaDescriptions => { this.observe('mediaDescriptions', mediaDescriptions => {
mediaDescriptions = mediaDescriptions || [] mediaDescriptions = mediaDescriptions || []
let index = this.get('index') let { index, rawText } = this.get()
let text = mediaDescriptions[index] || '' let text = mediaDescriptions[index] || ''
if (this.get('rawText') !== text) { if (rawText !== text) {
this.set({rawText: text}) this.set({rawText: text})
} }
}) })
@ -104,8 +104,8 @@
const saveStore = debounce(() => scheduleIdleTask(() => this.store.save()), 1000) const saveStore = debounce(() => scheduleIdleTask(() => this.store.save()), 1000)
this.observe('rawText', rawText => { this.observe('rawText', rawText => {
let realm = this.get('realm') let { realm } = this.get()
let index = this.get('index') let { index } = this.get()
let mediaDescriptions = store.getComposeData(realm, 'mediaDescriptions') || [] let mediaDescriptions = store.getComposeData(realm, 'mediaDescriptions') || []
if (mediaDescriptions[index] === rawText) { if (mediaDescriptions[index] === rawText) {
return return
@ -119,7 +119,11 @@
}, {init: false}) }, {init: false})
}, },
onDeleteMedia() { onDeleteMedia() {
deleteMedia(this.get('realm'), this.get('index')) let {
realm,
index
} = this.get()
deleteMedia(realm, index)
} }
} }
} }

View File

@ -71,22 +71,25 @@
methods: { methods: {
async onEmojiClick() { async onEmojiClick() {
let dialogs = await importDialogs() let dialogs = await importDialogs()
dialogs.showEmojiDialog(this.get('realm')) let { realm } = this.get()
dialogs.showEmojiDialog(realm)
}, },
onMediaClick() { onMediaClick() {
this.refs.input.click() this.refs.input.click()
}, },
onFileChange(e) { onFileChange(e) {
let file = e.target.files[0] let file = e.target.files[0]
let realm = this.get('realm') let { realm } = this.get()
doMediaUpload(realm, file) doMediaUpload(realm, file)
}, },
async onPostPrivacyClick() { async onPostPrivacyClick() {
let dialogs = await importDialogs() let dialogs = await importDialogs()
dialogs.showPostPrivacyDialog(this.get('realm')) let { realm } = this.get()
dialogs.showPostPrivacyDialog(realm)
}, },
onContentWarningClick() { onContentWarningClick() {
toggleContentWarningShown(this.get('realm')) let { realm } = this.get()
toggleContentWarningShown(realm)
} }
} }
} }

View File

@ -99,7 +99,7 @@ export default {
} }
}, },
async onMentionClicked() { async onMentionClicked() {
let acct = this.get('acct') let { acct } = this.get()
this.store.setComposeData('dialog', { this.store.setComposeData('dialog', {
text: `@${acct} ` text: `@${acct} `
}) })
@ -108,21 +108,17 @@ export default {
this.close() this.close()
}, },
async onFollowClicked() { async onFollowClicked() {
let accountId = this.get('accountId') let { accountId, following } = this.get()
let following = this.get('following')
this.close() this.close()
await setAccountFollowed(accountId, !following, true) await setAccountFollowed(accountId, !following, true)
}, },
async onBlockClicked() { async onBlockClicked() {
let account = this.get('account') let { accountId, blocking } = this.get()
let blocking = this.get('blocking')
let accountId = account.id
this.close() this.close()
await setAccountBlocked(accountId, !blocking, true) await setAccountBlocked(accountId, !blocking, true)
}, },
async onMuteClicked() { async onMuteClicked() {
let accountId = this.get('accountId') let { accountId, muting } = this.get()
let muting = this.get('muting')
this.close() this.close()
await setAccountMuted(accountId, !muting, true) await setAccountMuted(accountId, !muting, true)
} }

View File

@ -47,17 +47,23 @@
methods: { methods: {
show, show,
close, close,
onDestroyDialog(id) { onDestroyDialog(thisId) {
if (id !== this.get('id')) { let {
id,
positiveResult,
onPositive,
onNegative
} = this.get()
if (thisId !== id) {
return return
} }
if (this.get('positiveResult')) { if (positiveResult) {
if (this.get('onPositive')) { if (onPositive) {
this.get('onPositive')() onPositive()
} }
} else { } else {
if (this.get('onNegative')) { if (onNegative) {
this.get('onNegative')() onNegative()
} }
} }
}, },

View File

@ -82,7 +82,8 @@
show, show,
close, close,
onClickEmoji(emoji) { onClickEmoji(emoji) {
insertEmoji(this.get('realm'), emoji) let { realm } = this.get()
insertEmoji(realm, emoji)
this.close() this.close()
} }
} }

View File

@ -132,7 +132,8 @@
this._a11yDialog = new A11yDialog(dialogElement) this._a11yDialog = new A11yDialog(dialogElement)
this._a11yDialog.on('hide', () => { this._a11yDialog.on('hide', () => {
this._a11yDialog.destroy() this._a11yDialog.destroy()
emit('destroyDialog', this.get('id')) let { id } = this.get()
emit('destroyDialog', id)
requestAnimationFrame(() => document.body.removeChild(dialogElement)) requestAnimationFrame(() => document.body.removeChild(dialogElement))
}) })
on('showDialog', this, this.showDialog) on('showDialog', this, this.showDialog)
@ -161,8 +162,9 @@
} }
}, },
methods: { methods: {
showDialog(id) { showDialog(thisId) {
if (this.get('id') !== id) { let { id } = this.get()
if (id !== thisId) {
return return
} }
this._a11yDialog.show() this._a11yDialog.show()
@ -170,8 +172,9 @@
this.set({ fadedIn: true }) this.set({ fadedIn: true })
}) })
}, },
closeDialog(id) { closeDialog(thisId) {
if (this.get('id') !== id) { let { id } = this.get()
if (id !== thisId) {
return return
} }
setTimeout(() => { // use setTimeout to workaround svelte timing issue setTimeout(() => { // use setTimeout to workaround svelte timing issue

View File

@ -30,7 +30,8 @@
show, show,
close, close,
onClick(item) { onClick(item) {
setPostPrivacy(this.get('realm'), item.key) let { realm } = this.get()
setPostPrivacy(realm, item.key)
this.close() this.close()
} }
}, },

View File

@ -102,25 +102,22 @@ export default {
} }
}, },
async onDeleteClicked() { async onDeleteClicked() {
let statusId = this.get('statusId') let { statusId } = this.get()
this.close() this.close()
await doDeleteStatus(statusId) await doDeleteStatus(statusId)
}, },
async onFollowClicked() { async onFollowClicked() {
let accountId = this.get('accountId') let { accountId, following } = this.get()
let following = this.get('following')
this.close() this.close()
await setAccountFollowed(accountId, !following, true) await setAccountFollowed(accountId, !following, true)
}, },
async onBlockClicked() { async onBlockClicked() {
let accountId = this.get('accountId') let { accountId, blocking } = this.get()
let blocking = this.get('blocking')
this.close() this.close()
await setAccountBlocked(accountId, !blocking, true) await setAccountBlocked(accountId, !blocking, true)
}, },
async onMuteClicked() { async onMuteClicked() {
let accountId = this.get('accountId') let { accountId, muting } = this.get()
let muting = this.get('muting')
this.close() this.close()
await setAccountMuted(accountId, !muting, true) await setAccountMuted(accountId, !muting, true)
} }

View File

@ -1,6 +1,6 @@
import { emit } from '../../../_utils/eventBus' import { emit } from '../../../_utils/eventBus'
export function close () { export function close () {
let id = this.get('id') let { id } = this.get()
emit('closeDialog', id) emit('closeDialog', id)
} }

View File

@ -1,7 +1,8 @@
import { on } from '../../../_utils/eventBus' import { on } from '../../../_utils/eventBus'
function onDestroy (id) { function onDestroy (thisId) {
if (this.get('id') !== id) { let { id } = this.get()
if (id !== thisId) {
return return
} }
this.destroy() this.destroy()

View File

@ -1,6 +1,6 @@
import { emit } from '../../../_utils/eventBus' import { emit } from '../../../_utils/eventBus'
export function show () { export function show () {
let id = this.get('id') let { id } = this.get()
emit('showDialog', id) emit('showDialog', id)
} }

View File

@ -121,9 +121,7 @@
}, },
methods: { methods: {
async onMoreOptionsClick() { async onMoreOptionsClick() {
let account = this.get('account') let { account, relationship, verifyCredentials } = this.get()
let relationship = this.get('relationship')
let verifyCredentials = this.get('verifyCredentials')
let dialogs = await importDialogs() let dialogs = await importDialogs()
dialogs.showAccountProfileOptionsDialog(account, relationship, verifyCredentials) dialogs.showAccountProfileOptionsDialog(account, relationship, verifyCredentials)
} }

View File

@ -31,11 +31,13 @@
async onFollowButtonClick(e) { async onFollowButtonClick(e) {
e.preventDefault() e.preventDefault()
e.stopPropagation() e.stopPropagation()
let account = this.get('account') let {
let accountId = this.get('accountId') account,
let following = this.get('following') accountId,
let followRequested = this.get('followRequested') following,
let blocking = this.get('blocking') followRequested,
blocking
} = this.get()
this.set({animateFollowButton: true}) // TODO: this should be an event, not toggling a boolean this.set({animateFollowButton: true}) // TODO: this should be an event, not toggling a boolean
if (blocking) { // unblock if (blocking) { // unblock
await setAccountBlocked(accountId, false) await setAccountBlocked(accountId, false)

View File

@ -28,25 +28,28 @@
export default { export default {
oncreate() { oncreate() {
mark('PseudoVirtualList oncreate()') mark('PseudoVirtualList oncreate()')
this.store.setCurrentRealm(this.get('realm')) let { realm } = this.get()
this.store.setCurrentRealm(realm)
// When re-rendering, assume all items are non-intersecting until told otherwise. // When re-rendering, assume all items are non-intersecting until told otherwise.
// We already have the heights cached. // We already have the heights cached.
let intersectionStates = this.store.get('intersectionStates') let { intersectionStates } = this.store.get()
let keys = Object.keys(intersectionStates) let keys = Object.keys(intersectionStates)
for (let key of keys) { for (let key of keys) {
intersectionStates[key].isCached = true intersectionStates[key].isCached = true
} }
this.store.setForRealm({intersectionStates: intersectionStates}) this.store.setForRealm({intersectionStates: intersectionStates})
let { containerQuery } = this.get()
let intersectionObserver = new IntersectionObserver(this.onIntersection.bind(this), { let intersectionObserver = new IntersectionObserver(this.onIntersection.bind(this), {
root: document.querySelector(this.get('containerQuery')), root: document.querySelector(containerQuery),
rootMargin: '300% 0px' rootMargin: '300% 0px'
}) })
this.set({intersectionObserver}) this.set({intersectionObserver})
this.observe('allItemsHaveHeight', allItemsHaveHeight => { this.observe('allItemsHaveHeight', allItemsHaveHeight => {
console.log('allItemsHaveHeight', allItemsHaveHeight) console.log('allItemsHaveHeight', allItemsHaveHeight)
if (allItemsHaveHeight && !this.get('initialized')) { let { initialized } = this.get()
if (allItemsHaveHeight && !initialized) {
this.set({initialized: true}) this.set({initialized: true})
console.log('initialized PseudoVirtualList') console.log('initialized PseudoVirtualList')
this.fire('initialized') this.fire('initialized')
@ -55,7 +58,7 @@
stop('PseudoVirtualList oncreate()') stop('PseudoVirtualList oncreate()')
}, },
ondestroy() { ondestroy() {
let intersectionObserver = this.get('intersectionObserver') let { intersectionObserver } = this.get()
if (intersectionObserver) { if (intersectionObserver) {
intersectionObserver.disconnect() intersectionObserver.disconnect()
} }
@ -74,7 +77,8 @@
}, },
methods: { methods: {
scrollToPosition(element) { scrollToPosition(element) {
if (this.get('scrolledToPosition')) { let { scrolledToPosition } = this.get()
if (scrolledToPosition) {
return return
} }
this.set({scrolledToPosition: true}) this.set({scrolledToPosition: true})
@ -86,8 +90,8 @@
onIntersection(entries) { onIntersection(entries) {
mark('onIntersection') mark('onIntersection')
let newIntersectionStates = {} let newIntersectionStates = {}
let scrollToItem = this.get('scrollToItem') let { scrollToItem } = this.get()
let intersectionStates = this.store.get('intersectionStates') let { intersectionStates } = this.store.get()
for (let entry of entries) { for (let entry of entries) {
let key = entry.target.getAttribute('pseudo-virtual-list-key') let key = entry.target.getAttribute('pseudo-virtual-list-key')
let rect = getRectFromEntry(entry) let rect = getRectFromEntry(entry)

View File

@ -12,7 +12,6 @@
{{/if}} {{/if}}
</div> </div>
<script> <script>
import { scheduleIdleTask } from '../../_utils/scheduleIdleTask' import { scheduleIdleTask } from '../../_utils/scheduleIdleTask'
import { mark, stop } from '../../_utils/marks' import { mark, stop } from '../../_utils/marks'
@ -27,7 +26,8 @@
// unrender lazily; it's not a critical UI task // unrender lazily; it's not a critical UI task
scheduleIdleTask(() => { scheduleIdleTask(() => {
mark('unrender') mark('unrender')
if (!this.get('isIntersecting')) { let { isIntersecting } = this.get() || {} // TODO: wtf svelte?
if (!isIntersecting) {
this.set({hide: true}) this.set({hide: true})
} }
stop('unrender') stop('unrender')
@ -35,7 +35,7 @@
} }
}) })
let intersectionObserver = this.get('intersectionObserver') let { intersectionObserver } = this.get()
intersectionObserver.observe(this.refs.node) intersectionObserver.observe(this.refs.node)
}, },
computed: { computed: {

View File

@ -19,8 +19,7 @@
async oncreate() { async oncreate() {
// TODO: there appears to be a bug in {{#await}} that means we have to do this manually. // 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. // Some items may appear on top of other items because their offset is 0 and never updated.
let makeProps = this.get('makeProps') let { makeProps, key } = this.get()
let key = this.get('key')
if (makeProps) { if (makeProps) {
let props = await makeProps(key) let props = await makeProps(key)
mark('PseudoVirtualListLazyItem set props') mark('PseudoVirtualListLazyItem set props')

View File

@ -111,8 +111,10 @@
export default { export default {
oncreate() { oncreate() {
registerClickDelegate(this, this.get('delegateKey'), () => { let { delegateKey } = this.get()
if (this.get('media').type === 'video') { registerClickDelegate(this, delegateKey, () => {
let { media } = this.get()
if (media.type === 'video') {
this.onClickPlayVideoButton() this.onClickPlayVideoButton()
} else { } else {
this.onClickShowImageButton() this.onClickShowImageButton()
@ -138,18 +140,16 @@
}, },
methods: { methods: {
async onClickPlayVideoButton() { async onClickPlayVideoButton() {
let media = this.get('media') let { media, modalWidth, modalHeight } = this.get()
let width = this.get('modalWidth')
let height = this.get('modalHeight')
let dialogs = await importDialogs() let dialogs = await importDialogs()
dialogs.showVideoDialog(media.preview_url, media.url, width, height, media.description) dialogs.showVideoDialog(media.preview_url, media.url,
modalWidth, modalHeight, media.description)
}, },
async onClickShowImageButton() { async onClickShowImageButton() {
let media = this.get('media') let { media, modalWidth, modalHeight } = this.get()
let width = this.get('modalWidth')
let height = this.get('modalHeight')
let dialogs = await importDialogs() let dialogs = await importDialogs()
dialogs.showImageDialog(media.preview_url, media.url, media.type, width, height, media.description) dialogs.showImageDialog(media.preview_url, media.url, media.type,
modalWidth, modalHeight, media.description)
} }
}, },
data: () => ({ data: () => ({

View File

@ -123,12 +123,12 @@
export default { export default {
oncreate() { oncreate() {
let delegateKey = this.get('delegateKey') let { delegateKey, isStatusInOwnThread, showContent } = this.get()
if (!this.get('isStatusInOwnThread')) { if (!isStatusInOwnThread) {
// the whole <article> is clickable in this case // the whole <article> is clickable in this case
registerClickDelegate(this, delegateKey, (e) => this.onClickOrKeydown(e)) registerClickDelegate(this, delegateKey, (e) => this.onClickOrKeydown(e))
} }
if (!this.get('showContent')) { if (!showContent) {
scheduleIdleTask(() => { scheduleIdleTask(() => {
// Perf optimization: lazily load the StatusContent when the user is idle so that // Perf optimization: lazily load the StatusContent when the user is idle so that
// it's fast when they click the "show more" button // it's fast when they click the "show more" button
@ -171,7 +171,8 @@
e.preventDefault() e.preventDefault()
e.stopPropagation() e.stopPropagation()
goto(`/statuses/${this.get('originalStatusId')}`) let { originalStatusId } = this.get()
goto(`/statuses/${originalStatusId}`)
} }
}, },
computed: { computed: {

View File

@ -35,14 +35,15 @@
}, },
methods: { methods: {
onPostedStatus(realm) { onPostedStatus(realm) {
if (realm !== this.get('originalStatusId')) { let { originalStatusId } = this.get()
if (realm !== originalStatusId) {
return return
} }
requestAnimationFrame(() => { requestAnimationFrame(() => {
let uuid = this.get('uuid') let { uuid } = this.get()
let $repliesShown = this.store.get('repliesShown') let { repliesShown } = this.store.get()
$repliesShown[uuid] = false repliesShown[uuid] = false
this.store.set({'repliesShown': $repliesShown}) this.store.set({repliesShown})
this.fire('recalculateHeight') this.fire('recalculateHeight')
}) })
}, },

View File

@ -96,8 +96,7 @@
} }
mark('hydrateContent') mark('hydrateContent')
let node = this.refs.node let node = this.refs.node
let originalStatus = this.get('originalStatus') let { originalStatus, uuid } = this.get()
let uuid = this.get('uuid')
let count = 0 let count = 0
let anchors = node.getElementsByTagName('A') let anchors = node.getElementsByTagName('A')
let mentions = originalStatus.mentions let mentions = originalStatus.mentions

View File

@ -130,7 +130,8 @@
export default { export default {
oncreate() { oncreate() {
registerClickDelegate(this, this.get('delegateKey'), () => this.onClickSensitiveMediaButton()) let { delegateKey } = this.get()
registerClickDelegate(this, delegateKey, () => this.onClickSensitiveMediaButton())
}, },
components: { components: {
MediaAttachments MediaAttachments
@ -144,10 +145,10 @@
}, },
methods: { methods: {
onClickSensitiveMediaButton() { onClickSensitiveMediaButton() {
let uuid = this.get('uuid') let { uuid } = this.get()
let $sensitivesShown = this.store.get('sensitivesShown') || {} let { sensitivesShown } = this.store.get()
$sensitivesShown[uuid] = !$sensitivesShown[uuid] sensitivesShown[uuid] = !sensitivesShown[uuid]
this.store.set({'sensitivesShown': $sensitivesShown}) this.store.set({sensitivesShown})
this.fire('recalculateHeight') this.fire('recalculateHeight')
} }
} }

View File

@ -53,7 +53,8 @@
export default { export default {
oncreate() { oncreate() {
registerClickDelegate(this, this.get('delegateKey'), () => this.onClickSpoilerButton()) let { delegateKey } = this.get()
registerClickDelegate(this, delegateKey, () => this.onClickSpoilerButton())
}, },
store: () => store, store: () => store,
computed: { computed: {
@ -69,10 +70,10 @@
onClickSpoilerButton() { onClickSpoilerButton() {
requestAnimationFrame(() => { requestAnimationFrame(() => {
mark('clickSpoilerButton') mark('clickSpoilerButton')
let uuid = this.get('uuid') let { uuid } = this.get()
let $spoilersShown = this.store.get('spoilersShown') let { spoilersShown } = this.store.get()
$spoilersShown[uuid] = !$spoilersShown[uuid] spoilersShown[uuid] = !spoilersShown[uuid]
this.store.set({'spoilersShown': $spoilersShown}) this.store.set({spoilersShown})
this.fire('recalculateHeight') this.fire('recalculateHeight')
stop('clickSpoilerButton') stop('clickSpoilerButton')
}) })

View File

@ -54,11 +54,17 @@
export default { export default {
oncreate() { oncreate() {
let {
favoriteKey,
reblogKey,
replyKey,
optionsKey
} = this.get()
registerClickDelegates(this, { registerClickDelegates(this, {
[this.get('favoriteKey')]: (e) => this.onFavoriteClick(e), [favoriteKey]: (e) => this.onFavoriteClick(e),
[this.get('reblogKey')]: (e) => this.onReblogClick(e), [reblogKey]: (e) => this.onReblogClick(e),
[this.get('replyKey')]: (e) => this.onReplyClick(e), [replyKey]: (e) => this.onReplyClick(e),
[this.get('optionsKey')]: (e) => this.onOptionsClick(e) [optionsKey]: (e) => this.onOptionsClick(e)
}) })
on('postedStatus', this, this.onPostedStatus) on('postedStatus', this, this.onPostedStatus)
}, },
@ -70,16 +76,14 @@
onFavoriteClick(e) { onFavoriteClick(e) {
e.preventDefault() e.preventDefault()
e.stopPropagation() e.stopPropagation()
let originalStatusId = this.get('originalStatusId') let { originalStatusId, favorited } = this.get()
let favorited = this.get('favorited')
/* no await */ setFavorited(originalStatusId, !favorited) /* no await */ setFavorited(originalStatusId, !favorited)
this.set({animateFavorite: !favorited}) this.set({animateFavorite: !favorited})
}, },
onReblogClick(e) { onReblogClick(e) {
e.preventDefault() e.preventDefault()
e.stopPropagation() e.stopPropagation()
let originalStatusId = this.get('originalStatusId') let { originalStatusId, reblogged } = this.get()
let reblogged = this.get('reblogged')
/* no await */ setReblogged(originalStatusId, !reblogged) /* no await */ setReblogged(originalStatusId, !reblogged)
this.set({animateReblog: !reblogged}) this.set({animateReblog: !reblogged})
}, },
@ -87,26 +91,29 @@
e.preventDefault() e.preventDefault()
e.stopPropagation() e.stopPropagation()
requestAnimationFrame(() => { requestAnimationFrame(() => {
let uuid = this.get('uuid') let { uuid } = this.get()
let $repliesShown = this.store.get('repliesShown') let { repliesShown } = this.store.get()
$repliesShown[uuid] = !$repliesShown[uuid] repliesShown[uuid] = !repliesShown[uuid]
this.store.set({'repliesShown': $repliesShown}) this.store.set({repliesShown})
this.fire('recalculateHeight') this.fire('recalculateHeight')
}) })
}, },
async onOptionsClick(e) { async onOptionsClick(e) {
e.preventDefault() e.preventDefault()
e.stopPropagation() e.stopPropagation()
let originalStatusId = this.get('originalStatusId') let { originalStatusId, originalAccountId } = this.get()
let originalAccountId = this.get('originalAccountId')
let updateRelationshipPromise = updateProfileAndRelationship(originalAccountId) let updateRelationshipPromise = updateProfileAndRelationship(originalAccountId)
let dialogs = await importDialogs() let dialogs = await importDialogs()
await updateRelationshipPromise await updateRelationshipPromise
dialogs.showStatusOptionsDialog(originalStatusId) dialogs.showStatusOptionsDialog(originalStatusId)
}, },
onPostedStatus(realm, inReplyToUuid) { onPostedStatus(realm, inReplyToUuid) {
if (realm !== this.get('originalStatusId') || let {
inReplyToUuid !== this.get('uuid')) { originalStatusId,
uuid
} = this.get()
if (realm !== originalStatusId ||
inReplyToUuid !== uuid) {
return return
} }
try { try {

View File

@ -17,10 +17,10 @@
export default { export default {
oncreate() { oncreate() {
let instanceName = this.store.get('currentInstance') let { currentInstance } = this.store.get()
let timeline = this.get('timeline') let { timeline } = this.get()
this.store.set({currentTimeline: timeline}) this.store.set({currentTimeline: timeline})
this.store.setForTimeline(instanceName, timeline, {runningUpdate: false}) this.store.setForTimeline(currentInstance, timeline, {runningUpdate: false})
}, },
store: () => store, store: () => store,
data: () => ({ data: () => ({

View File

@ -15,7 +15,7 @@
export default { export default {
methods: { methods: {
onClick(event) { onClick(event) {
let onClick = this.get('onClick') let { onClick } = this.get()
if (onClick) { if (onClick) {
onClick(event) onClick(event)
} }

View File

@ -17,7 +17,7 @@
export default { export default {
async oncreate() { async oncreate() {
let accountId = this.get('accountId') let { accountId } = this.get()
await updatePinnedStatusesForAccount(accountId) await updatePinnedStatusesForAccount(accountId)
}, },
computed: { computed: {

View File

@ -150,7 +150,8 @@
}, },
methods: { methods: {
initialize() { initialize() {
if (this.get('initializeStarted')) { let { initializeStarted } = this.get()
if (initializeStarted) {
return return
} }
this.set({initializeStarted: true}) this.set({initializeStarted: true})
@ -165,18 +166,28 @@
this.set({scrollTop: scrollTop}) this.set({scrollTop: scrollTop})
}, },
onScrollToBottom() { onScrollToBottom() {
if (!this.store.get('timelineInitialized') || let {
this.store.get('runningUpdate') || timelineInitialized,
this.get('timelineType') === 'status') { // for status contexts, we've already fetched the whole thread runningUpdate
} = this.store.get()
let {
timelineType
} = this.get()
if (!timelineInitialized ||
runningUpdate ||
timelineType === 'status') { // for status contexts, we've already fetched the whole thread
return return
} }
let { currentInstance } = this.store.get()
let { timeline } = this.get()
fetchTimelineItemsOnScrollToBottom( fetchTimelineItemsOnScrollToBottom(
this.store.get('currentInstance'), currentInstance,
this.get('timeline') timeline
) )
}, },
onScrollToTop() { onScrollToTop() {
if (this.store.get('shouldShowHeader')) { let { shouldShowHeader } = this.store.get()
if (shouldShowHeader) {
this.store.setForCurrentTimeline({ this.store.setForCurrentTimeline({
showHeader: true, showHeader: true,
shouldShowHeader: false shouldShowHeader: false
@ -184,27 +195,29 @@
} }
}, },
setupStreaming() { setupStreaming() {
let instanceName = this.store.get('currentInstance') let { currentInstance } = this.store.get()
let timelineName = this.get('timeline') let { timeline } = this.get()
let handleItemIdsToAdd = () => { let handleItemIdsToAdd = () => {
let itemIdsToAdd = this.get('itemIdsToAdd') let { itemIdsToAdd } = this.get() || {} // TODO: wtf svelte?
if (!itemIdsToAdd || !itemIdsToAdd.length) { if (!itemIdsToAdd || !itemIdsToAdd.length) {
return return
} }
mark('handleItemIdsToAdd') mark('handleItemIdsToAdd')
let scrollTop = this.get('scrollTop') let { scrollTop } = this.get()
let shouldShowHeader = this.store.get('shouldShowHeader') let {
let showHeader = this.store.get('showHeader') shouldShowHeader,
if (timelineName.startsWith('status/')) { showHeader
} = this.store.get()
if (timeline.startsWith('status/')) {
// this is a thread, just insert the statuses already // this is a thread, just insert the statuses already
showMoreItemsForThread(instanceName, timelineName) showMoreItemsForThread(currentInstance, timeline)
} else if (scrollTop === 0 && !shouldShowHeader && !showHeader) { } else if (scrollTop === 0 && !shouldShowHeader && !showHeader) {
// if the user is scrolled to the top and we're not showing the header, then // if the user is scrolled to the top and we're not showing the header, then
// just insert the statuses. this is "chat room mode" // just insert the statuses. this is "chat room mode"
showMoreItemsForTimeline(instanceName, timelineName) showMoreItemsForTimeline(currentInstance, timeline)
} else { } else {
// user hasn't scrolled to the top, show a header instead // user hasn't scrolled to the top, show a header instead
this.store.setForTimeline(instanceName, timelineName, {shouldShowHeader: true}) this.store.setForTimeline(currentInstance, timeline, {shouldShowHeader: true})
} }
stop('handleItemIdsToAdd') stop('handleItemIdsToAdd')
} }
@ -232,8 +245,8 @@
}, },
saveFocus(e) { saveFocus(e) {
try { try {
let instanceName = this.store.get('currentInstance') let { currentInstance } = this.store.get()
let timelineName = this.get('timeline') let { timeline } = this.get()
let lastFocusedElementSelector let lastFocusedElementSelector
let activeElement = e.target let activeElement = e.target
if (activeElement) { if (activeElement) {
@ -243,7 +256,7 @@
} }
} }
console.log('saving focus to ', lastFocusedElementSelector) console.log('saving focus to ', lastFocusedElementSelector)
this.store.setForTimeline(instanceName, timelineName, { this.store.setForTimeline(currentInstance, timeline, {
lastFocusedElementSelector lastFocusedElementSelector
}) })
} catch (err) { } catch (err) {
@ -252,13 +265,14 @@
}, },
clearFocus() { clearFocus() {
try { try {
if (this.store.get('ignoreBlurEvents')) { let { ignoreBlurEvents } = this.store.get()
if (ignoreBlurEvents) {
return return
} }
console.log('clearing focus') console.log('clearing focus')
let instanceName = this.store.get('currentInstance') let { currentInstance } = this.store.get()
let timelineName = this.get('timeline') let { timeline } = this.get()
this.store.setForTimeline(instanceName, timelineName, { this.store.setForTimeline(currentInstance, timeline, {
lastFocusedElementSelector: null lastFocusedElementSelector: null
}) })
} catch (err) { } catch (err) {
@ -266,7 +280,7 @@
} }
}, },
restoreFocus() { restoreFocus() {
let lastFocusedElementSelector = this.store.get('lastFocusedElementSelector') let { lastFocusedElementSelector } = this.store.get()
if (!lastFocusedElementSelector) { if (!lastFocusedElementSelector) {
return return
} }

View File

@ -13,15 +13,20 @@
export default { export default {
oncreate() { oncreate() {
mark('onCreate VirtualListContainer') mark('onCreate VirtualListContainer')
this.store.setCurrentRealm(this.get('realm')) let {
let node = document.querySelector(this.get('containerQuery')) realm,
containerQuery
} = this.get()
this.store.setCurrentRealm(realm)
let node = document.querySelector(containerQuery)
this.setupScroll(node) this.setupScroll(node)
this.setupFullscreen() this.setupFullscreen()
let scrollTop = this.store.get('scrollTop') let { scrollTop } = this.store.get()
if (scrollTop > 0) { if (scrollTop > 0) {
this.observe('allVisibleItemsHaveHeight', allVisibleItemsHaveHeight => { this.observe('allVisibleItemsHaveHeight', allVisibleItemsHaveHeight => {
console.log('allVisibleItemsHaveHeight', allVisibleItemsHaveHeight) console.log('allVisibleItemsHaveHeight', allVisibleItemsHaveHeight)
if (!this.get('initializedScrollTop') && allVisibleItemsHaveHeight && node) { let { initializedScrollTop } = this.get()
if (!initializedScrollTop && allVisibleItemsHaveHeight && node) {
this.set({'initializedScrollTop': true}) this.set({'initializedScrollTop': true})
mark('set scrollTop') mark('set scrollTop')
console.log('forcing scroll top to ', scrollTop) console.log('forcing scroll top to ', scrollTop)
@ -60,7 +65,8 @@
return return
} }
this.scrollListener = throttle(event => { this.scrollListener = throttle(event => {
if (this.get('fullscreen')) { let { fullscreen } = this.get()
if (fullscreen) {
return return
} }
this.onScroll(event) this.onScroll(event)
@ -71,7 +77,8 @@
node.addEventListener('scroll', this.scrollListener) node.addEventListener('scroll', this.scrollListener)
}, },
teardownScroll() { teardownScroll() {
let node = document.querySelector(this.get('containerQuery')) let { containerQuery } = this.get()
let node = document.querySelector(containerQuery)
if (node) { if (node) {
node.removeEventListener('scroll', this.scrollListener) node.removeEventListener('scroll', this.scrollListener)
} }

View File

@ -39,7 +39,8 @@
store: () => virtualListStore, store: () => virtualListStore,
methods: { methods: {
doCalculateHeight() { doCalculateHeight() {
if (this.get('heightCalculated')) { // only need to calculate once, it never changes let { heightCalculated } = this.get()
if (heightCalculated) { // only need to calculate once, it never changes
return return
} }
this.set({heightCalculated: true}) this.set({heightCalculated: true})

View File

@ -30,7 +30,7 @@
export default { export default {
oncreate() { oncreate() {
let asyncLayout = new AsyncLayout(node => node.getAttribute('virtual-list-key')) let asyncLayout = new AsyncLayout(node => node.getAttribute('virtual-list-key'))
let key = this.get('key') let { key } = this.get()
asyncLayout.observe(key, this.refs.node, (rect) => { asyncLayout.observe(key, this.refs.node, (rect) => {
asyncLayout.disconnect() asyncLayout.disconnect()
// update all item heights in one batch for better perf // update all item heights in one batch for better perf
@ -51,8 +51,8 @@
// Recalculate immediately because this is done on-demand, e.g. // Recalculate immediately because this is done on-demand, e.g.
// when clicking the "More" button on a spoiler. // when clicking the "More" button on a spoiler.
let rect = this.refs.node.getBoundingClientRect() let rect = this.refs.node.getBoundingClientRect()
let key = this.get('key') let { key } = this.get()
let itemHeights = this.store.get('itemHeights') let { itemHeights } = this.store.get()
itemHeights[key] = rect.height itemHeights[key] = rect.height
this.store.setForRealm({itemHeights}) this.store.setForRealm({itemHeights})
} }

View File

@ -14,8 +14,7 @@
async oncreate() { async oncreate() {
// TODO: there appears to be a bug in {{#await}} that means we have to do this manually. // 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. // Some items may appear on top of other items because their offset is 0 and never updated.
let makeProps = this.get('makeProps') let { makeProps, key } = this.get()
let key = this.get('key')
if (makeProps) { if (makeProps) {
let props = await makeProps(key) let props = await makeProps(key)
mark('VirtualListLazyItem set props') mark('VirtualListLazyItem set props')

View File

@ -140,8 +140,8 @@ function doCleanup (instanceName) {
function scheduledCleanup () { function scheduledCleanup () {
console.log('scheduledCleanup') console.log('scheduledCleanup')
let instances = store.get('loggedInInstancesInOrder') let { loggedInInstancesInOrder } = store.get()
for (let instance of instances) { for (let instance of loggedInInstancesInOrder) {
doCleanup(instance) doCleanup(instance)
} }
} }

View File

@ -30,7 +30,8 @@
export default { export default {
oncreate() { oncreate() {
let accountId = this.get('params').accountId let { params } = this.get()
let { accountId } = params
clearProfileAndRelationship() clearProfileAndRelationship()
updateProfileAndRelationship(accountId) updateProfileAndRelationship(accountId)
}, },

View File

@ -96,7 +96,8 @@
export default { export default {
async oncreate() { async oncreate() {
if (this.store.get('currentInstance')) { let { currentInstance } = this.store.get()
if (currentInstance) {
await updateLists() await updateLists()
} }
}, },

View File

@ -38,13 +38,11 @@
export default { export default {
async oncreate() { async oncreate() {
let accountsFetcher = this.get('accountsFetcher')
try { try {
let currentInstance = this.store.get('currentInstance') let { currentInstance } = this.store.get()
await updateVerifyCredentialsForInstance(currentInstance) await updateVerifyCredentialsForInstance(currentInstance)
let accessToken = this.store.get('accessToken') let { accessToken, currentVerifyCredentials } = this.store.get()
let verifyCredentials = this.store.get('currentVerifyCredentials') let statuses = await getPinnedStatuses(currentInstance, accessToken, currentVerifyCredentials.id)
let statuses = await getPinnedStatuses(currentInstance, accessToken, verifyCredentials.id)
this.set({ statuses: statuses }) this.set({ statuses: statuses })
} catch (e) { } catch (e) {
toast.say('Error: ' + (e.name || '') + ' ' + (e.message || '')) toast.say('Error: ' + (e.name || '') + ' ' + (e.message || ''))

View File

@ -115,7 +115,7 @@
themes: themes, themes: themes,
}), }),
async oncreate() { async oncreate() {
let instanceName = this.get('instanceName') let { instanceName } = this.get()
await updateVerifyCredentialsForInstance(instanceName) await updateVerifyCredentialsForInstance(instanceName)
}, },
computed: { computed: {
@ -125,18 +125,17 @@
}, },
methods: { methods: {
onThemeChange() { onThemeChange() {
let newTheme = this.get('selectedTheme') let { newTheme, instanceName } = this.get()
let instanceName = this.get('instanceName')
changeTheme(instanceName, newTheme) changeTheme(instanceName, newTheme)
}, },
onSwitchToThisInstance(e) { onSwitchToThisInstance(e) {
e.preventDefault() e.preventDefault()
let instanceName = this.get('instanceName') let { instanceName } = this.get()
switchToInstance(instanceName) switchToInstance(instanceName)
}, },
async onLogOut(e) { async onLogOut(e) {
e.preventDefault() e.preventDefault()
let instanceName = this.get('instanceName') let { instanceName } = this.get()
let dialogs = await importDialogs() let dialogs = await importDialogs()
dialogs.showConfirmationDialog({ dialogs.showConfirmationDialog({

View File

@ -1,25 +1,22 @@
export function instanceMixins (Store) { export function instanceMixins (Store) {
Store.prototype.setComposeData = function (realm, obj) { Store.prototype.setComposeData = function (realm, obj) {
let composeData = this.get('composeData') let { composeData, currentInstance } = this.get()
let instanceName = this.get('currentInstance') let instanceNameData = composeData[currentInstance] = composeData[currentInstance] || {}
let instanceNameData = composeData[instanceName] = composeData[instanceName] || {}
instanceNameData[realm] = Object.assign(instanceNameData[realm] || {}, obj) instanceNameData[realm] = Object.assign(instanceNameData[realm] || {}, obj)
this.set({composeData}) this.set({composeData})
} }
Store.prototype.getComposeData = function (realm, key) { Store.prototype.getComposeData = function (realm, key) {
let composeData = this.get('composeData') let { composeData, currentInstance } = this.get()
let instanceName = this.get('currentInstance') return composeData[currentInstance] &&
return composeData[instanceName] && composeData[currentInstance][realm] &&
composeData[instanceName][realm] && composeData[currentInstance][realm][key]
composeData[instanceName][realm][key]
} }
Store.prototype.clearComposeData = function (realm) { Store.prototype.clearComposeData = function (realm) {
let composeData = this.get('composeData') let { composeData, currentInstance } = this.get()
let instanceName = this.get('currentInstance') if (composeData && composeData[currentInstance]) {
if (composeData && composeData[instanceName]) { delete composeData[currentInstance][realm]
delete composeData[instanceName][realm]
} }
this.set({composeData}) this.set({composeData})
} }

View File

@ -1,5 +1,5 @@
function getStatusModifications (store, instanceName) { function getStatusModifications (store, instanceName) {
let statusModifications = store.get('statusModifications') let { statusModifications } = store.get()
statusModifications[instanceName] = statusModifications[instanceName] || { statusModifications[instanceName] = statusModifications[instanceName] || {
favorites: {}, favorites: {},
reblogs: {} reblogs: {}

View File

@ -21,9 +21,8 @@ export function timelineMixins (Store) {
} }
Store.prototype.getForCurrentTimeline = function (key) { Store.prototype.getForCurrentTimeline = function (key) {
let instanceName = this.get('currentInstance') let { currentInstance, currentTimeline } = this.get()
let timelineName = this.get('currentTimeline') return this.getForTimeline(currentInstance, currentTimeline, key)
return this.getForTimeline(instanceName, timelineName, key)
} }
Store.prototype.getAllTimelineData = function (instanceName, key) { Store.prototype.getAllTimelineData = function (instanceName, key) {
@ -32,9 +31,8 @@ export function timelineMixins (Store) {
} }
Store.prototype.setForCurrentTimeline = function (obj) { Store.prototype.setForCurrentTimeline = function (obj) {
let instanceName = this.get('currentInstance') let { currentInstance, currentTimeline } = this.get()
let timelineName = this.get('currentTimeline') this.setForTimeline(currentInstance, currentTimeline, obj)
this.setForTimeline(instanceName, timelineName, obj)
} }
Store.prototype.getThreads = function (instanceName) { Store.prototype.getThreads = function (instanceName) {

View File

@ -31,15 +31,16 @@ export function instanceObservers (store) {
await updateInstanceInfo(currentInstance) await updateInstanceInfo(currentInstance)
let currentInstanceIsUnchanged = () => { let currentInstanceIsUnchanged = () => {
return store.get('currentInstance') === currentInstance let { currentInstance: newCurrentInstance } = store.get()
return newCurrentInstance === currentInstance
} }
if (!currentInstanceIsUnchanged()) { if (!currentInstanceIsUnchanged()) {
return return
} }
let instanceInfo = store.get('currentInstanceInfo') let { currentInstanceInfo } = store.get()
if (!instanceInfo) { if (!currentInstanceInfo) {
return return
} }
@ -74,8 +75,8 @@ export function instanceObservers (store) {
]) ])
} }
let accessToken = store.get('accessToken') let { accessToken } = store.get()
let streamingApi = instanceInfo.urls.streaming_api let streamingApi = currentInstanceInfo.urls.streaming_api
currentInstanceStream = createStream(streamingApi, currentInstanceStream = createStream(streamingApi,
currentInstance, accessToken, 'home', onOpenStream) currentInstance, accessToken, 'home', onOpenStream)

View File

@ -39,14 +39,18 @@ export function timelineObservers (store) {
return return
} }
let currentInstance = store.get('currentInstance') let { currentInstance } = store.get()
let accessToken = store.get('accessToken') let { accessToken } = store.get()
await updateInstanceInfo(currentInstance) await updateInstanceInfo(currentInstance)
let currentTimelineIsUnchanged = () => ( let currentTimelineIsUnchanged = () => {
store.get('currentInstance') === currentInstance && let {
store.get('currentTimeline') === currentTimeline currentInstance: newCurrentInstance,
) currentTimeline: newCurrentTimeline
} = store.get()
return newCurrentInstance === currentInstance &&
newCurrentTimeline === currentTimeline
}
if (!currentTimelineIsUnchanged()) { if (!currentTimelineIsUnchanged()) {
return return
@ -69,8 +73,8 @@ export function timelineObservers (store) {
} }
} }
let instanceInfo = store.get('currentInstanceInfo') let { currentInstanceInfo } = store.get()
let streamingApi = instanceInfo.urls.streaming_api let streamingApi = currentInstanceInfo.urls.streaming_api
currentTimelineStream = createStream(streamingApi, currentInstance, accessToken, currentTimelineStream = createStream(streamingApi, currentInstance, accessToken,
currentTimeline, onOpenStream) currentTimeline, onOpenStream)

View File

@ -17,9 +17,9 @@ export class RealmStore extends Store {
} }
setForRealm (obj) { setForRealm (obj) {
let realmName = this.get('currentRealm') let { currentRealm } = this.get()
let realms = this.get('realms') let { realms } = this.get()
realms.set(realmName, Object.assign(realms.get(realmName) || {}, obj)) realms.set(currentRealm, Object.assign(realms.get(currentRealm) || {}, obj))
this.set({realms: realms}) this.set({realms: realms})
} }
@ -37,10 +37,10 @@ export class RealmStore extends Store {
* to a plain old javascript object. * to a plain old javascript object.
*/ */
batchUpdateForRealm (key, subKey, value) { batchUpdateForRealm (key, subKey, value) {
let realm = this.get('currentRealm') let { currentRealm } = this.get()
let realmBatches = this._batches[realm] let realmBatches = this._batches[currentRealm]
if (!realmBatches) { if (!realmBatches) {
realmBatches = this._batches[realm] = {} realmBatches = this._batches[currentRealm] = {}
} }
let batch = realmBatches[key] let batch = realmBatches[key]
if (!batch) { if (!batch) {
@ -49,7 +49,7 @@ export class RealmStore extends Store {
batch[subKey] = value batch[subKey] = value
requestAnimationFrame(() => { requestAnimationFrame(() => {
let batch = this._batches[realm] && this._batches[realm][key] let batch = this._batches[currentRealm] && this._batches[currentRealm][key]
if (!batch) { if (!batch) {
return return
} }
@ -62,9 +62,9 @@ export class RealmStore extends Store {
for (let otherKey of updatedKeys) { for (let otherKey of updatedKeys) {
obj[otherKey] = batch[otherKey] obj[otherKey] = batch[otherKey]
} }
delete this._batches[realm][key] delete this._batches[currentRealm][key]
let realms = this.get('realms') let { realms } = this.get()
realms.set(realm, Object.assign(realms.get(realm) || {}, {[key]: obj})) realms.set(currentRealm, Object.assign(realms.get(currentRealm) || {}, {[key]: obj}))
this.set({realms: realms}) this.set({realms: realms})
stop('batchUpdate') stop('batchUpdate')
}) })