Fetch all user info on startup

This commit is contained in:
wvffle 2022-07-21 23:19:16 +00:00 committed by Georg Krause
parent bd1a92c5f1
commit 4c02478470
10 changed files with 85 additions and 130 deletions

View File

@ -67,6 +67,11 @@ onKeyboardShortcut('h', () => toggleShortcutsModal())
const { width } = useWindowSize()
const showSetInstanceModal = ref(false)
// Fetch user data on startup
if (store.state.auth.authenticated) {
store.dispatch('auth/fetchUser')
}
</script>
<template>

View File

@ -9,7 +9,6 @@ import SemanticModal from '~/components/semantic/Modal.vue'
import useThemeList from '~/composables/useThemeList'
import useTheme from '~/composables/useTheme'
import axios from 'axios'
import { useRoute } from 'vue-router'
import { computed, ref, watch, watchEffect, onMounted } from 'vue'
import { useGettext } from 'vue3-gettext'
@ -94,37 +93,6 @@ const moderationNotifications = computed(() =>
+ store.state.ui.notifications.pendingReviewRequests
)
onMounted(async () => {
if (store.state.auth.authenticated) {
const [inbox, edits, reports, requests] = await Promise.all([
axios.get('federation/inbox/', { params: { is_read: false } }).catch(() => ({ data: { count: 0 } })),
axios.get('mutations/', { params: { page_size: 1, q: 'is_approved:null' } }).catch(() => ({ data: { count: 0 } })),
axios.get('manage/moderation/reports/', { params: { page_size: 1, q: 'resolved:no' } }).catch(() => ({ data: { count: 0 } })),
axios.get('manage/moderation/requests/', { params: { page_size: 1, q: 'status:pending' } }).catch(() => ({ data: { count: 0 } }))
])
store.commit('ui/incrementNotifications', {
type: 'inbox',
value: inbox.data.count
})
store.commit('ui/incrementNotifications', {
type: 'pendingReviewEdits',
value: edits.data.count
})
store.commit('ui/incrementNotifications', {
type: 'pendingReviewRequests',
value: requests.data.count
})
store.commit('ui/incrementNotifications', {
type: 'pendingReviewReports',
value: reports.data.count
})
}
})
const isProduction = import.meta.env.PROD
const showUserModal = ref(false)
const showLanguageModal = ref(false)

View File

@ -1,5 +1,6 @@
<script setup lang="ts">
import type { BackendError } from '~/types'
import type { RouteLocationRaw } from 'vue-router'
import { ref, reactive, computed, onMounted } from 'vue'
import { useGettext } from 'vue3-gettext'
@ -8,7 +9,7 @@ import { useStore } from '~/store'
import PasswordInput from '~/components/forms/PasswordInput.vue'
interface Props {
next?: string
next?: RouteLocationRaw
buttonClasses?: string
showSignup?: boolean
}
@ -42,10 +43,7 @@ const submit = async () => {
try {
if (domain === store.getters['instance/domain']) {
await store.dispatch('auth/login', {
credentials,
next: props.next
})
await store.dispatch('auth/login', { credentials })
} else {
await store.dispatch('auth/oauthLogin', props.next)
}
@ -61,14 +59,6 @@ const submit = async () => {
isLoading.value = false
}
// export default {
// created () {
// if (this.$store.state.auth.authenticated) {
// this.$router.push(this.next)
// }
// },
// }
</script>
<template>

View File

@ -1,6 +1,7 @@
import type { User } from '~/types'
import type { Module } from 'vuex'
import type { RootState } from '~/store/index'
import type { RouteLocationRaw } from 'vue-router'
import axios from 'axios'
import useLogger from '~/composables/useLogger'
@ -147,20 +148,12 @@ const store: Module<State, RootState> = {
},
actions: {
// Send a request to the login URL and save the returned JWT
login ({ dispatch }, { next, credentials, onError }) {
async login ({ dispatch }, { credentials }) {
const form = useFormData(credentials)
return axios.post('users/login', form).then(() => {
logger.info('Successfully logged in as', credentials.username)
dispatch('fetchUser').then(() => {
// Redirect to a specified route
import('~/router').then((router) => {
return router.default.push(next)
})
})
}, response => {
logger.error('Error while logging in', response.data)
onError(response)
})
await axios.post('users/login', form)
logger.info('Successfully logged in as', credentials.username)
await dispatch('fetchUser')
},
async logout ({ commit }) {
try {
@ -181,36 +174,40 @@ const store: Module<State, RootState> = {
})
logger.info('Log out, goodbye!')
},
fetchUser ({ dispatch }) {
return new Promise((resolve, reject) => {
axios.get('users/me/').then((response) => {
logger.info('Successfully fetched user profile')
dispatch('updateUser', response.data)
dispatch('ui/fetchUnreadNotifications', null, { root: true })
if (response.data.permissions.library) {
dispatch('ui/fetchPendingReviewEdits', null, { root: true })
}
if (response.data.permissions.moderation) {
dispatch('ui/fetchPendingReviewReports', null, { root: true })
dispatch('ui/fetchPendingReviewRequests', null, { root: true })
}
dispatch('favorites/fetch', null, { root: true })
dispatch('channels/fetchSubscriptions', null, { root: true })
dispatch('libraries/fetchFollows', null, { root: true })
async fetchNotifications ({ dispatch, state }) {
return Promise.all([
dispatch('ui/fetchUnreadNotifications', null, { root: true }),
state.availablePermissions.library && dispatch('ui/fetchPendingReviewEdits', null, { root: true }),
state.availablePermissions.moderation && dispatch('ui/fetchPendingReviewReports', null, { root: true }),
state.availablePermissions.moderation && dispatch('ui/fetchPendingReviewRequests', null, { root: true })
])
},
async fetchUser ({ dispatch }) {
try {
const response = await axios.get('users/me/')
logger.info('Successfully fetched user profile')
dispatch('updateUser', response.data)
await Promise.all([
dispatch('fetchNotifications'),
dispatch('favorites/fetch', null, { root: true }),
dispatch('playlists/fetchOwn', null, { root: true }),
dispatch('libraries/fetchFollows', null, { root: true }),
dispatch('channels/fetchSubscriptions', null, { root: true }),
dispatch('moderation/fetchContentFilters', null, { root: true })
dispatch('playlists/fetchOwn', null, { root: true })
resolve(response.data)
}, () => {
logger.info('Error while fetching user profile')
reject(new Error('Error while fetching user profile'))
})
})
])
} catch (error) {
logger.error('Error while fetching user profile', error)
}
},
updateUser ({ commit }, data) {
commit('authenticated', true)
commit('profile', data)
commit('username', data.username)
commit('fullUsername', data.full_username)
if (data.tokens) {
commit('scopedTokens', data.tokens)
}
@ -220,7 +217,7 @@ const store: Module<State, RootState> = {
commit('permission', { key: permission, status: hasPermission })
}
},
async oauthLogin ({ state, rootState, commit }, next) {
async oauthLogin ({ state, rootState, commit }, next: RouteLocationRaw) {
const app = await createOauthApp()
commit('oauthApp', app)
const redirectUri = encodeURIComponent(`${location.origin}/auth/callback`)

View File

@ -103,13 +103,11 @@ const store: Module<State, RootState> = {
toggle ({ getters, dispatch }, uuid) {
dispatch('set', { uuid, value: !getters.isSubscribed(uuid) })
},
fetchSubscriptions ({ commit }) {
const promise = axios.get('subscriptions/all/')
return promise.then((response) => {
response.data.results.forEach((result: { channel: unknown }) => {
commit('subscriptions', { uuid: result.channel, value: true })
})
})
async fetchSubscriptions ({ commit }) {
const response = await axios.get('subscriptions/all/')
for (const result of response.data.results) {
commit('subscriptions', { uuid: result.channel, value: true })
}
}
}
}

View File

@ -64,20 +64,20 @@ const store: Module<State, RootState> = {
toggle ({ getters, dispatch }, id) {
dispatch('set', { id, value: !getters.isFavorite(id) })
},
fetch ({ commit, rootState }) {
async fetch ({ commit, rootState }) {
// will fetch favorites by batches from API to have them locally
const params = {
user: rootState.auth.profile?.id,
page_size: 50,
ordering: '-creation_date'
}
const promise = axios.get('favorites/tracks/all/', { params })
return promise.then((response) => {
logger.info('Fetched a batch of ' + response.data.results.length + ' favorites')
response.data.results.forEach((result: { track: string }) => {
commit('track', { id: result.track, value: true })
})
})
const response = await axios.get('favorites/tracks/all/', { params })
logger.info('Fetched a batch of ' + response.data.results.length + ' favorites')
for (const result of response.data.results) {
commit('track', { id: result.track, value: true })
}
}
}
}

View File

@ -67,13 +67,11 @@ const store: Module<State, RootState> = {
toggle ({ getters, dispatch }, uuid) {
dispatch('set', { uuid, value: !getters.follow(uuid) })
},
fetchFollows ({ dispatch, state, commit, rootState }, url) {
const promise = axios.get('federation/follows/library/all/')
return promise.then((response) => {
response.data.results.forEach((result: { library: string }) => {
commit('follows', { library: result.library, follow: result })
})
})
async fetchFollows ({ dispatch, state, commit, rootState }, url) {
const response = await axios.get('federation/follows/library/all/')
for (const result of response.data.results) {
commit('follows', { library: result.library, follow: result })
}
}
}
}

View File

@ -128,30 +128,28 @@ const store: Module<State, RootState> = {
commit('reportModalTarget', payload)
commit('showReportModal', true)
},
fetchContentFilters ({ dispatch, commit }, url) {
let params = {}
let promise
if (url) {
promise = axios.get(url)
} else {
commit('empty')
params = {
page_size: 100,
ordering: '-creation_date'
}
promise = axios.get('moderation/content-filters/', { params })
async fetchContentFilters ({ dispatch, commit }, url) {
const params = url
? {}
: {
page_size: 100,
ordering: '-creation_date'
}
if (!url) commit('empty')
const response = await axios.get(url ?? 'moderation/content-filters/', { params })
logger.info(`Fetched a batch of ${response.data.results.length} filters`)
for (const result of response.data.results) {
commit('contentFilter', result)
}
if (response.data.next) {
await dispatch('fetchContentFilters', response.data.next)
}
return promise.then((response) => {
logger.info('Fetched a batch of ' + response.data.results.length + ' filters')
if (response.data.next) {
dispatch('fetchContentFilters', response.data.next)
}
response.data.results.forEach((result: ContentFilter) => {
commit('contentFilter', result)
})
})
},
deleteContentFilter ({ commit }, uuid) {
async deleteContentFilter ({ commit }, uuid) {
return axios.delete(`moderation/content-filters/${uuid}/`).then(() => {
commit('deleteContentFilter', uuid)
})

View File

@ -41,7 +41,7 @@ const store: Module<State, RootState> = {
const playlists = []
let url = 'playlists/'
while (url != null) {
while (url !== null) {
const response = await axios.get(url, { params: { scope: 'me' } })
playlists.push(...response.data.results)
url = response.data.next

View File

@ -6,6 +6,7 @@ import { useRouter } from 'vue-router'
import { computed } from 'vue'
import { useGettext } from 'vue3-gettext'
import { useStore } from '~/store'
import { whenever } from '@vueuse/core'
interface Props {
next?: RouteLocationRaw
@ -21,11 +22,11 @@ const labels = computed(() => ({
}))
const store = useStore()
if (store.state.auth.authenticated) {
const router = useRouter()
const router = useRouter()
whenever(() => store.state.auth.authenticated, () => {
const resolved = router.resolve(props.next)
router.push(resolved.name === '404' ? '/library' : props.next)
}
})
</script>
<template>