Fetch all user info on startup
This commit is contained in:
parent
bd1a92c5f1
commit
4c02478470
|
@ -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>
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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`)
|
||||
|
|
|
@ -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 })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
})
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue