forked from Mirrors/elk
feat: prevent mixing data on account switch (#384)
This commit is contained in:
parent
8c82c91056
commit
de160c219a
5 changed files with 42 additions and 26 deletions
|
@ -15,7 +15,8 @@ export function setCached(key: string, value: any, override = false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fetchStatus(id: string, force = false): Promise<Status> {
|
export function fetchStatus(id: string, force = false): Promise<Status> {
|
||||||
const key = `status:${id}`
|
const server = currentServer.value
|
||||||
|
const key = `${server}:status:${id}`
|
||||||
const cached = cache.get(key)
|
const cached = cache.get(key)
|
||||||
if (cached && !force)
|
if (cached && !force)
|
||||||
return cached
|
return cached
|
||||||
|
@ -32,30 +33,37 @@ export function fetchAccountById(id?: string | null): Promise<Account | null> {
|
||||||
if (!id)
|
if (!id)
|
||||||
return Promise.resolve(null)
|
return Promise.resolve(null)
|
||||||
|
|
||||||
const key = `account:${id}`
|
const server = currentServer.value
|
||||||
|
const key = `${server}:account:${id}`
|
||||||
const cached = cache.get(key)
|
const cached = cache.get(key)
|
||||||
if (cached)
|
if (cached)
|
||||||
return cached
|
return cached
|
||||||
|
const uri = currentInstance.value?.uri
|
||||||
const promise = useMasto().accounts.fetch(id)
|
const promise = useMasto().accounts.fetch(id)
|
||||||
.then((account) => {
|
.then((r) => {
|
||||||
cacheAccount(account, true)
|
if (!r.acct.includes('@') && uri)
|
||||||
return account
|
r.acct = `${r.acct}@${uri}`
|
||||||
|
|
||||||
|
cacheAccount(r, server, true)
|
||||||
|
return r
|
||||||
})
|
})
|
||||||
cache.set(key, promise)
|
cache.set(key, promise)
|
||||||
return promise
|
return promise
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchAccountByHandle(acct: string): Promise<Account> {
|
export async function fetchAccountByHandle(acct: string): Promise<Account> {
|
||||||
const key = `account:${acct}`
|
const server = currentServer.value
|
||||||
|
const key = `${server}:account:${acct}`
|
||||||
const cached = cache.get(key)
|
const cached = cache.get(key)
|
||||||
if (cached)
|
if (cached)
|
||||||
return cached
|
return cached
|
||||||
|
const uri = currentInstance.value?.uri
|
||||||
const account = useMasto().accounts.lookup({ acct })
|
const account = useMasto().accounts.lookup({ acct })
|
||||||
.then((r) => {
|
.then((r) => {
|
||||||
if (!r.acct.includes('@') && currentInstance.value)
|
if (!r.acct.includes('@') && uri)
|
||||||
r.acct = `${r.acct}@${currentInstance.value.uri}`
|
r.acct = `${r.acct}@${uri}`
|
||||||
|
|
||||||
cacheAccount(r, true)
|
cacheAccount(r, server, true)
|
||||||
return r
|
return r
|
||||||
})
|
})
|
||||||
cache.set(key, account)
|
cache.set(key, account)
|
||||||
|
@ -70,11 +78,11 @@ export function useAccountById(id?: string | null) {
|
||||||
return useAsyncState(() => fetchAccountById(id), null).state
|
return useAsyncState(() => fetchAccountById(id), null).state
|
||||||
}
|
}
|
||||||
|
|
||||||
export function cacheStatus(status: Status, override?: boolean) {
|
export function cacheStatus(status: Status, server = currentServer.value, override?: boolean) {
|
||||||
setCached(`status:${status.id}`, status, override)
|
setCached(`${server}:status:${status.id}`, status, override)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function cacheAccount(account: Account, override?: boolean) {
|
export function cacheAccount(account: Account, server = currentServer.value, override?: boolean) {
|
||||||
setCached(`account:${account.id}`, account, override)
|
setCached(`${server}:account:${account.id}`, account, override)
|
||||||
setCached(`account:${account.acct}`, account, override)
|
setCached(`${server}:account:${account.acct}`, account, override)
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,12 +31,6 @@ export const currentInstance = computed<null | Instance>(() => currentUserId.val
|
||||||
export const characterLimit = computed(() => currentInstance.value?.configuration.statuses.maxCharacters ?? DEFAULT_POST_CHARS_LIMIT)
|
export const characterLimit = computed(() => currentInstance.value?.configuration.statuses.maxCharacters ?? DEFAULT_POST_CHARS_LIMIT)
|
||||||
|
|
||||||
export async function loginTo(user?: Omit<UserLogin, 'account'> & { account?: AccountCredentials }) {
|
export async function loginTo(user?: Omit<UserLogin, 'account'> & { account?: AccountCredentials }) {
|
||||||
if (user) {
|
|
||||||
const existing = users.value.find(u => u.server === user.server && u.token === user.token)
|
|
||||||
if (existing && currentUserId.value !== user.account?.id)
|
|
||||||
currentUserId.value = user.account?.id
|
|
||||||
}
|
|
||||||
|
|
||||||
const config = useRuntimeConfig()
|
const config = useRuntimeConfig()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
@ -76,7 +70,7 @@ export async function loginTo(user?: Omit<UserLogin, 'account'> & { account?: Ac
|
||||||
|
|
||||||
setMasto(masto)
|
setMasto(masto)
|
||||||
|
|
||||||
if ('server' in route.params) {
|
if ('server' in route.params && user?.token) {
|
||||||
await router.push({
|
await router.push({
|
||||||
...route,
|
...route,
|
||||||
force: true,
|
force: true,
|
||||||
|
@ -110,7 +104,7 @@ export async function signout() {
|
||||||
currentUserId.value = users.value[0]?.account?.id
|
currentUserId.value = users.value[0]?.account?.id
|
||||||
|
|
||||||
if (!currentUserId.value)
|
if (!currentUserId.value)
|
||||||
await useRouter().push(`/${currentServer.value}/public`)
|
await useRouter().push('/')
|
||||||
|
|
||||||
await loginTo(currentUser.value)
|
await loginTo(currentUser.value)
|
||||||
}
|
}
|
||||||
|
@ -127,7 +121,7 @@ export const useNotifications = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function connect(): Promise<void> {
|
async function connect(): Promise<void> {
|
||||||
if (!id || notifications[id])
|
if (!id || notifications[id] || !currentUser.value?.token)
|
||||||
return
|
return
|
||||||
|
|
||||||
const masto = useMasto()
|
const masto = useMasto()
|
||||||
|
|
|
@ -6,7 +6,9 @@ export default defineNuxtRouteMiddleware(async (to, from) => {
|
||||||
if (!('server' in to.params))
|
if (!('server' in to.params))
|
||||||
return
|
return
|
||||||
|
|
||||||
if (!currentUser.value) {
|
const user = currentUser.value
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
if (from.params.server !== to.params.server) {
|
if (from.params.server !== to.params.server) {
|
||||||
await loginTo({
|
await loginTo({
|
||||||
server: to.params.server as string,
|
server: to.params.server as string,
|
||||||
|
@ -16,7 +18,7 @@ export default defineNuxtRouteMiddleware(async (to, from) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// No need to additionally resolve an id if we're already logged in
|
// No need to additionally resolve an id if we're already logged in
|
||||||
if (currentUser.value.server === to.params.server)
|
if (user.server === to.params.server)
|
||||||
return
|
return
|
||||||
|
|
||||||
// Tags don't need to be redirected to a local id
|
// Tags don't need to be redirected to a local id
|
||||||
|
@ -29,12 +31,19 @@ export default defineNuxtRouteMiddleware(async (to, from) => {
|
||||||
...to,
|
...to,
|
||||||
params: {
|
params: {
|
||||||
...to.params,
|
...to.params,
|
||||||
server: currentUser.value.server,
|
server: user.server,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// If we're already on an account page, we can search for this on the new instance
|
||||||
|
if (to.params.account) {
|
||||||
|
const account = await fetchAccountByHandle(to.params.account as string)
|
||||||
|
if (account)
|
||||||
|
return getAccountRoute(account)
|
||||||
|
}
|
||||||
|
|
||||||
// If we're logged in, search for the local id the account or status corresponds to
|
// If we're logged in, search for the local id the account or status corresponds to
|
||||||
const { value } = await useMasto().search({ q: `https:/${to.fullPath}`, resolve: true, limit: 1 }).next()
|
const { value } = await useMasto().search({ q: `https:/${to.fullPath}`, resolve: true, limit: 1 }).next()
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import type { ComponentPublicInstance } from 'vue'
|
||||||
|
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
name: 'status',
|
name: 'status',
|
||||||
|
key: route => route.path,
|
||||||
})
|
})
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
definePageMeta({
|
||||||
|
key: route => `${route.params.server}:${route.params.account}`,
|
||||||
|
})
|
||||||
|
|
||||||
const params = useRoute().params
|
const params = useRoute().params
|
||||||
const accountName = $(computedEager(() => toShortHandle(params.account as string)))
|
const accountName = $(computedEager(() => toShortHandle(params.account as string)))
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue