more work on profile page

This commit is contained in:
Nolan Lawson 2018-01-28 12:51:48 -08:00
parent 5e7438cb52
commit 88d59678f2
14 changed files with 309 additions and 205 deletions

View file

@ -1,20 +1,26 @@
<div class="account-profile {{headerIsMissing ? 'header-is-missing' : ''}}" style="background-image: url({{profile.header}});"> <div class="account-profile {{headerIsMissing ? 'header-is-missing' : ''}}" style="background-image: url({{profile.header}});">
<div class="account-profile-grid"> <div class="account-profile-grid">
<div class="account-profile-avatar"> <div class="account-profile-avatar">
<img src="{{profile.avatar}}"> <img src="{{profile.avatar}}" aria-hidden="true">
</div> </div>
<div class="account-profile-name"> <div class="account-profile-name">
{{profile.display_name}} {{profile.display_name}}
</div> </div>
<div class="account-profile-following"> <div class="account-profile-followed-by">
{{#if relationship && relationship.followed_by}}
<span> <span>
Follows you Follows you
</span> </span>
{{/if}}
</div> </div>
<div class="account-profile-follow"> <div class="account-profile-follow">
<svg> {{#if verifyCredentials && relationship && verifyCredentials.id !== relationship.id}}
<use xlink:href="#fa-user-plus" /> <IconButton
</svg> label="{{relationship && relationship.following ? 'Unfollow' : 'Follow'}}"
href="{{relationship && relationship.following ? '#fa-user-times' : '#fa-user-plus'}}"
big="true"
/>
{{/if}}
</div> </div>
<div class="account-profile-note"> <div class="account-profile-note">
{{{profile.note}}} {{{profile.note}}}
@ -32,6 +38,7 @@
.account-profile.header-is-missing { .account-profile.header-is-missing {
padding-top: 0; padding-top: 0;
background-color: #ccc;
} }
.account-profile-background { .account-profile-background {
@ -45,7 +52,7 @@
.account-profile-grid { .account-profile-grid {
display: grid; display: grid;
grid-template-areas: "avatar name following follow" grid-template-areas: "avatar name followed-by follow"
"avatar note note note"; "avatar note note note";
grid-template-columns: min-content auto 1fr min-content; grid-template-columns: min-content auto 1fr min-content;
grid-column-gap: 10px; grid-column-gap: 10px;
@ -68,19 +75,19 @@
} }
} }
.account-profile-following, .account-profile-avatar, .account-profile-follow, .account-profile-followed-by, .account-profile-avatar, .account-profile-follow,
.account-profile-name, .account-profile-username, .account-profile-note { .account-profile-name, .account-profile-username, .account-profile-note {
z-index: 10; z-index: 10;
} }
.account-profile-following { .account-profile-followed-by {
grid-area: following; grid-area: followed-by;
align-self: center; align-self: center;
text-transform: uppercase; text-transform: uppercase;
color: var(--deemphasized-text-color); color: var(--deemphasized-text-color);
font-size: 0.8em; font-size: 0.8em;
} }
.account-profile-following span { .account-profile-followed-by span {
background: rgba(30, 30, 30, 0.2); background: rgba(30, 30, 30, 0.2);
border-radius: 4px; border-radius: 4px;
padding: 3px 5px; padding: 3px 5px;
@ -99,11 +106,6 @@
grid-area: follow; grid-area: follow;
align-self: center; align-self: center;
} }
.account-profile-follow svg {
width: 32px;
height: 32px;
fill: var(--svg-fill);
}
.account-profile-name { .account-profile-name {
grid-area: name; grid-area: name;
font-size: 1.5em; font-size: 1.5em;
@ -121,9 +123,14 @@
} }
</style> </style>
<script> <script>
import IconButton from './IconButton.html'
export default { export default {
computed: { computed: {
headerIsMissing: (profile) => profile.header.endsWith('missing.png') headerIsMissing: (profile) => profile.header.endsWith('missing.png')
},
components: {
IconButton
} }
} }
</script> </script>

View file

@ -0,0 +1,56 @@
{{#if pressable}}
<button type="button"
aria-label="{{label}}"
aria-pressed="{{!!pressed}}"
class="icon-button {{pressed ? 'pressed' : ''}} {{big ? 'big-icon' : ''}}">
<svg>
<use xlink:href="{{href}}" />
</svg>
</button>
{{else}}
<button type="button"
aria-label="{{label}}"
class="icon-button {{big ? 'big-icon' : ''}}">
<svg>
<use xlink:href="{{href}}" />
</svg>
</button>
{{/if}}
<style>
button.icon-button {
padding: 6px 10px;
background: none;
border: none;
}
button.icon-button svg {
width: 24px;
height: 24px;
fill: var(--action-button-fill-color);
}
button.icon-button.big-icon svg {
width: 32px;
height: 32px;
}
button.icon-button:hover svg {
fill: var(--action-button-fill-color-hover);
}
button.icon-button:active svg {
fill: var(--action-button-fill-color-active);
}
button.icon-button.pressed svg {
fill: var(--action-button-fill-color-pressed)
}
button.icon-button.pressed:hover svg {
fill: var(--action-button-fill-color-pressed-hover);
}
button.icon-button.pressed:active svg {
fill: var(--action-button-fill-color-pressed-active);
}
</style>

View file

@ -1,30 +1,24 @@
<div class="status-toolbar"> <div class="status-toolbar">
<button aria-label="Reply" type="button"> <IconButton
<svg> label="Reply"
<use xlink:href="#fa-reply" /> href="#fa-reply"
</svg> />
</button> <IconButton
<button aria-label="Boost" aria-pressed="{{status.reblogged}}" class="{{status.reblogged ? 'selected' : ''}}" type="button"> label="Boost"
<svg> pressable="true"
{{#if status.visibility === 'private'}} pressed="{{status.reblogged}}"
<use xlink:href="#fa-lock" /> href="{{status.visibility === 'private' ? '#fa-lock' : status.visibility === 'direct' ? '#fa-envelope' : '#fa-retweet'}}"
{{elseif status.visibility === 'direct'}} />
<use xlink:href="#fa-envelope" /> <IconButton
{{else}} label="Favorite"
<use xlink:href="#fa-retweet" /> pressable="true"
{{/if}} pressed="{{status.favourited}}"
</svg> href="#fa-star"
</button> />
<button aria-label="Favorite" aria-pressed="{{status.favourited}}" class="{{status.favourited ? 'selected' : ''}}" type="button"> <IconButton
<svg> label="Show more actions"
<use xlink:href="#fa-star" /> href="#fa-ellipsis-h"
</svg> />
</button>
<button aria-label="Show more actions" type="button">
<svg>
<use xlink:href="#fa-ellipsis-h" />
</svg>
</button>
</div> </div>
<style> <style>
.status-toolbar { .status-toolbar {
@ -32,41 +26,14 @@
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
} }
.status-toolbar button {
padding: 6px 10px;
background: none;
border: none;
}
.status-toolbar button svg {
width: 24px;
height: 24px;
fill: var(--action-button-fill-color);
}
.status-toolbar button:hover svg {
fill: var(--action-button-fill-color-hover);
}
.status-toolbar button:active svg {
fill: var(--action-button-fill-color-active);
}
.status-toolbar button.selected svg {
fill: var(--action-button-fill-color-pressed)
}
.status-toolbar button.selected:hover svg {
fill: var(--action-button-fill-color-pressed-hover);
}
.status-toolbar button.selected:active svg {
fill: var(--action-button-fill-color-pressed-active);
}
</style> </style>
<script> <script>
import IconButton from '../IconButton.html'
export default { export default {
components: {
IconButton
}
} }
</script> </script>

View file

@ -1,10 +1,10 @@
<div class="lazy-timeline"> <div class="lazy-timeline">
{{#if !$initialized}} {{#if !$initialized}}
<div transition:fade> <!-- <div transition:fade> -->
<div class="loading-page"> <div class="loading-page">
<LoadingSpinner /> <LoadingSpinner />
</div> </div>
</div> <!-- </div> -->
{{/if}} {{/if}}
{{#await promise}} {{#await promise}}
{{then constructor}} {{then constructor}}
@ -33,7 +33,8 @@
<script> <script>
import { importTimeline } from '../../_utils/asyncModules' import { importTimeline } from '../../_utils/asyncModules'
import LoadingSpinner from '../LoadingSpinner.html' import LoadingSpinner from '../LoadingSpinner.html'
import { fade } from 'svelte-transitions' // TODO: the transition seems to occasionally cause an error in Svelte, transition_run is undefined
//import { fade } from 'svelte-transitions'
import { store } from '../../_utils/store' import { store } from '../../_utils/store'
export default { export default {
@ -49,9 +50,9 @@
}), }),
components: { components: {
LoadingSpinner LoadingSpinner
}, }/*,
transitions: { transitions: {
fade fade
} }*/
} }
</script> </script>

View file

@ -0,0 +1,61 @@
import QuickLRU from 'quick-lru'
export const statusesCache = {
maxSize: 100,
caches: {}
}
export const accountsCache = {
maxSize: 50,
caches: {}
}
export const relationshipsCache = {
maxSize: 20,
caches: {}
}
export const metaCache = {
maxSize: 20,
caches: {}
}
if (process.browser && process.env.NODE_ENV !== 'production') {
window.cacheStats = {
statuses: statusesCache,
accounts: accountsCache,
relationships: relationshipsCache,
meta: metaCache
}
}
function getOrCreateInstanceCache(cache, instanceName) {
let cached = cache.caches[instanceName]
if (!cached) {
cached = cache.caches[instanceName] = new QuickLRU({maxSize: cache.maxSize})
}
return cached
}
export function clearCache(cache, instanceName) {
delete cache.caches[instanceName]
}
export function setInCache(cache, instanceName, key, value) {
let instanceCache = getOrCreateInstanceCache(cache, instanceName)
return instanceCache.set(key, value)
}
export function getInCache(cache, instanceName, key) {
let instanceCache = getOrCreateInstanceCache(cache, instanceName)
return instanceCache.get(key)
}
export function hasInCache(cache, instanceName, key) {
let instanceCache = getOrCreateInstanceCache(cache, instanceName)
let res = instanceCache.has(key)
if (process.env.NODE_ENV !== 'production') {
if (res) {
cache.hits = (cache.hits || 0) + 1
} else {
cache.misses = (cache.misses || 0) + 1
}
}
return res
}

View file

@ -1,4 +1,5 @@
export const STATUSES_STORE = 'statuses' export const STATUSES_STORE = 'statuses'
export const TIMELINE_STORE = 'timelines' export const TIMELINE_STORE = 'timelines'
export const META_STORE = 'meta' export const META_STORE = 'meta'
export const ACCOUNTS_STORE= 'accounts' export const ACCOUNTS_STORE = 'accounts'
export const RELATIONSHIPS_STORE = 'relationships'

View file

@ -10,69 +10,44 @@ import {
import { import {
META_STORE, META_STORE,
TIMELINE_STORE, TIMELINE_STORE,
STATUSES_STORE, ACCOUNTS_STORE STATUSES_STORE,
ACCOUNTS_STORE,
RELATIONSHIPS_STORE
} from './constants' } from './constants'
import QuickLRU from 'quick-lru' import {
statusesCache,
relationshipsCache,
accountsCache,
metaCache,
clearCache,
getInCache,
hasInCache,
setInCache
} from './cache'
const statusesCache = { //
maxSize: 100, // helpers
caches: {} //
}
const accountsCache = {
maxSize: 50,
caches: {}
}
const metaCache = {
maxSize: 20,
caches: {}
}
if (process.browser && process.env.NODE_ENV !== 'production') { async function getGenericEntityWithId(store, cache, instanceName, id) {
window.cacheStats = { if (hasInCache(cache, instanceName, id)) {
statuses: { return getInCache(cache, instanceName, id)
cache: statusesCache,
hits: 0,
misses: 0
},
accounts: {
cache: accountsCache,
hits: 0,
misses: 0
},
meta: {
cache: accountsCache,
hits: 0,
misses: 0
}
} }
const db = await getDatabase(instanceName)
let result = await dbPromise(db, store, 'readonly', (store, callback) => {
store.get(id).onsuccess = (e) => callback(e.target.result)
})
setInCache(cache, instanceName, id, result)
return result
} }
function clearCache(cache, instanceName) { async function setGenericEntityWithId(store, cache, instanceName, entity) {
delete cache.caches[instanceName] setInCache(cache, instanceName, entity.id, entity)
} const db = await getDatabase(instanceName)
return await dbPromise(db, store, 'readwrite', (store) => {
function getOrCreateInstanceCache(cache, instanceName) { store.put(entity)
let cached = cache.caches[instanceName] })
if (!cached) {
cached = cache.caches[instanceName] = new QuickLRU({maxSize: cache.maxSize})
}
return cached
}
function setInCache(cache, instanceName, key, value) {
let instanceCache = getOrCreateInstanceCache(cache, instanceName)
return instanceCache.set(key, value)
}
function getInCache(cache, instanceName, key) {
let instanceCache = getOrCreateInstanceCache(cache, instanceName)
return instanceCache.get(key)
}
function hasInCache(cache, instanceName, key) {
let instanceCache = getOrCreateInstanceCache(cache, instanceName)
return instanceCache.has(key)
} }
// //
@ -129,23 +104,7 @@ export async function insertStatuses(instanceName, timeline, statuses) {
} }
export async function getStatus(instanceName, statusId) { export async function getStatus(instanceName, statusId) {
if (hasInCache(statusesCache, instanceName, statusId)) { return await getGenericEntityWithId(STATUSES_STORE, statusesCache, instanceName, statusId)
if (process.browser && process.env.NODE_ENV !== 'production') {
window.cacheStats.statuses.hits++
}
return getInCache(statusesCache, instanceName, statusId)
}
const db = await getDatabase(instanceName)
let result = await dbPromise(db, STATUSES_STORE, 'readonly', (store, callback) => {
store.get(statusId).onsuccess = (e) => {
callback(e.target.result && e.target.result)
}
})
setInCache(statusesCache, instanceName, statusId, result)
if (process.browser && process.env.NODE_ENV !== 'production') {
window.cacheStats.statuses.misses++
}
return result
} }
// //
@ -154,9 +113,6 @@ export async function getStatus(instanceName, statusId) {
async function getMetaProperty(instanceName, key) { async function getMetaProperty(instanceName, key) {
if (hasInCache(metaCache, instanceName, key)) { if (hasInCache(metaCache, instanceName, key)) {
if (process.browser && process.env.NODE_ENV !== 'production') {
window.cacheStats.meta.hits++
}
return getInCache(metaCache, instanceName, key) return getInCache(metaCache, instanceName, key)
} }
const db = await getDatabase(instanceName) const db = await getDatabase(instanceName)
@ -166,9 +122,6 @@ async function getMetaProperty(instanceName, key) {
} }
}) })
setInCache(metaCache, instanceName, key, result) setInCache(metaCache, instanceName, key, result)
if (process.browser && process.env.NODE_ENV !== 'production') {
window.cacheStats.meta.misses++
}
return result return result
} }
@ -200,34 +153,23 @@ export async function setInstanceInfo(instanceName, value) {
} }
// //
// accounts // accounts/relationships
// //
export async function getAccount(instanceName, accountId) { export async function getAccount(instanceName, accountId) {
if (hasInCache(accountsCache, instanceName, accountId)) { return await getGenericEntityWithId(ACCOUNTS_STORE, accountsCache, instanceName, accountId)
if (process.browser && process.env.NODE_ENV !== 'production') {
window.cacheStats.accounts.hits++
}
return getInCache(accountsCache, instanceName, accountId)
}
const db = await getDatabase(instanceName)
let result = await dbPromise(db, ACCOUNTS_STORE, 'readonly', (store, callback) => {
store.get(accountId).onsuccess = (e) => {
callback(e.target.result && e.target.result)
}
})
if (process.browser && process.env.NODE_ENV !== 'production') {
window.cacheStats.accounts.misses++
}
return result
} }
export async function setAccount(instanceName, account) { export async function setAccount(instanceName, account) {
setInCache(accountsCache, instanceName, account.id, account) return await setGenericEntityWithId(ACCOUNTS_STORE, accountsCache, instanceName, account)
const db = await getDatabase(instanceName) }
return await dbPromise(db, ACCOUNTS_STORE, 'readwrite', (store) => {
store.put(account) export async function getRelationship(instanceName, accountId) {
}) return await getGenericEntityWithId(RELATIONSHIPS_STORE, relationshipsCache, instanceName, accountId)
}
export async function setRelationship(instanceName, relationship) {
return await setGenericEntityWithId(RELATIONSHIPS_STORE, relationshipsCache, instanceName, relationship)
} }
// //

View file

@ -1,11 +1,14 @@
const openReqs = {} const openReqs = {}
const databaseCache = {} const databaseCache = {}
const DB_VERSION = 2
import { import {
META_STORE, META_STORE,
TIMELINE_STORE, TIMELINE_STORE,
STATUSES_STORE, STATUSES_STORE,
ACCOUNTS_STORE ACCOUNTS_STORE,
RELATIONSHIPS_STORE
} from './constants' } from './constants'
export function getDatabase(instanceName) { export function getDatabase(instanceName) {
@ -17,19 +20,24 @@ export function getDatabase(instanceName) {
} }
databaseCache[instanceName] = new Promise((resolve, reject) => { databaseCache[instanceName] = new Promise((resolve, reject) => {
let req = indexedDB.open(instanceName, 1) let req = indexedDB.open(instanceName, DB_VERSION)
openReqs[instanceName] = req openReqs[instanceName] = req
req.onerror = reject req.onerror = reject
req.onblocked = () => { req.onblocked = () => {
console.log('idb blocked') console.log('idb blocked')
} }
req.onupgradeneeded = () => { req.onupgradeneeded = (e) => {
let db = req.result; let db = req.result;
db.createObjectStore(META_STORE, {keyPath: 'key'}) if (e.oldVersion < 1) {
db.createObjectStore(STATUSES_STORE, {keyPath: 'id'}) db.createObjectStore(META_STORE, {keyPath: 'key'})
db.createObjectStore(ACCOUNTS_STORE, {keyPath: 'id'}) db.createObjectStore(STATUSES_STORE, {keyPath: 'id'})
let timelineStore = db.createObjectStore(TIMELINE_STORE, {keyPath: 'id'}) db.createObjectStore(ACCOUNTS_STORE, {keyPath: 'id'})
timelineStore.createIndex('statusId', 'statusId') let timelineStore = db.createObjectStore(TIMELINE_STORE, {keyPath: 'id'})
timelineStore.createIndex('statusId', 'statusId')
}
if (e.oldVersion < 2) {
db.createObjectStore(RELATIONSHIPS_STORE, {keyPath: 'id'})
}
} }
req.onsuccess = () => resolve(req.result) req.onsuccess = () => resolve(req.result)
}) })

View file

@ -1,4 +1,4 @@
import { get } from '../ajax' import { get, paramsString } from '../ajax'
import { basename } from './utils' import { basename } from './utils'
export function getVerifyCredentials(instanceName, accessToken) { export function getVerifyCredentials(instanceName, accessToken) {
@ -14,3 +14,12 @@ export function getAccount(instanceName, accessToken, accountId) {
'Authorization': `Bearer ${accessToken}` 'Authorization': `Bearer ${accessToken}`
}) })
} }
export async function getRelationship(instanceName, accessToken, accountId) {
let url = `${basename(instanceName)}/api/v1/accounts/relationships`
url += '?' + paramsString({id: accountId})
let res = await get(url, {
'Authorization': `Bearer ${accessToken}`
})
return res[0]
}

View file

@ -1,4 +1,5 @@
import { Store } from 'svelte/store.js' import { Store } from 'svelte/store.js'
import { storeObservers } from './storeObservers'
const LOCAL_STORAGE_KEYS = new Set([ const LOCAL_STORAGE_KEYS = new Set([
"currentInstance", "currentInstance",
@ -112,6 +113,12 @@ store.compute(
} }
) )
store.compute(
'currentVerifyCredentials',
['currentInstance', 'verifyCredentials'],
(currentInstance, verifyCredentials) => verifyCredentials && verifyCredentials[currentInstance]
)
store.compute('currentTimelineData', ['currentInstance', 'currentTimeline', 'timelines'], store.compute('currentTimelineData', ['currentInstance', 'currentTimeline', 'timelines'],
(currentInstance, currentTimeline, timelines) => { (currentInstance, currentTimeline, timelines) => {
return ((timelines && timelines[currentInstance]) || {})[currentTimeline] || {} return ((timelines && timelines[currentInstance]) || {})[currentTimeline] || {}
@ -122,6 +129,8 @@ store.compute('runningUpdate', ['currentTimelineData'], (currentTimelineData) =>
store.compute('initialized', ['currentTimelineData'], (currentTimelineData) => currentTimelineData.initialized) store.compute('initialized', ['currentTimelineData'], (currentTimelineData) => currentTimelineData.initialized)
store.compute('lastStatusId', ['statusIds'], (statusIds) => statusIds.length && statusIds[statusIds.length - 1]) store.compute('lastStatusId', ['statusIds'], (statusIds) => statusIds.length && statusIds[statusIds.length - 1])
storeObservers(store)
if (process.browser && process.env.NODE_ENV !== 'production') { if (process.browser && process.env.NODE_ENV !== 'production') {
window.store = store // for debugging window.store = store // for debugging
} }

View file

@ -0,0 +1,7 @@
import { updateVerifyCredentialsForInstance } from '../settings/instances/_actions/[instanceName]'
export function storeObservers(store) {
store.observe('currentInstance', (currentInstance) => {
updateVerifyCredentialsForInstance(currentInstance)
})
}

View file

@ -12,7 +12,10 @@
{{#if $isUserLoggedIn}} {{#if $isUserLoggedIn}}
<DynamicPageBanner title="{{profileName}}" /> <DynamicPageBanner title="{{profileName}}" />
{{#if $currentAccountProfile}} {{#if $currentAccountProfile}}
<AccountProfile profile="{{$currentAccountProfile}}" /> <AccountProfile profile="{{$currentAccountProfile}}"
relationship="{{$currentAccountRelationship}}"
verifyCredentials="{{$currentVerifyCredentials}}"
/>
{{/if}} {{/if}}
<LazyTimeline timeline='account/{{params.accountId}}' /> <LazyTimeline timeline='account/{{params.accountId}}' />
{{else}} {{else}}
@ -32,13 +35,16 @@
import { store } from '../_utils/store.js' import { store } from '../_utils/store.js'
import HiddenFromSSR from '../_components/HiddenFromSSR' import HiddenFromSSR from '../_components/HiddenFromSSR'
import DynamicPageBanner from '../_components/DynamicPageBanner.html' import DynamicPageBanner from '../_components/DynamicPageBanner.html'
import { showAccountProfile } from './_actions/[accountId]' import { updateProfileAndRelationship } from './_actions/[accountId]'
import AccountProfile from '../_components/AccountProfile.html' import AccountProfile from '../_components/AccountProfile.html'
import { updateVerifyCredentialsForInstance } from '../settings/instances/_actions/[instanceName]'
export default { export default {
oncreate() { oncreate() {
let accountId = this.get('params').accountId let accountId = this.get('params').accountId
showAccountProfile(accountId) let instanceName = this.store.get('currentInstance')
updateProfileAndRelationship(accountId)
updateVerifyCredentialsForInstance(instanceName)
}, },
store: () => store, store: () => store,
computed: { computed: {

View file

@ -1,24 +1,54 @@
import { getAccount } from '../../_utils/mastodon/user' import { getAccount, getRelationship } from '../../_utils/mastodon/user'
import { database } from '../../_utils/database/database' import { database } from '../../_utils/database/database'
import { store } from '../../_utils/store' import { store } from '../../_utils/store'
export async function showAccountProfile(accountId) { async function updateAccount(accountId, instanceName, accessToken) {
store.set({currentAccountProfile: null})
let instanceName = store.get('currentInstance')
let accessToken = store.get('accessToken')
let localPromise = database.getAccount(instanceName, accountId) let localPromise = database.getAccount(instanceName, accountId)
let remotePromise = getAccount(instanceName, accessToken, accountId).then(account => { let remotePromise = getAccount(instanceName, accessToken, accountId).then(account => {
database.setAccount(instanceName, account) database.setAccount(instanceName, account)
return account return account
}) })
let localAccount = await localPromise
store.set({currentAccountProfile: localAccount})
try { try {
let remoteAccount = await remotePromise store.set({currentAccountProfile: (await localPromise)})
store.set({currentAccountProfile: remoteAccount})
} catch (e) { } catch (e) {
console.error("couldn't fetch profile", e) console.error(e)
}
try {
store.set({currentAccountProfile: (await remotePromise)})
} catch (e) {
console.error(e)
} }
} }
async function updateRelationship(accountId, instanceName, accessToken) {
let localPromise = database.getRelationship(instanceName, accountId)
let remotePromise = getRelationship(instanceName, accessToken, accountId).then(relationship => {
database.setRelationship(instanceName, relationship)
return relationship
})
try {
store.set({currentAccountRelationship: (await localPromise)})
} catch (e) {
console.error(e)
}
try {
store.set({currentAccountRelationship: (await remotePromise)})
} catch (e) {
console.error(e)
}
}
export async function updateProfileAndRelationship(accountId) {
store.set({
currentAccountProfile: null,
currentAccountRelationship: null
})
let instanceName = store.get('currentInstance')
let accessToken = store.get('accessToken')
await Promise.all([
updateAccount(accountId, instanceName, accessToken),
updateRelationship(accountId, instanceName, accessToken)
])
}

View file

@ -63,5 +63,5 @@
--deemphasized-text-color: #666; --deemphasized-text-color: #666;
--focus-outline: $focus-outline; --focus-outline: $focus-outline;
--status-direct-background: darken($body-bg-color, 5%) --status-direct-background: darken($body-bg-color, 5%);
} }