remaining backend interactor removals

This commit is contained in:
Henry Jameson 2026-06-15 20:02:22 +03:00
commit 0d9709825f
45 changed files with 1118 additions and 856 deletions

View file

@ -19,7 +19,6 @@ import {
config.autoAddCss = false config.autoAddCss = false
import App from '../App.vue' import App from '../App.vue'
import backendInteractorService from '../services/backend_interactor_service/backend_interactor_service.js'
import FaviconService from '../services/favicon_service/favicon_service.js' import FaviconService from '../services/favicon_service/favicon_service.js'
import { applyStyleConfig } from '../services/style_setter/style_setter.js' import { applyStyleConfig } from '../services/style_setter/style_setter.js'
import { initServiceWorker, updateFocus } from '../services/sw/sw.js' import { initServiceWorker, updateFocus } from '../services/sw/sw.js'
@ -31,6 +30,7 @@ import routes from './routes'
import { useAnnouncementsStore } from 'src/stores/announcements' import { useAnnouncementsStore } from 'src/stores/announcements'
import { useAuthFlowStore } from 'src/stores/auth_flow' import { useAuthFlowStore } from 'src/stores/auth_flow'
import { useCredentialsStore } from 'src/stores/credentials.js'
import { useEmojiStore } from 'src/stores/emoji.js' import { useEmojiStore } from 'src/stores/emoji.js'
import { useI18nStore } from 'src/stores/i18n' import { useI18nStore } from 'src/stores/i18n'
import { useInstanceStore } from 'src/stores/instance.js' import { useInstanceStore } from 'src/stores/instance.js'
@ -264,10 +264,7 @@ const getStickers = async ({ store }) => {
const getAppSecret = async ({ store }) => { const getAppSecret = async ({ store }) => {
const oauth = useOAuthStore() const oauth = useOAuthStore()
if (oauth.userToken) { if (oauth.userToken) {
store.commit( useCredentialsStore().setCredentials(oauth.getToken)
'setBackendInteractor',
backendInteractorService(oauth.getToken),
)
} }
} }

View file

@ -16,8 +16,15 @@ import {
isScrollable, isScrollable,
} from './chat_layout_utils.js' } from './chat_layout_utils.js'
import { useCredentialsStore } from 'src/stores/credentials.js'
import { useInterfaceStore } from 'src/stores/interface.js' import { useInterfaceStore } from 'src/stores/interface.js'
import {
chatMessages,
getOrCreateChat,
sendChatMessage,
} from 'src/services/api/api.service.js'
import { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'
import { faChevronDown, faChevronLeft } from '@fortawesome/free-solid-svg-icons' import { faChevronDown, faChevronLeft } from '@fortawesome/free-solid-svg-icons'
@ -115,7 +122,6 @@ const Chat = {
mobileLayout: (store) => store.layoutType === 'mobile', mobileLayout: (store) => store.layoutType === 'mobile',
}), }),
...mapState({ ...mapState({
backendInteractor: (state) => state.api.backendInteractor,
mastoUserSocketStatus: (state) => state.api.mastoUserSocketStatus, mastoUserSocketStatus: (state) => state.api.mastoUserSocketStatus,
currentUser: (state) => state.users.currentUser, currentUser: (state) => state.users.currentUser,
}), }),
@ -267,42 +273,46 @@ const Chat = {
const fetchOlderMessages = !!maxId const fetchOlderMessages = !!maxId
const sinceId = fetchLatest && chatMessageService.maxId const sinceId = fetchLatest && chatMessageService.maxId
return this.backendInteractor return chatMessages({
.chatMessages({ id: chatId, maxId, sinceId }) id: chatId,
.then((messages) => { maxId,
// Clear the current chat in case we're recovering from a ws connection loss. sinceId,
if (isFirstFetch) { credentials: useCredentialsStore().current,
chatService.clear(chatMessageService) }).then((messages) => {
} // Clear the current chat in case we're recovering from a ws connection loss.
if (isFirstFetch) {
chatService.clear(chatMessageService)
}
const positionBeforeUpdate = getScrollPosition() const positionBeforeUpdate = getScrollPosition()
this.$store this.$store
.dispatch('addChatMessages', { chatId, messages }) .dispatch('addChatMessages', { chatId, messages })
.then(() => { .then(() => {
this.$nextTick(() => { this.$nextTick(() => {
if (fetchOlderMessages) { if (fetchOlderMessages) {
this.handleScrollUp(positionBeforeUpdate) this.handleScrollUp(positionBeforeUpdate)
} }
// In vertical screens, the first batch of fetched messages may not always take the // In vertical screens, the first batch of fetched messages may not always take the
// full height of the scrollable container. // full height of the scrollable container.
// If this is the case, we want to fetch the messages until the scrollable container // If this is the case, we want to fetch the messages until the scrollable container
// is fully populated so that the user has the ability to scroll up and load the history. // is fully populated so that the user has the ability to scroll up and load the history.
if (!isScrollable() && messages.length > 0) { if (!isScrollable() && messages.length > 0) {
this.fetchChat({ this.fetchChat({
maxId: this.currentChatMessageService.minId, maxId: this.currentChatMessageService.minId,
}) })
} }
})
}) })
}) })
})
}, },
async startFetching() { async startFetching() {
let chat = this.findOpenedChatByRecipientId(this.recipientId) let chat = this.findOpenedChatByRecipientId(this.recipientId)
if (!chat) { if (!chat) {
try { try {
chat = await this.backendInteractor.getOrCreateChat({ chat = await getOrCreateChat({
accountId: this.recipientId, accountId: this.recipientId,
credentials: useCredentialsStore().current,
}) })
} catch (e) { } catch (e) {
console.error('Error creating or getting a chat', e) console.error('Error creating or getting a chat', e)
@ -369,8 +379,10 @@ const Chat = {
doSendMessage({ params, fakeMessage, retriesLeft = MAX_RETRIES }) { doSendMessage({ params, fakeMessage, retriesLeft = MAX_RETRIES }) {
if (retriesLeft <= 0) return if (retriesLeft <= 0) return
this.backendInteractor sendChatMessage({
.sendChatMessage(params) params,
credentials: useCredentialsStore().current,
})
.then((data) => { .then((data) => {
this.$store.dispatch('addChatMessages', { this.$store.dispatch('addChatMessages', {
chatId: this.currentChat.id, chatId: this.currentChat.id,

View file

@ -3,6 +3,10 @@ import { mapGetters, mapState } from 'vuex'
import BasicUserCard from 'src/components/basic_user_card/basic_user_card.vue' import BasicUserCard from 'src/components/basic_user_card/basic_user_card.vue'
import UserAvatar from 'src/components/user_avatar/user_avatar.vue' import UserAvatar from 'src/components/user_avatar/user_avatar.vue'
import { useCredentialsStore } from 'src/stores/credentials.js'
import { chats } from 'src/services/api/api.service.js'
import { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'
import { faChevronLeft, faSearch } from '@fortawesome/free-solid-svg-icons' import { faChevronLeft, faSearch } from '@fortawesome/free-solid-svg-icons'
@ -22,7 +26,9 @@ const chatNew = {
} }
}, },
async created() { async created() {
const { chats } = await this.backendInteractor.chats() const { chats } = await chats({
credentials: useCredentialsStore().current,
})
chats.forEach((chat) => this.suggestions.push(chat.account)) chats.forEach((chat) => this.suggestions.push(chat.account))
}, },
computed: { computed: {
@ -38,7 +44,6 @@ const chatNew = {
}, },
...mapState({ ...mapState({
currentUser: (state) => state.users.currentUser, currentUser: (state) => state.users.currentUser,
backendInteractor: (state) => state.api.backendInteractor,
}), }),
...mapGetters(['findUser']), ...mapGetters(['findUser']),
}, },

View file

@ -7,9 +7,12 @@ import QuickViewSettings from 'src/components/quick_view_settings/quick_view_set
import ThreadTree from 'src/components/thread_tree/thread_tree.vue' import ThreadTree from 'src/components/thread_tree/thread_tree.vue'
import { WSConnectionStatus } from '../../services/api/api.service.js' import { WSConnectionStatus } from '../../services/api/api.service.js'
import { useCredentialsStore } from 'src/stores/credentials.js'
import { useInterfaceStore } from 'src/stores/interface' import { useInterfaceStore } from 'src/stores/interface'
import { useMergedConfigStore } from 'src/stores/merged_config.js' import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { fetchConversation, fetchStatus } from 'src/services/api/api.service.js'
import { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'
import { import {
faAngleDoubleDown, faAngleDoubleDown,
@ -436,17 +439,20 @@ const conversation = {
methods: { methods: {
fetchConversation() { fetchConversation() {
if (this.status) { if (this.status) {
this.$store.state.api.backendInteractor fetchConversation({
.fetchConversation({ id: this.statusId }) id: this.statusId,
.then(({ ancestors, descendants }) => { credentials: useCredentialsStore().current,
this.$store.dispatch('addNewStatuses', { statuses: ancestors }) }).then(({ ancestors, descendants }) => {
this.$store.dispatch('addNewStatuses', { statuses: descendants }) this.$store.dispatch('addNewStatuses', { statuses: ancestors })
this.setHighlight(this.originalStatusId) this.$store.dispatch('addNewStatuses', { statuses: descendants })
}) this.setHighlight(this.originalStatusId)
})
} else { } else {
this.loadStatusError = null this.loadStatusError = null
this.$store.state.api.backendInteractor fetchStatus({
.fetchStatus({ id: this.statusId }) id: this.statusId,
credentials: useCredentialsStore().current,
})
.then((status) => { .then((status) => {
this.$store.dispatch('addNewStatuses', { statuses: [status] }) this.$store.dispatch('addNewStatuses', { statuses: [status] })
this.fetchConversation() this.fetchConversation()

View file

@ -3,8 +3,11 @@ import { defineAsyncComponent } from 'vue'
import { notificationsFromStore } from '../../services/notification_utils/notification_utils.js' import { notificationsFromStore } from '../../services/notification_utils/notification_utils.js'
import BasicUserCard from '../basic_user_card/basic_user_card.vue' import BasicUserCard from '../basic_user_card/basic_user_card.vue'
import { useCredentialsStore } from 'src/stores/credentials.js'
import { useMergedConfigStore } from 'src/stores/merged_config.js' import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { approveUser, denyUser } from 'src/services/api/api.service.js'
const FollowRequestCard = { const FollowRequestCard = {
props: ['user'], props: ['user'],
components: { components: {
@ -48,7 +51,10 @@ const FollowRequestCard = {
} }
}, },
doApprove() { doApprove() {
this.$store.state.api.backendInteractor.approveUser({ id: this.user.id }) approveUser({
id: this.user.id,
credentials: useCredentialsStore().current,
})
this.$store.dispatch('removeFollowRequest', this.user) this.$store.dispatch('removeFollowRequest', this.user)
const notifId = this.findFollowRequestNotificationId() const notifId = this.findFollowRequestNotificationId()
@ -70,12 +76,14 @@ const FollowRequestCard = {
}, },
doDeny() { doDeny() {
const notifId = this.findFollowRequestNotificationId() const notifId = this.findFollowRequestNotificationId()
this.$store.state.api.backendInteractor
.denyUser({ id: this.user.id }) denyUser({
.then(() => { id: this.user.id,
this.$store.dispatch('dismissNotificationLocal', { id: notifId }) credentials: useCredentialsStore().current,
this.$store.dispatch('removeFollowRequest', this.user) }).then(() => {
}) this.$store.dispatch('dismissNotificationLocal', { id: notifId })
this.$store.dispatch('removeFollowRequest', this.user)
})
this.hideDenyConfirmDialog() this.hideDenyConfirmDialog()
}, },
}, },

View file

@ -13,10 +13,12 @@ import {
highlightStyle, highlightStyle,
} from '../../services/user_highlighter/user_highlighter.js' } from '../../services/user_highlighter/user_highlighter.js'
import { useCredentialsStore } from 'src/stores/credentials.js'
import { useInstanceStore } from 'src/stores/instance.js' import { useInstanceStore } from 'src/stores/instance.js'
import { useMergedConfigStore } from 'src/stores/merged_config.js' import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { useUserHighlightStore } from 'src/stores/user_highlight.js' import { useUserHighlightStore } from 'src/stores/user_highlight.js'
import { approveUser, denyUser } from 'src/services/api/api.service.js'
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator' import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
import { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'
@ -142,7 +144,10 @@ const Notification = {
} }
}, },
doApprove() { doApprove() {
this.$store.state.api.backendInteractor.approveUser({ id: this.user.id }) approveUser({
id: this.user.id,
credentials: useCredentialsStore().current,
})
this.$store.dispatch('removeFollowRequest', this.user) this.$store.dispatch('removeFollowRequest', this.user)
this.$store.dispatch('markSingleNotificationAsSeen', { this.$store.dispatch('markSingleNotificationAsSeen', {
id: this.notification.id, id: this.notification.id,
@ -163,14 +168,15 @@ const Notification = {
} }
}, },
doDeny() { doDeny() {
this.$store.state.api.backendInteractor denyUser({
.denyUser({ id: this.user.id }) id: this.user.id,
.then(() => { credentials: useCredentialsStore().current,
this.$store.dispatch('dismissNotificationLocal', { }).then(() => {
id: this.notification.id, this.$store.dispatch('dismissNotificationLocal', {
}) id: this.notification.id,
this.$store.dispatch('removeFollowRequest', this.user)
}) })
this.$store.dispatch('removeFollowRequest', this.user)
})
this.hideDenyConfirmDialog() this.hideDenyConfirmDialog()
}, },
}, },

View file

@ -1,3 +1,7 @@
import { useCredentialsStore } from 'src/stores/credentials.js'
import { fetchUser } from 'src/services/api/api.service.js'
const RemoteUserResolver = { const RemoteUserResolver = {
data: () => ({ data: () => ({
error: false, error: false,
@ -7,10 +11,11 @@ const RemoteUserResolver = {
}, },
methods: { methods: {
redirect() { redirect() {
const acct = const id = this.$route.params.username + '@' + this.$route.params.hostname
this.$route.params.username + '@' + this.$route.params.hostname fetchUser({
this.$store.state.api.backendInteractor id,
.fetchUser({ id: acct }) credentials: useCredentialsStore().current,
})
.then((externalUser) => { .then((externalUser) => {
if (externalUser.error) { if (externalUser.error) {
this.error = true this.error = true

View file

@ -11,6 +11,7 @@ import ModifiedIndicator from '../helpers/modified_indicator.vue'
import SharedComputedObject from '../helpers/shared_computed_object.js' import SharedComputedObject from '../helpers/shared_computed_object.js'
import StringSetting from '../helpers/string_setting.vue' import StringSetting from '../helpers/string_setting.vue'
import { useAdminSettingsStore } from 'src/stores/admin_settings.js'
import { useEmojiStore } from 'src/stores/emoji.js' import { useEmojiStore } from 'src/stores/emoji.js'
import { useInstanceStore } from 'src/stores/instance.js' import { useInstanceStore } from 'src/stores/instance.js'
import { useInterfaceStore } from 'src/stores/interface.js' import { useInterfaceStore } from 'src/stores/interface.js'
@ -98,10 +99,10 @@ const EmojiTab = {
methods: { methods: {
reloadEmoji() { reloadEmoji() {
this.$store.state.api.backendInteractor.reloadEmoji() useAdminSettingsStore().reloadEmoji()
}, },
importFromFS() { importFromFS() {
this.$store.state.api.backendInteractor.importEmojiFromFS() useAdminSettingsStore().importEmojiFromFS()
}, },
emojiAddr(name) { emojiAddr(name) {
if (this.pack.remote !== undefined) { if (this.pack.remote !== undefined) {
@ -113,7 +114,7 @@ const EmojiTab = {
}, },
createEmojiPack() { createEmojiPack() {
this.$store.state.api.backendInteractor useAdminSettingsStore()
.createEmojiPack({ name: this.newPackName }) .createEmojiPack({ name: this.newPackName })
.then((resp) => resp.json()) .then((resp) => resp.json())
.then((resp) => { .then((resp) => {
@ -130,7 +131,7 @@ const EmojiTab = {
}) })
}, },
deleteEmojiPack() { deleteEmojiPack() {
this.$store.state.api.backendInteractor useAdminSettingsStore()
.deleteEmojiPack({ name: this.packName }) .deleteEmojiPack({ name: this.packName })
.then((resp) => resp.json()) .then((resp) => resp.json())
.then((resp) => { .then((resp) => {
@ -157,7 +158,7 @@ const EmojiTab = {
return edited !== def return edited !== def
}, },
savePackMetadata() { savePackMetadata() {
this.$store.state.api.backendInteractor useAdminSettingsStore()
.saveEmojiPackMetadata({ name: this.packName, newData: this.packMeta }) .saveEmojiPackMetadata({ name: this.packName, newData: this.packMeta })
.then((resp) => resp.json()) .then((resp) => resp.json())
.then((resp) => { .then((resp) => {
@ -182,7 +183,7 @@ const EmojiTab = {
useEmojiStore() useEmojiStore()
.getAdminPacks( .getAdminPacks(
this.remotePackInstance, this.remotePackInstance,
this.$store.state.api.backendInteractor.listEmojiPacks, useAdminSettingsStore().listEmojiPacks,
) )
.then((allPacks) => { .then((allPacks) => {
this.knownLocalPacks = allPacks this.knownLocalPacks = allPacks
@ -195,7 +196,7 @@ const EmojiTab = {
useEmojiStore() useEmojiStore()
.getAdminPacks( .getAdminPacks(
this.remotePackInstance, this.remotePackInstance,
this.$store.state.api.backendInteractor.listRemoteEmojiPacks, useAdminSettingsStore().listRemoteEmojiPacks,
) )
.then((allPacks) => { .then((allPacks) => {
let inst = this.remotePackInstance let inst = this.remotePackInstance
@ -226,7 +227,7 @@ const EmojiTab = {
this.remotePackDownloadAs = this.pack.remote.baseName this.remotePackDownloadAs = this.pack.remote.baseName
} }
this.$store.state.api.backendInteractor useAdminSettingsStore()
.downloadRemoteEmojiPack({ .downloadRemoteEmojiPack({
instance: this.pack.remote.instance, instance: this.pack.remote.instance,
packName: this.pack.remote.baseName, packName: this.pack.remote.baseName,
@ -247,7 +248,7 @@ const EmojiTab = {
}) })
}, },
downloadRemoteURLPack() { downloadRemoteURLPack() {
this.$store.state.api.backendInteractor useAdminSettingsStore()
.downloadRemoteEmojiPackZIP({ .downloadRemoteEmojiPackZIP({
url: this.remotePackURL, url: this.remotePackURL,
packName: this.newPackName, packName: this.newPackName,
@ -268,7 +269,7 @@ const EmojiTab = {
}) })
}, },
downloadRemoteFilePack() { downloadRemoteFilePack() {
this.$store.state.api.backendInteractor useAdminSettingsStore()
.downloadRemoteEmojiPackZIP({ .downloadRemoteEmojiPackZIP({
file: this.remotePackFile[0], file: this.remotePackFile[0],
packName: this.newPackName, packName: this.newPackName,

View file

@ -71,7 +71,7 @@ const FrontendsTab = {
const payload = { name, ref } const payload = { name, ref }
this.working = true this.working = true
this.$store.state.api.backendInteractor useAdminSettingsStore()
.installFrontend({ payload }) .installFrontend({ payload })
.finally(() => { .finally(() => {
this.working = false this.working = false

View file

@ -153,6 +153,14 @@ import Popover from 'components/popover/popover.vue'
import SelectComponent from 'components/select/select.vue' import SelectComponent from 'components/select/select.vue'
import { defineAsyncComponent } from 'vue' import { defineAsyncComponent } from 'vue'
import { useCredentialsStore } from 'src/stores/credentials.js'
import {
addNewEmojiFile,
deleteEmojiFile,
updateEmojiFile,
} from 'src/services/api/api.service.js'
export default { export default {
components: { components: {
Popover, Popover,
@ -243,14 +251,14 @@ export default {
saveEditedEmoji() { saveEditedEmoji() {
if (!this.isEdited) return if (!this.isEdited) return
this.$store.state.api.backendInteractor updateEmojiFile({
.updateEmojiFile({ packName: this.packName,
packName: this.packName, shortcode: this.shortcode,
shortcode: this.shortcode, newShortcode: this.editedShortcode,
newShortcode: this.editedShortcode, newFilename: this.editedFile,
newFilename: this.editedFile, force: false,
force: false, credentials: useCredentialsStore().current,
}) })
.then((resp) => { .then((resp) => {
if (resp.error !== undefined) { if (resp.error !== undefined) {
this.$emit('displayError', resp.error) this.$emit('displayError', resp.error)
@ -263,18 +271,18 @@ export default {
}, },
uploadEmoji() { uploadEmoji() {
let packName = this.remote === undefined ? this.packName : this.copyToPack let packName = this.remote === undefined ? this.packName : this.copyToPack
this.$store.state.api.backendInteractor addNewEmojiFile({
.addNewEmojiFile({ packName: packName,
packName: packName, file:
file: this.remote === undefined
this.remote === undefined ? this.uploadURL !== ''
? this.uploadURL !== '' ? this.uploadURL
? this.uploadURL : this.uploadFile[0]
: this.uploadFile[0] : this.emojiAddr(this.file),
: this.emojiAddr(this.file), shortcode: this.editedShortcode,
shortcode: this.editedShortcode, filename: this.editedFile,
filename: this.editedFile, credentials: useCredentialsStore().current,
}) })
.then((resp) => resp.json()) .then((resp) => resp.json())
.then((resp) => { .then((resp) => {
if (resp.error !== undefined) { if (resp.error !== undefined) {
@ -297,8 +305,11 @@ export default {
deleteEmoji() { deleteEmoji() {
this.deleteModalVisible = false this.deleteModalVisible = false
this.$store.state.api.backendInteractor deleteEmojiFile({
.deleteEmojiFile({ packName: this.packName, shortcode: this.shortcode }) packName: this.packName,
shortcode: this.shortcode,
credentials: useCredentialsStore().current,
})
.then((resp) => resp.json()) .then((resp) => resp.json())
.then((resp) => { .then((resp) => {
if (resp.error !== undefined) { if (resp.error !== undefined) {

View file

@ -10,9 +10,11 @@ import SharedComputedObject from '../helpers/shared_computed_object.js'
import UnitSetting from '../helpers/unit_setting.vue' import UnitSetting from '../helpers/unit_setting.vue'
import Preview from './old_theme_tab/theme_preview.vue' import Preview from './old_theme_tab/theme_preview.vue'
import { useCredentialsStore } from 'src/stores/credentials.js'
import { useInstanceStore } from 'src/stores/instance.js' import { useInstanceStore } from 'src/stores/instance.js'
import { normalizeThemeData, useInterfaceStore } from 'src/stores/interface.js' import { normalizeThemeData, useInterfaceStore } from 'src/stores/interface.js'
import { updateProfileImages } from 'src/services/api/api.service.js'
import { newImporter } from 'src/services/export_import/export_import.js' import { newImporter } from 'src/services/export_import/export_import.js'
import { import {
adoptStyleSheets, adoptStyleSheets,
@ -484,8 +486,10 @@ const AppearanceTab = {
} }
this.backgroundUploading = true this.backgroundUploading = true
this.$store.state.api.backendInteractor updateProfileImages({
.updateProfileImages({ background }) background,
credentials: useCredentialsStore().current,
})
.then((data) => { .then((data) => {
this.$store.commit('addNewUsers', [data]) this.$store.commit('addNewUsers', [data])
this.$store.commit('setCurrentUser', data) this.$store.commit('setCurrentUser', data)

View file

@ -11,11 +11,13 @@ import IntegerSetting from '../helpers/integer_setting.vue'
import SharedComputedObject from '../helpers/shared_computed_object.js' import SharedComputedObject from '../helpers/shared_computed_object.js'
import UnitSetting from '../helpers/unit_setting.vue' import UnitSetting from '../helpers/unit_setting.vue'
import { useCredentialsStore } from 'src/stores/credentials.js'
import { useInstanceStore } from 'src/stores/instance.js' import { useInstanceStore } from 'src/stores/instance.js'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js' import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
import { useMergedConfigStore } from 'src/stores/merged_config.js' import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { useSyncConfigStore } from 'src/stores/sync_config.js' import { useSyncConfigStore } from 'src/stores/sync_config.js'
import { updateProfile } from 'src/services/api/api.service.js'
import localeService from 'src/services/locale/locale.service.js' import localeService from 'src/services/locale/locale.service.js'
import { cacheKey, clearCache, emojiCacheKey } from 'src/services/sw/sw.js' import { cacheKey, clearCache, emojiCacheKey } from 'src/services/sw/sw.js'
@ -164,12 +166,13 @@ const ComposingTab = {
), ),
} }
this.$store.state.api.backendInteractor updateProfile({
.updateProfile({ params }) params,
.then((user) => { credentials: useCredentialsStore().current,
this.$store.commit('addNewUsers', [user]) }).then((user) => {
this.$store.commit('setCurrentUser', user) this.$store.commit('addNewUsers', [user])
}) this.$store.commit('setCurrentUser', user)
})
}, },
updateFont(key, value) { updateFont(key, value) {
useSyncConfigStore().setSimplePrefAndSave({ useSyncConfigStore().setSimplePrefAndSave({

View file

@ -4,8 +4,20 @@ import Checkbox from 'src/components/checkbox/checkbox.vue'
import Exporter from 'src/components/exporter/exporter.vue' import Exporter from 'src/components/exporter/exporter.vue'
import Importer from 'src/components/importer/importer.vue' import Importer from 'src/components/importer/importer.vue'
import { useCredentialsStore } from 'src/stores/credentials.js'
import { useOAuthTokensStore } from 'src/stores/oauth_tokens.js' import { useOAuthTokensStore } from 'src/stores/oauth_tokens.js'
import {
addBackup,
exportFriends,
fetchBlocks,
fetchMutes,
importBlocks,
importFollows,
importMutes,
listBackups,
} from 'src/services/api/api.service.js'
const DataImportExportTab = { const DataImportExportTab = {
data() { data() {
return { return {
@ -28,42 +40,51 @@ const DataImportExportTab = {
}, },
computed: { computed: {
...mapState({ ...mapState({
backendInteractor: (state) => state.api.backendInteractor,
user: (state) => state.users.currentUser, user: (state) => state.users.currentUser,
}), }),
}, },
methods: { methods: {
getFollowsContent() { getFollowsContent() {
return this.backendInteractor return exportFriends({
.exportFriends({ id: this.user.id }) id: this.user.id,
.then(this.generateExportableUsersContent) credentials: useCredentialsStore().current,
}).then(this.generateExportableUsersContent)
}, },
getBlocksContent() { getBlocksContent() {
return this.backendInteractor return fetchBlocks({
.fetchBlocks() credentials: useCredentialsStore().current,
.then(this.generateExportableUsersContent) }).then(this.generateExportableUsersContent)
}, },
getMutesContent() { getMutesContent() {
return this.backendInteractor return fetchMutes({
.fetchMutes() credentials: useCredentialsStore().current,
.then(this.generateExportableUsersContent) }).then(this.generateExportableUsersContent)
}, },
importFollows(file) { importFollows(file) {
return this.backendInteractor.importFollows({ file }).then((status) => { return importFollows({
file,
credentials: useCredentialsStore().current,
}).then((status) => {
if (!status) { if (!status) {
throw new Error('failed') throw new Error('failed')
} }
}) })
}, },
importBlocks(file) { importBlocks(file) {
return this.backendInteractor.importBlocks({ file }).then((status) => { return importBlocks({
file,
credentials: useCredentialsStore().current,
}).then((status) => {
if (!status) { if (!status) {
throw new Error('failed') throw new Error('failed')
} }
}) })
}, },
importMutes(file) { importMutes(file) {
return this.backendInteractor.importMutes({ file }).then((status) => { return importMutes({
file,
credentials: useCredentialsStore().current,
}).then((status) => {
if (!status) { if (!status) {
throw new Error('failed') throw new Error('failed')
} }
@ -83,8 +104,9 @@ const DataImportExportTab = {
.join('\n') .join('\n')
}, },
addBackup() { addBackup() {
this.$store.state.api.backendInteractor addBackup({
.addBackup() credentials: useCredentialsStore().current,
})
.then(() => { .then(() => {
this.addedBackup = true this.addedBackup = true
this.addBackupError = false this.addBackupError = false
@ -96,8 +118,9 @@ const DataImportExportTab = {
.then(() => this.fetchBackups()) .then(() => this.fetchBackups())
}, },
fetchBackups() { fetchBackups() {
this.$store.state.api.backendInteractor listBackups({
.listBackups() credentials: useCredentialsStore().current,
})
.then((res) => { .then((res) => {
this.backups = res this.backups = res
this.listBackupsError = false this.listBackupsError = false

View file

@ -8,12 +8,14 @@ import FloatSetting from '../helpers/float_setting.vue'
import SharedComputedObject from '../helpers/shared_computed_object.js' import SharedComputedObject from '../helpers/shared_computed_object.js'
import UnitSetting from '../helpers/unit_setting.vue' import UnitSetting from '../helpers/unit_setting.vue'
import { useCredentialsStore } from 'src/stores/credentials.js'
import { useInstanceStore } from 'src/stores/instance.js' import { useInstanceStore } from 'src/stores/instance.js'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js' import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
import { useLocalConfigStore } from 'src/stores/local_config.js' import { useLocalConfigStore } from 'src/stores/local_config.js'
import { useMergedConfigStore } from 'src/stores/merged_config.js' import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { useSyncConfigStore } from 'src/stores/sync_config.js' import { useSyncConfigStore } from 'src/stores/sync_config.js'
import { updateProfile } from 'src/services/api/api.service.js'
import localeService from 'src/services/locale/locale.service.js' import localeService from 'src/services/locale/locale.service.js'
const GeneralTab = { const GeneralTab = {
@ -58,12 +60,13 @@ const GeneralTab = {
), ),
} }
this.$store.state.api.backendInteractor updateProfile({
.updateProfile({ params }) params,
.then((user) => { credentials: useCredentialsStore().current,
this.$store.commit('addNewUsers', [user]) }).then((user) => {
this.$store.commit('setCurrentUser', user) this.$store.commit('addNewUsers', [user])
}) this.$store.commit('setCurrentUser', user)
})
}, },
updateFont(path, value) { updateFont(path, value) {
useLocalConfigStore().set({ path, value }) useLocalConfigStore().set({ path, value })

View file

@ -9,9 +9,12 @@ import MuteCard from 'src/components/mute_card/mute_card.vue'
import ProgressButton from 'src/components/progress_button/progress_button.vue' import ProgressButton from 'src/components/progress_button/progress_button.vue'
import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx' import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx'
import { useCredentialsStore } from 'src/stores/credentials.js'
import { useInstanceStore } from 'src/stores/instance.js' import { useInstanceStore } from 'src/stores/instance.js'
import { useOAuthTokensStore } from 'src/stores/oauth_tokens.js' import { useOAuthTokensStore } from 'src/stores/oauth_tokens.js'
import { importBlocks, importFollows } from 'src/services/api/api.service.js'
const MutesAndBlocks = { const MutesAndBlocks = {
data() { data() {
return { return {
@ -54,22 +57,24 @@ const MutesAndBlocks = {
return () => this.$store.dispatch('fetch' + group, this.userId) return () => this.$store.dispatch('fetch' + group, this.userId)
}, },
importFollows(file) { importFollows(file) {
return this.$store.state.api.backendInteractor return importFollows({
.importFollows({ file }) file,
.then((status) => { credentials: useCredentialsStore().current,
if (!status) { }).then((status) => {
throw new Error('failed') if (!status) {
} throw new Error('failed')
}) }
})
}, },
importBlocks(file) { importBlocks(file) {
return this.$store.state.api.backendInteractor return importBlocks({
.importBlocks({ file }) file,
.then((status) => { credentials: useCredentialsStore().current,
if (!status) { }).then((status) => {
throw new Error('failed') if (!status) {
} throw new Error('failed')
}) }
})
}, },
generateExportableUsersContent(users) { generateExportableUsersContent(users) {
// Get addresses // Get addresses

View file

@ -1,6 +1,10 @@
import BooleanSetting from '../helpers/boolean_setting.vue' import BooleanSetting from '../helpers/boolean_setting.vue'
import SharedComputedObject from '../helpers/shared_computed_object.js' import SharedComputedObject from '../helpers/shared_computed_object.js'
import { useCredentialsStore } from 'src/stores/credentials.js'
import { updateNotificationSettings } from 'src/services/api/api.service.js'
const NotificationsTab = { const NotificationsTab = {
data() { data() {
return { return {
@ -27,7 +31,8 @@ const NotificationsTab = {
}, },
methods: { methods: {
updateNotificationSettings() { updateNotificationSettings() {
this.$store.state.api.backendInteractor.updateNotificationSettings({ updateNotificationSettings({
credentials: useCredentialsStore().current,
settings: this.notificationSettings, settings: this.notificationSettings,
}) })
}, },

View file

@ -3,6 +3,10 @@ import UserCard from 'src/components/user_card/user_card.vue'
import BooleanSetting from '../helpers/boolean_setting.vue' import BooleanSetting from '../helpers/boolean_setting.vue'
import SharedComputedObject from '../helpers/shared_computed_object.js' import SharedComputedObject from '../helpers/shared_computed_object.js'
import { useCredentialsStore } from 'src/stores/credentials.js'
import { updateProfile } from 'src/services/api/api.service.js'
import { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'
import { import {
faCircleNotch, faCircleNotch,
@ -35,9 +39,10 @@ const ProfileTab = {
const params = { const params = {
locked: this.locked, locked: this.locked,
} }
updateProfile({
this.$store.state.api.backendInteractor params,
.updateProfile({ params }) credentials: useCredentialsStore().current,
})
.then((user) => { .then((user) => {
this.$store.commit('addNewUsers', [user]) this.$store.commit('addNewUsers', [user])
this.$store.commit('setCurrentUser', user) this.$store.commit('setCurrentUser', user)

View file

@ -5,6 +5,15 @@ import Confirm from './confirm.vue'
import RecoveryCodes from './mfa_backup_codes.vue' import RecoveryCodes from './mfa_backup_codes.vue'
import TOTP from './mfa_totp.vue' import TOTP from './mfa_totp.vue'
import { useCredentialsStore } from 'src/stores/credentials.js'
import {
generateMfaBackupCodes,
mfaConfirmOTP,
mfaSetupOTP,
settingsMFA,
} from 'src/services/api/api.service.js'
const Mfa = { const Mfa = {
data: () => ({ data: () => ({
settings: { settings: {
@ -71,9 +80,6 @@ const Mfa = {
confirmNewBackupCodes() { confirmNewBackupCodes() {
return this.backupCodes.getNewCodes return this.backupCodes.getNewCodes
}, },
...mapState({
backendInteractor: (state) => state.api.backendInteractor,
}),
}, },
methods: { methods: {
@ -87,7 +93,9 @@ const Mfa = {
this.backupCodes.inProgress = true this.backupCodes.inProgress = true
this.backupCodes.codes = [] this.backupCodes.codes = []
return this.backendInteractor.generateMfaBackupCodes().then((res) => { return generateMfaBackupCodes({
credentials: useCredentialsStore().current,
}).then((res) => {
this.backupCodes.codes = res.codes this.backupCodes.codes = res.codes
this.backupCodes.inProgress = false this.backupCodes.inProgress = false
}) })
@ -112,7 +120,9 @@ const Mfa = {
// prepare setup OTP // prepare setup OTP
this.setupState.state = 'setupOTP' this.setupState.state = 'setupOTP'
this.setupState.setupOTPState = 'prepare' this.setupState.setupOTPState = 'prepare'
this.backendInteractor.mfaSetupOTP().then((res) => { mfaSetupOTP({
credentials: useCredentialsStore().current,
}).then((res) => {
this.otpSettings = res this.otpSettings = res
this.setupState.setupOTPState = 'confirm' this.setupState.setupOTPState = 'confirm'
}) })
@ -120,18 +130,17 @@ const Mfa = {
doConfirmOTP() { doConfirmOTP() {
// handler confirm enable OTP // handler confirm enable OTP
this.error = null this.error = null
this.backendInteractor mfaConfirmOTP({
.mfaConfirmOTP({ token: this.otpConfirmToken,
token: this.otpConfirmToken, password: this.currentPassword,
password: this.currentPassword, credentials: useCredentialsStore().current,
}) }).then((res) => {
.then((res) => { if (res.error) {
if (res.error) { this.error = res.error
this.error = res.error return
return }
} this.completeSetup()
this.completeSetup() })
})
}, },
completeSetup() { completeSetup() {
@ -152,7 +161,9 @@ const Mfa = {
// fetch settings from server // fetch settings from server
async fetchSettings() { async fetchSettings() {
const result = await this.backendInteractor.settingsMFA() const result = await settingsMFA({
credentials: useCredentialsStore().current,
})
if (result.error) return if (result.error) return
this.settings = result.settings this.settings = result.settings
this.settings.available = true this.settings.available = true

View file

@ -2,6 +2,10 @@ import { mapState } from 'vuex'
import Confirm from './confirm.vue' import Confirm from './confirm.vue'
import { useCredentialsStore } from 'src/stores/credentials.js'
import { mfaDisableOTP } from 'src/services/api/api.service.js'
export default { export default {
props: ['settings'], props: ['settings'],
data: () => ({ data: () => ({
@ -17,9 +21,6 @@ export default {
isActivated() { isActivated() {
return this.settings.totp return this.settings.totp
}, },
...mapState({
backendInteractor: (state) => state.api.backendInteractor,
}),
}, },
methods: { methods: {
doActivate() { doActivate() {
@ -36,19 +37,18 @@ export default {
// confirm deactivate TOTP method // confirm deactivate TOTP method
this.error = null this.error = null
this.inProgress = true this.inProgress = true
this.backendInteractor mfaDisableOTP({
.mfaDisableOTP({ password: this.currentPassword,
password: this.currentPassword, credentials: useCredentialsStore().current,
}) }).then((res) => {
.then((res) => { this.inProgress = false
this.inProgress = false if (res.error) {
if (res.error) { this.error = res.error
this.error = res.error return
return }
} this.deactivate = false
this.deactivate = false this.$emit('deactivate')
this.$emit('deactivate') })
})
}, },
}, },
} }

View file

@ -2,10 +2,20 @@ import Checkbox from 'src/components/checkbox/checkbox.vue'
import ProgressButton from 'src/components/progress_button/progress_button.vue' import ProgressButton from 'src/components/progress_button/progress_button.vue'
import Mfa from './mfa.vue' import Mfa from './mfa.vue'
import { useCredentialsStore } from 'src/stores/credentials.js'
import { useInstanceStore } from 'src/stores/instance.js' import { useInstanceStore } from 'src/stores/instance.js'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js' import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
import { useOAuthTokensStore } from 'src/stores/oauth_tokens' import { useOAuthTokensStore } from 'src/stores/oauth_tokens'
import {
addAlias,
changeEmail,
changePassword,
deleteAccount,
deleteAlias,
listAliases,
moveAccount,
} from 'src/services/api/api.service.js'
import localeService from 'src/services/locale/locale.service.js' import localeService from 'src/services/locale/locale.service.js'
const SecurityTab = { const SecurityTab = {
@ -65,78 +75,79 @@ const SecurityTab = {
this.deletingAccount = true this.deletingAccount = true
}, },
deleteAccount() { deleteAccount() {
this.$store.state.api.backendInteractor deleteAccount({
.deleteAccount({ password: this.deleteAccountConfirmPasswordInput }) credentials: useCredentialsStore().current,
.then((res) => { password: this.deleteAccountConfirmPasswordInput,
if (res.status === 'success') { }).then((res) => {
this.$store.dispatch('logout') if (res.status === 'success') {
this.$router.push({ name: 'root' }) this.$store.dispatch('logout')
} else { this.$router.push({ name: 'root' })
this.deleteAccountError = res.error } else {
} this.deleteAccountError = res.error
}) }
})
}, },
changePassword() { changePassword() {
const params = { const params = {
password: this.changePasswordInputs[0], password: this.changePasswordInputs[0],
newPassword: this.changePasswordInputs[1], newPassword: this.changePasswordInputs[1],
newPasswordConfirmation: this.changePasswordInputs[2], newPasswordConfirmation: this.changePasswordInputs[2],
credentials: useCredentialsStore().current,
} }
this.$store.state.api.backendInteractor changePassword(params).then((res) => {
.changePassword(params) if (res.status === 'success') {
.then((res) => { this.changedPassword = true
if (res.status === 'success') { this.changePasswordError = false
this.changedPassword = true this.logout()
this.changePasswordError = false } else {
this.logout() this.changedPassword = false
} else { this.changePasswordError = res.error
this.changedPassword = false }
this.changePasswordError = res.error })
}
})
}, },
changeEmail() { changeEmail() {
const params = { const params = {
email: this.newEmail, email: this.newEmail,
password: this.changeEmailPassword, password: this.changeEmailPassword,
credentials: useCredentialsStore().current,
} }
this.$store.state.api.backendInteractor changeEmail(params).then((res) => {
.changeEmail(params) if (res.status === 'success') {
.then((res) => { this.changedEmail = true
if (res.status === 'success') { this.changeEmailError = false
this.changedEmail = true } else {
this.changeEmailError = false this.changedEmail = false
} else { this.changeEmailError = res.error
this.changedEmail = false }
this.changeEmailError = res.error })
}
})
}, },
moveAccount() { moveAccount() {
const params = { const params = {
targetAccount: this.moveAccountTarget, targetAccount: this.moveAccountTarget,
password: this.moveAccountPassword, password: this.moveAccountPassword,
credentials: useCredentialsStore().current,
} }
this.$store.state.api.backendInteractor moveAccount(params).then((res) => {
.moveAccount(params) if (res.status === 'success') {
.then((res) => { this.movedAccount = true
if (res.status === 'success') { this.moveAccountError = false
this.movedAccount = true } else {
this.moveAccountError = false this.movedAccount = false
} else { this.moveAccountError = res.error
this.movedAccount = false }
this.moveAccountError = res.error })
}
})
}, },
removeAlias(alias) { removeAlias(alias) {
this.$store.state.api.backendInteractor deleteAlias({
.deleteAlias({ alias }) alias,
.then(() => this.fetchAliases()) credentials: useCredentialsStore().current,
}).then(() => this.fetchAliases())
}, },
addAlias() { addAlias() {
this.$store.state.api.backendInteractor addAlias({
.addAlias({ alias: this.addAliasTarget }) alias: this.addAliasTarget,
credentials: useCredentialsStore().current,
})
.then(() => { .then(() => {
this.addedAlias = true this.addedAlias = true
this.addAliasError = false this.addAliasError = false
@ -149,8 +160,9 @@ const SecurityTab = {
.then(() => this.fetchAliases()) .then(() => this.fetchAliases())
}, },
fetchAliases() { fetchAliases() {
this.$store.state.api.backendInteractor listAliases({
.listAliases() credentials: useCredentialsStore().current,
})
.then((res) => { .then((res) => {
this.aliases = res.aliases this.aliases = res.aliases
this.listAliasesError = false this.listAliasesError = false

View file

@ -2,6 +2,7 @@ import Popover from 'components/popover/popover.vue'
import SelectComponent from 'components/select/select.vue' import SelectComponent from 'components/select/select.vue'
import { mapState } from 'pinia' import { mapState } from 'pinia'
import { useAdminSettingsStore } from 'src/stores/admin_settings'
import { useEmojiStore } from 'src/stores/emoji' import { useEmojiStore } from 'src/stores/emoji'
import { useInterfaceStore } from 'src/stores/interface' import { useInterfaceStore } from 'src/stores/interface'
@ -37,7 +38,7 @@ export default {
}) })
}, },
copyToLocalPack() { copyToLocalPack() {
this.$store.state.api.backendInteractor useAdminSettingsStore()
.addNewEmojiFile({ .addNewEmojiFile({
packName: this.packName, packName: this.packName,
file: this.$attrs.src, file: this.$attrs.src,

View file

@ -16,6 +16,7 @@ import Select from 'src/components/select/select.vue'
import UserAvatar from 'src/components/user_avatar/user_avatar.vue' import UserAvatar from 'src/components/user_avatar/user_avatar.vue'
import UserLink from 'src/components/user_link/user_link.vue' import UserLink from 'src/components/user_link/user_link.vue'
import { useCredentialsStore } from 'src/stores/credentials.js'
import { useEmojiStore } from 'src/stores/emoji.js' import { useEmojiStore } from 'src/stores/emoji.js'
import { useInstanceStore } from 'src/stores/instance.js' import { useInstanceStore } from 'src/stores/instance.js'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js' import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
@ -25,6 +26,7 @@ import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { usePostStatusStore } from 'src/stores/post_status' import { usePostStatusStore } from 'src/stores/post_status'
import { useUserHighlightStore } from 'src/stores/user_highlight.js' import { useUserHighlightStore } from 'src/stores/user_highlight.js'
import { updateProfile } from 'src/services/api/api.service.js'
import { propsToNative } from 'src/services/attributes_helper/attributes_helper.service.js' import { propsToNative } from 'src/services/attributes_helper/attributes_helper.service.js'
import localeService from 'src/services/locale/locale.service.js' import localeService from 'src/services/locale/locale.service.js'
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator' import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
@ -597,8 +599,7 @@ export default {
params.header = this.newBannerFile params.header = this.newBannerFile
} }
this.$store.state.api.backendInteractor updateProfile({ params })
.updateProfile({ params })
.then((user) => { .then((user) => {
this.newFields.splice(this.newFields.length) this.newFields.splice(this.newFields.length)
merge(this.newFields, user.fields) merge(this.newFields, user.fields)

View file

@ -5,8 +5,11 @@ import List from 'src/components/list/list.vue'
import Modal from 'src/components/modal/modal.vue' import Modal from 'src/components/modal/modal.vue'
import UserLink from 'src/components/user_link/user_link.vue' import UserLink from 'src/components/user_link/user_link.vue'
import { useCredentialsStore } from 'src/stores/credentials.js'
import { useReportsStore } from 'src/stores/reports.js' import { useReportsStore } from 'src/stores/reports.js'
import { reportUser } from 'src/services/api/api.service.js'
const UserReportingModal = { const UserReportingModal = {
components: { components: {
List, List,
@ -71,9 +74,9 @@ const UserReportingModal = {
comment: this.comment, comment: this.comment,
forward: this.forward, forward: this.forward,
statusIds: [...this.statusIdsToReport], statusIds: [...this.statusIdsToReport],
credentials: useCredentialsStore().current,
} }
this.$store.state.api.backendInteractor reportUser({ ...params })
.reportUser({ ...params })
.then(() => { .then(() => {
this.processing = false this.processing = false
this.resetState() this.resetState()

View file

@ -1,8 +1,11 @@
import FollowCard from 'src/components/follow_card/follow_card.vue' import FollowCard from 'src/components/follow_card/follow_card.vue'
import apiService from '../../services/api/api.service.js' import apiService from '../../services/api/api.service.js'
import { useCredentialsStore } from 'src/stores/credentials.js'
import { useInstanceStore } from 'src/stores/instance.js' import { useInstanceStore } from 'src/stores/instance.js'
import { fetchUser, suggestions } from 'src/services/api/api.service.js'
const WhoToFollow = { const WhoToFollow = {
components: { components: {
FollowCard, FollowCard,
@ -17,21 +20,22 @@ const WhoToFollow = {
}, },
methods: { methods: {
showWhoToFollow(reply) { showWhoToFollow(reply) {
reply.forEach((i) => { reply.forEach(({ id }) => {
this.$store.state.api.backendInteractor fetchUser({
.fetchUser({ id: i.acct }) id,
.then((externalUser) => { credentials: useCredentialsStore().current,
if (!externalUser.error) { }).then((externalUser) => {
this.$store.commit('addNewUsers', [externalUser]) if (!externalUser.error) {
this.users.push(externalUser) this.$store.commit('addNewUsers', [externalUser])
} this.users.push(externalUser)
}) }
})
}) })
}, },
getWhoToFollow() { getWhoToFollow() {
const credentials = this.$store.state.users.currentUser.credentials const credentials = useCredentialsStore().current
if (credentials) { if (credentials) {
apiService.suggestions({ credentials }).then((reply) => { suggestions({ credentials }).then((reply) => {
this.showWhoToFollow(reply) this.showWhoToFollow(reply)
}) })
} }

View file

@ -1,10 +1,10 @@
import { shuffle } from 'lodash' import { shuffle } from 'lodash'
import apiService from '../../services/api/api.service.js' import { useCredentialsStore } from 'src/stores/credentials.js'
import { useInstanceStore } from 'src/stores/instance.js' import { useInstanceStore } from 'src/stores/instance.js'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js' import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
import { fetchUser, suggestions } from 'src/services/api/api.service.js'
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator' import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
function showWhoToFollow(panel, reply) { function showWhoToFollow(panel, reply) {
@ -18,14 +18,15 @@ function showWhoToFollow(panel, reply) {
toFollow.img = img toFollow.img = img
toFollow.name = name toFollow.name = name
panel.$store.state.api.backendInteractor fetchUser({
.fetchUser({ id: name }) id: name,
.then((externalUser) => { credentials: useCredentialsStore().current,
if (!externalUser.error) { }).then((externalUser) => {
panel.$store.commit('addNewUsers', [externalUser]) if (!externalUser.error) {
toFollow.id = externalUser.id panel.$store.commit('addNewUsers', [externalUser])
} toFollow.id = externalUser.id
}) }
})
}) })
} }
@ -35,7 +36,7 @@ function getWhoToFollow(panel) {
panel.usersToFollow.forEach((toFollow) => { panel.usersToFollow.forEach((toFollow) => {
toFollow.name = 'Loading...' toFollow.name = 'Loading...'
}) })
apiService.suggestions({ credentials }).then((reply) => { suggestions({ credentials }).then((reply) => {
showWhoToFollow(panel, reply) showWhoToFollow(panel, reply)
}) })
} }

View file

@ -1,20 +1,28 @@
import { Socket } from 'phoenix' import { Socket } from 'phoenix'
import { WSConnectionStatus } from '../services/api/api.service.js' import { WSConnectionStatus } from '../services/api/api.service.js'
import backendInteractorService from '../services/backend_interactor_service/backend_interactor_service.js'
import { maybeShowChatNotification } from '../services/chat_utils/chat_utils.js' import { maybeShowChatNotification } from '../services/chat_utils/chat_utils.js'
import { useCredentialsStore } from 'src/stores/credentials.js'
import { useInstanceStore } from 'src/stores/instance.js' import { useInstanceStore } from 'src/stores/instance.js'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js' import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
import { useInterfaceStore } from 'src/stores/interface.js' import { useInterfaceStore } from 'src/stores/interface.js'
import { useShoutStore } from 'src/stores/shout.js' import { useShoutStore } from 'src/stores/shout.js'
import {
fetchTimeline,
getMastodonSocketURI,
ProcessedWS,
} from 'src/services/api/api.service.js'
import followRequestFetcher from 'src/services/follow_request_fetcher/follow_request_fetcher.service'
import notificationsFetcher from 'src/services/notifications_fetcher/notifications_fetcher.service.js'
import timelineFetcher from 'src/services/timeline_fetcher/timeline_fetcher.service.js'
const retryTimeout = (multiplier) => 1000 * multiplier const retryTimeout = (multiplier) => 1000 * multiplier
const api = { const api = {
state: { state: {
retryMultiplier: 1, retryMultiplier: 1,
backendInteractor: backendInteractorService(),
fetchers: {}, fetchers: {},
socket: null, socket: null,
mastoUserSocket: null, mastoUserSocket: null,
@ -25,9 +33,6 @@ const api = {
followRequestCount: (state) => state.followRequests.length, followRequestCount: (state) => state.followRequests.length,
}, },
mutations: { mutations: {
setBackendInteractor(state, backendInteractor) {
state.backendInteractor = backendInteractor
},
addFetcher(state, { fetcherName, fetcher }) { addFetcher(state, { fetcherName, fetcher }) {
state.fetchers[fetcherName] = fetcher state.fetchers[fetcherName] = fetcher
}, },
@ -91,9 +96,17 @@ const api = {
try { try {
const { state, commit, dispatch, rootState } = store const { state, commit, dispatch, rootState } = store
const timelineData = rootState.statuses.timelines.friends const timelineData = rootState.statuses.timelines.friends
state.mastoUserSocket = state.backendInteractor.startUserSocket({
store, const serv = useInstanceStore().server.replace('http', 'ws')
const credentials = useCredentialsStore().current
const url = getMastodonSocketURI({ credentials }, serv)
state.mastoUserSocket = ProcessedWS({
url,
id: 'Unified',
credentials,
}) })
state.mastoUserSocket.addEventListener( state.mastoUserSocket.addEventListener(
'pleroma:authenticated', 'pleroma:authenticated',
() => { () => {
@ -245,7 +258,7 @@ const api = {
return return
if (store.state.fetchers[timeline]) return if (store.state.fetchers[timeline]) return
const fetcher = store.state.backendInteractor.startFetchingTimeline({ const fetcher = timelineFetcher.startFetching({
timeline, timeline,
store, store,
userId, userId,
@ -253,7 +266,9 @@ const api = {
statusId, statusId,
bookmarkFolderId, bookmarkFolderId,
tag, tag,
credentials: useCredentialsStore().current,
}) })
store.commit('addFetcher', { fetcherName: timeline, fetcher }) store.commit('addFetcher', { fetcherName: timeline, fetcher })
}, },
stopFetchingTimeline(store, timeline) { stopFetchingTimeline(store, timeline) {
@ -261,19 +276,22 @@ const api = {
if (!fetcher) return if (!fetcher) return
store.commit('removeFetcher', { fetcherName: timeline, fetcher }) store.commit('removeFetcher', { fetcherName: timeline, fetcher })
}, },
fetchTimeline(store, { timeline, ...rest }) { fetchTimeline(store, { timeline, ...rest }) {
store.state.backendInteractor.fetchTimeline({ fetchTimeline({
store, store,
timeline, timeline,
...rest, ...rest,
credentials: useCredentialsStore().current,
}) })
}, },
// Notifications // Notifications
startFetchingNotifications(store) { startFetchingNotifications(store) {
if (store.state.fetchers.notifications) return if (store.state.fetchers.notifications) return
const fetcher = store.state.backendInteractor.startFetchingNotifications({ const fetcher = notificationsFetcher.startFetching({
store, store,
credentials: useCredentialsStore().current,
}) })
store.commit('addFetcher', { fetcherName: 'notifications', fetcher }) store.commit('addFetcher', { fetcherName: 'notifications', fetcher })
}, },
@ -282,19 +300,14 @@ const api = {
if (!fetcher) return if (!fetcher) return
store.commit('removeFetcher', { fetcherName: 'notifications', fetcher }) store.commit('removeFetcher', { fetcherName: 'notifications', fetcher })
}, },
fetchNotifications(store, { ...rest }) {
store.state.backendInteractor.fetchNotifications({
store,
...rest,
})
},
// Follow requests // Follow requests
startFetchingFollowRequests(store) { startFetchingFollowRequests(store) {
if (store.state.fetchers.followRequests) return if (store.state.fetchers.followRequests) return
const fetcher = store.state.backendInteractor.startFetchingFollowRequests( const fetcher = followRequestFetcher.startFetchingFollowRequests({
{ store }, store,
) credentials: useCredentialsStore().current,
})
store.commit('addFetcher', { fetcherName: 'followRequests', fetcher }) store.commit('addFetcher', { fetcherName: 'followRequests', fetcher })
}, },
@ -303,39 +316,6 @@ const api = {
if (!fetcher) return if (!fetcher) return
store.commit('removeFetcher', { fetcherName: 'followRequests', fetcher }) store.commit('removeFetcher', { fetcherName: 'followRequests', fetcher })
}, },
removeFollowRequest(store, request) {
const requests = store.state.followRequests.filter((it) => it !== request)
store.commit('setFollowRequests', requests)
},
// Lists
startFetchingLists(store) {
if (store.state.fetchers.lists) return
const fetcher = store.state.backendInteractor.startFetchingLists({
store,
})
store.commit('addFetcher', { fetcherName: 'lists', fetcher })
},
stopFetchingLists(store) {
const fetcher = store.state.fetchers.lists
if (!fetcher) return
store.commit('removeFetcher', { fetcherName: 'lists', fetcher })
},
// Bookmark folders
startFetchingBookmarkFolders(store) {
if (store.state.fetchers.bookmarkFolders) return
if (!useInstanceCapabilitiesStore().pleromaBookmarkFoldersAvailable)
return
const fetcher =
store.state.backendInteractor.startFetchingBookmarkFolders({ store })
store.commit('addFetcher', { fetcherName: 'bookmarkFolders', fetcher })
},
stopFetchingBookmarkFolders(store) {
const fetcher = store.state.fetchers.bookmarkFolders
if (!fetcher) return
store.commit('removeFetcher', { fetcherName: 'bookmarkFolders', fetcher })
},
// Pleroma websocket // Pleroma websocket
setWsToken(store, token) { setWsToken(store, token) {

View file

@ -11,7 +11,11 @@ import { promiseInterval } from '../services/promise_interval/promise_interval.j
import { useCredentialsStore } from 'src/stores/credentials.js' import { useCredentialsStore } from 'src/stores/credentials.js'
import { chats } from 'src/services/api/api.service.js' import {
chats,
deleteChatMessage,
readChat,
} from 'src/services/api/api.service.js'
const emptyChatList = () => ({ const emptyChatList = () => ({
data: [], data: [],
@ -119,11 +123,18 @@ const chatsModule = {
commit('readChat', { id, lastReadId }) commit('readChat', { id, lastReadId })
if (isNewMessage) { if (isNewMessage) {
rootState.api.backendInteractor.readChat({ id, lastReadId }) readChat({
id,
lastReadId,
credentials: useCredentialsStore().current,
})
} }
}, },
deleteChatMessage({ rootState, commit }, value) { deleteChatMessage({ rootState, commit }, value) {
rootState.api.backendInteractor.deleteChatMessage(value) deleteChatMessage({
...value,
credentials: useCredentialsStore().current,
})
commit('deleteChatMessage', { commit, ...value }) commit('deleteChatMessage', { commit, ...value })
}, },
resetChats({ commit, dispatch }) { resetChats({ commit, dispatch }) {

View file

@ -9,11 +9,14 @@ import {
maybeShowNotification, maybeShowNotification,
} from '../services/notification_utils/notification_utils.js' } from '../services/notification_utils/notification_utils.js'
import { useCredentialsStore } from 'src/stores/credentials.js'
import { useI18nStore } from 'src/stores/i18n.js' import { useI18nStore } from 'src/stores/i18n.js'
import { useMergedConfigStore } from 'src/stores/merged_config.js' import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { useReportsStore } from 'src/stores/reports.js' import { useReportsStore } from 'src/stores/reports.js'
import { useSyncConfigStore } from 'src/stores/sync_config.js' import { useSyncConfigStore } from 'src/stores/sync_config.js'
import { dismissNotification } from 'src/services/api/api.service.js'
const emptyNotifications = () => ({ const emptyNotifications = () => ({
desktopNotificationSilence: true, desktopNotificationSilence: true,
maxId: 0, maxId: 0,
@ -176,7 +179,10 @@ export const notifications = {
}, },
dismissNotification({ rootState, commit }, { id }) { dismissNotification({ rootState, commit }, { id }) {
commit('dismissNotification', { id }) commit('dismissNotification', { id })
rootState.api.backendInteractor.dismissNotification({ id }) dismissNotification({
id,
credentials: useCredentialsStore().current,
})
}, },
updateNotification({ commit }, { id, updater }) { updateNotification({ commit }, { id, updater }) {
commit('updateNotification', { id, updater }) commit('updateNotification', { id, updater })

View file

@ -1,28 +1,37 @@
import { get, set } from 'lodash' import { get, set } from 'lodash'
import { useCredentialsStore } from 'src/stores/credentials.js'
import {
updateNotificationSettings,
updateProfile,
} from 'src/services/api/api.service.js'
const defaultApi = ({ rootState, commit }, { path, value }) => { const defaultApi = ({ rootState, commit }, { path, value }) => {
const params = {} const params = {}
set(params, path, value) set(params, path, value)
return rootState.api.backendInteractor return updateProfile({
.updateProfile({ params }) params,
.then((result) => { credentials: useCredentialsStore().current,
commit('addNewUsers', [result]) }).then((result) => {
commit('setCurrentUser', result) commit('addNewUsers', [result])
}) commit('setCurrentUser', result)
})
} }
const notificationsApi = ({ rootState, commit }, { path, value, oldValue }) => { const notificationsApi = ({ rootState, commit }, { path, value, oldValue }) => {
const settings = {} const settings = {}
set(settings, path, value) set(settings, path, value)
return rootState.api.backendInteractor return updateNotificationSettings({
.updateNotificationSettings({ settings }) settings,
.then((result) => { credentials: useCredentialsStore().current,
if (result.status === 'success') { }).then((result) => {
commit('confirmProfileOption', { name, value }) if (result.status === 'success') {
} else { commit('confirmProfileOption', { name, value })
commit('confirmProfileOption', { name, value: oldValue }) } else {
} commit('confirmProfileOption', { name, value: oldValue })
}) }
})
} }
/** /**

View file

@ -14,10 +14,28 @@ import {
} from 'lodash' } from 'lodash'
import { import {
bookmarkStatus,
deleteStatus, deleteStatus,
favorite,
fetchEmojiReactions,
fetchFavoritedByUsers,
fetchPinnedStatuses,
fetchRebloggedByUsers,
fetchScrobbles, fetchScrobbles,
fetchStatus,
fetchStatusHistory, fetchStatusHistory,
fetchStatusSource, fetchStatusSource,
muteConversation,
pinOwnStatus,
reactWithEmoji,
retweet,
search2,
unbookmarkStatus,
unfavorite,
unmuteConversation,
unpinOwnStatus,
unreactWithEmoji,
unretweet,
} from '../services/api/api.service.js' } from '../services/api/api.service.js'
import { useCredentialsStore } from 'src/stores/credentials.js' import { useCredentialsStore } from 'src/stores/credentials.js'
@ -607,9 +625,9 @@ const statuses = {
}) })
}, },
fetchStatus({ rootState, dispatch }, id) { fetchStatus({ rootState, dispatch }, id) {
return rootState.api.backendInteractor return fetchStatus({ id }).then((status) =>
.fetchStatus({ id }) dispatch('addNewStatuses', { statuses: [status] }),
.then((status) => dispatch('addNewStatuses', { statuses: [status] })) )
}, },
fetchStatusSource({ rootState }, status) { fetchStatusSource({ rootState }, status) {
return fetchStatusSource({ return fetchStatusSource({
@ -647,99 +665,111 @@ const statuses = {
favorite({ rootState, commit }, status) { favorite({ rootState, commit }, status) {
// Optimistic favoriting... // Optimistic favoriting...
commit('setFavorited', { status, value: true }) commit('setFavorited', { status, value: true })
rootState.api.backendInteractor favorite({
.favorite({ id: status.id }) id: status.id,
.then((status) => credentials: useCredentialsStore().current,
commit('setFavoritedConfirm', { }).then((status) =>
status, commit('setFavoritedConfirm', {
user: rootState.users.currentUser, status,
}), user: rootState.users.currentUser,
) }),
)
}, },
unfavorite({ rootState, commit }, status) { unfavorite({ rootState, commit }, status) {
// Optimistic unfavoriting... // Optimistic unfavoriting...
commit('setFavorited', { status, value: false }) commit('setFavorited', { status, value: false })
rootState.api.backendInteractor unfavorite({
.unfavorite({ id: status.id }) id: status.id,
.then((status) => credentials: useCredentialsStore().current,
commit('setFavoritedConfirm', { }).then((status) =>
status, commit('setFavoritedConfirm', {
user: rootState.users.currentUser, status,
}), user: rootState.users.currentUser,
) }),
)
}, },
fetchPinnedStatuses({ rootState, dispatch }, userId) { fetchPinnedStatuses({ rootState, dispatch }, userId) {
rootState.api.backendInteractor fetchPinnedStatuses({
.fetchPinnedStatuses({ id: userId }) id: userId,
.then((statuses) => credentials: useCredentialsStore().current,
dispatch('addNewStatuses', { }).then((statuses) =>
statuses, dispatch('addNewStatuses', {
timeline: 'user', statuses,
userId, timeline: 'user',
showImmediately: true, userId,
noIdUpdate: true, showImmediately: true,
}), noIdUpdate: true,
) }),
)
}, },
pinStatus({ rootState, dispatch }, statusId) { pinStatus({ rootState, dispatch }, statusId) {
return rootState.api.backendInteractor return pinOwnStatus({
.pinOwnStatus({ id: statusId }) id: statusId,
.then((status) => dispatch('addNewStatuses', { statuses: [status] })) credentials: useCredentialsStore().current,
}).then((status) => dispatch('addNewStatuses', { statuses: [status] }))
}, },
unpinStatus({ rootState, dispatch }, statusId) { unpinStatus({ rootState, dispatch }, statusId) {
return rootState.api.backendInteractor return unpinOwnStatus({
.unpinOwnStatus({ id: statusId }) id: statusId,
.then((status) => dispatch('addNewStatuses', { statuses: [status] })) credentials: useCredentialsStore().current,
}).then((status) => dispatch('addNewStatuses', { statuses: [status] }))
}, },
muteConversation({ rootState, commit }, { id: statusId }) { muteConversation({ rootState, commit }, { id: statusId }) {
return rootState.api.backendInteractor return muteConversation({
.muteConversation({ id: statusId }) id: statusId,
.then((status) => commit('setMutedStatus', status)) credentials: useCredentialsStore().current,
}).then((status) => commit('setMutedStatus', status))
}, },
unmuteConversation({ rootState, commit }, { id: statusId }) { unmuteConversation({ rootState, commit }, { id: statusId }) {
return rootState.api.backendInteractor return unmuteConversation({
.unmuteConversation({ id: statusId }) id: statusId,
.then((status) => commit('setMutedStatus', status)) credentials: useCredentialsStore().current,
}).then((status) => commit('setMutedStatus', status))
}, },
retweet({ rootState, commit }, status) { retweet({ rootState, commit }, status) {
// Optimistic retweeting... // Optimistic retweeting...
commit('setRetweeted', { status, value: true }) commit('setRetweeted', { status, value: true })
rootState.api.backendInteractor retweet({
.retweet({ id: status.id }) id: status.id,
.then((status) => credentials: useCredentialsStore().current,
commit('setRetweetedConfirm', { }).then((status) =>
status: status.retweeted_status, commit('setRetweetedConfirm', {
user: rootState.users.currentUser, status: status.retweeted_status,
}), user: rootState.users.currentUser,
) }),
)
}, },
unretweet({ rootState, commit }, status) { unretweet({ rootState, commit }, status) {
// Optimistic unretweeting... // Optimistic unretweeting...
commit('setRetweeted', { status, value: false }) commit('setRetweeted', { status, value: false })
rootState.api.backendInteractor unretweet({
.unretweet({ id: status.id }) id: status.id,
.then((status) => credentials: useCredentialsStore().current,
commit('setRetweetedConfirm', { }).then((status) =>
status, commit('setRetweetedConfirm', {
user: rootState.users.currentUser, status,
}), user: rootState.users.currentUser,
) }),
)
}, },
bookmark({ rootState, commit }, status) { bookmark({ rootState, commit }, status) {
commit('setBookmarked', { status, value: true }) commit('setBookmarked', { status, value: true })
rootState.api.backendInteractor bookmarkStatus({
.bookmarkStatus({ id: status.id, folder_id: status.bookmark_folder_id }) id: status.id,
.then((status) => { folder_id: status.bookmark_folder_id,
commit('setBookmarkedConfirm', { status }) credentials: useCredentialsStore().current,
}) }).then((status) => {
commit('setBookmarkedConfirm', { status })
})
}, },
unbookmark({ rootState, commit }, status) { unbookmark({ rootState, commit }, status) {
commit('setBookmarked', { status, value: false }) commit('setBookmarked', { status, value: false })
rootState.api.backendInteractor unbookmarkStatus({
.unbookmarkStatus({ id: status.id }) id: status.id,
.then((status) => { credentials: useCredentialsStore().current,
commit('setBookmarkedConfirm', { status }) }).then((status) => {
}) commit('setBookmarkedConfirm', { status })
})
}, },
queueFlush({ commit }, { timeline, id }) { queueFlush({ commit }, { timeline, id }) {
commit('queueFlush', { timeline, id }) commit('queueFlush', { timeline, id })
@ -749,8 +779,14 @@ const statuses = {
}, },
fetchFavsAndRepeats({ rootState, commit }, id) { fetchFavsAndRepeats({ rootState, commit }, id) {
Promise.all([ Promise.all([
rootState.api.backendInteractor.fetchFavoritedByUsers({ id }), fetchFavoritedByUsers({
rootState.api.backendInteractor.fetchRebloggedByUsers({ id }), id,
credentials: useCredentialsStore().current,
}),
fetchRebloggedByUsers({
id,
credentials: useCredentialsStore().current,
}),
]).then(([favoritedByUsers, rebloggedByUsers]) => { ]).then(([favoritedByUsers, rebloggedByUsers]) => {
commit('addFavs', { commit('addFavs', {
id, id,
@ -769,7 +805,11 @@ const statuses = {
if (!currentUser) return if (!currentUser) return
commit('addOwnReaction', { id, emoji, currentUser }) commit('addOwnReaction', { id, emoji, currentUser })
rootState.api.backendInteractor.reactWithEmoji({ id, emoji }).then(() => { reactWithEmoji({
id,
emoji,
credentials: useCredentialsStore().current,
}).then(() => {
dispatch('fetchEmojiReactionsBy', id) dispatch('fetchEmojiReactionsBy', id)
}) })
}, },
@ -778,59 +818,70 @@ const statuses = {
if (!currentUser) return if (!currentUser) return
commit('removeOwnReaction', { id, emoji, currentUser }) commit('removeOwnReaction', { id, emoji, currentUser })
rootState.api.backendInteractor unreactWithEmoji({
.unreactWithEmoji({ id, emoji }) id,
.then(() => { emoji,
dispatch('fetchEmojiReactionsBy', id) currentUser: rootState.users.currentUser,
}) }).then(() => {
dispatch('fetchEmojiReactionsBy', id)
})
}, },
fetchEmojiReactionsBy({ rootState, commit }, id) { fetchEmojiReactionsBy({ rootState, commit }, id) {
return rootState.api.backendInteractor return fetchEmojiReactions({
.fetchEmojiReactions({ id }) id,
.then((emojiReactions) => { credentials: useCredentialsStore().current,
commit('addEmojiReactionsBy', { }).then((emojiReactions) => {
id, commit('addEmojiReactionsBy', {
emojiReactions, id,
currentUser: rootState.users.currentUser, emojiReactions,
}) currentUser: rootState.users.currentUser,
}) })
})
}, },
fetchFavs({ rootState, commit }, id) { fetchFavs({ rootState, commit }, id) {
rootState.api.backendInteractor fetchFavoritedByUsers({
.fetchFavoritedByUsers({ id }) id,
.then((favoritedByUsers) => credentials: useCredentialsStore().current,
commit('addFavs', { }).then((favoritedByUsers) =>
id, commit('addFavs', {
favoritedByUsers, id,
currentUser: rootState.users.currentUser, favoritedByUsers,
}), currentUser: rootState.users.currentUser,
) }),
)
}, },
fetchRepeats({ rootState, commit }, id) { fetchRepeats({ rootState, commit }, id) {
rootState.api.backendInteractor fetchRebloggedByUsers({
.fetchRebloggedByUsers({ id }) id,
.then((rebloggedByUsers) => credentials: useCredentialsStore().current,
commit('addRepeats', { }).then((rebloggedByUsers) =>
id, commit('addRepeats', {
rebloggedByUsers, id,
currentUser: rootState.users.currentUser, rebloggedByUsers,
}), currentUser: rootState.users.currentUser,
) }),
)
}, },
search(store, { q, resolve, limit, offset, following, type }) { search(store, { q, resolve, limit, offset, following, type }) {
return store.rootState.api.backendInteractor return search2({
.search2({ q, resolve, limit, offset, following, type }) q,
.then((data) => { resolve,
store.commit('addNewUsers', data.accounts) limit,
store.commit( offset,
'addNewUsers', following,
data.statuses.map((s) => s.user).filter((u) => u), type,
) credentials: useCredentialsStore().current,
data.statuses = store.commit('addNewStatuses', { }).then((data) => {
statuses: data.statuses, store.commit('addNewUsers', data.accounts)
}) store.commit(
return data 'addNewUsers',
data.statuses.map((s) => s.user).filter((u) => u),
)
data.statuses = store.commit('addNewStatuses', {
statuses: data.statuses,
}) })
return data
})
}, },
setVirtualHeight({ commit }, { statusId, height }) { setVirtualHeight({ commit }, { statusId, height }) {
commit('setVirtualHeight', { statusId, height }) commit('setVirtualHeight', { statusId, height })

View file

@ -10,7 +10,6 @@ import {
} from 'lodash' } from 'lodash'
import { register } from '../services/api/api.service.js' import { register } from '../services/api/api.service.js'
import backendInteractorService from '../services/backend_interactor_service/backend_interactor_service.js'
import oauthApi from '../services/new_api/oauth.js' import oauthApi from '../services/new_api/oauth.js'
import { import {
registerPushNotifications, registerPushNotifications,
@ -21,15 +20,35 @@ import {
windowWidth, windowWidth,
} from '../services/window_utils/window_utils' } from '../services/window_utils/window_utils'
import { useBookmarkFoldersStore } from 'src/stores/bookmark_folders.js'
import { useCredentialsStore } from 'src/stores/credentials.js'
import { useEmojiStore } from 'src/stores/emoji.js' import { useEmojiStore } from 'src/stores/emoji.js'
import { useInstanceStore } from 'src/stores/instance.js' import { useInstanceStore } from 'src/stores/instance.js'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js' import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
import { useInterfaceStore } from 'src/stores/interface.js' import { useInterfaceStore } from 'src/stores/interface.js'
import { useListsStore } from 'src/stores/lists.js'
import { useMergedConfigStore } from 'src/stores/merged_config.js' import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { useOAuthStore } from 'src/stores/oauth.js' import { useOAuthStore } from 'src/stores/oauth.js'
import { useSyncConfigStore } from 'src/stores/sync_config.js' import { useSyncConfigStore } from 'src/stores/sync_config.js'
import { useUserHighlightStore } from 'src/stores/user_highlight.js' import { useUserHighlightStore } from 'src/stores/user_highlight.js'
import {
fetchBlocks,
fetchDomainMutes,
fetchFollowers,
fetchFriends,
fetchMutes,
fetchUser,
fetchUserByName,
fetchUserInLists,
fetchUserRelationship,
followUser,
getCaptcha,
muteUser,
searchUsers,
verifyCredentials,
} from 'src/services/api/api.service.js'
// TODO: Unify with mergeOrAdd in statuses.js // TODO: Unify with mergeOrAdd in statuses.js
export const mergeOrAdd = (arr, obj, item) => { export const mergeOrAdd = (arr, obj, item) => {
if (!item) { if (!item) {
@ -72,46 +91,38 @@ const blockUser = (store, args) => {
store.commit('updateUserRelationship', [predictedRelationship]) store.commit('updateUserRelationship', [predictedRelationship])
store.commit('addBlockId', id) store.commit('addBlockId', id)
return store.rootState.api.backendInteractor return blockUser({ id, expiresIn }).then((relationship) => {
.blockUser({ id, expiresIn }) store.commit('updateUserRelationship', [relationship])
.then((relationship) => { store.commit('addBlockId', id)
store.commit('updateUserRelationship', [relationship])
store.commit('addBlockId', id)
store.commit('removeStatus', { timeline: 'friends', userId: id }) store.commit('removeStatus', { timeline: 'friends', userId: id })
store.commit('removeStatus', { timeline: 'public', userId: id }) store.commit('removeStatus', { timeline: 'public', userId: id })
store.commit('removeStatus', { store.commit('removeStatus', {
timeline: 'publicAndExternal', timeline: 'publicAndExternal',
userId: id, userId: id,
})
}) })
})
} }
const unblockUser = (store, id) => { const unblockUser = (store, id) => {
return store.rootState.api.backendInteractor return unblockUser({ id }).then((relationship) =>
.unblockUser({ id }) store.commit('updateUserRelationship', [relationship]),
.then((relationship) => )
store.commit('updateUserRelationship', [relationship]),
)
} }
const removeUserFromFollowers = (store, id) => { const removeUserFromFollowers = (store, id) => {
return store.rootState.api.backendInteractor return removeUserFromFollowers({ id }).then((relationship) =>
.removeUserFromFollowers({ id }) store.commit('updateUserRelationship', [relationship]),
.then((relationship) => )
store.commit('updateUserRelationship', [relationship]),
)
} }
const editUserNote = (store, { id, comment }) => { const editUserNote = (store, { id, comment }) => {
return store.rootState.api.backendInteractor return editUserNote({ id, comment }).then((relationship) =>
.editUserNote({ id, comment }) store.commit('updateUserRelationship', [relationship]),
.then((relationship) => )
store.commit('updateUserRelationship', [relationship]),
)
} }
const muteUser = (store, args) => { const localMuteUser = (store, args) => {
const id = typeof args === 'object' ? args.id : args const id = typeof args === 'object' ? args.id : args
const expiresIn = typeof args === 'object' ? args.expiresIn : 0 const expiresIn = typeof args === 'object' ? args.expiresIn : 0
@ -119,12 +130,14 @@ const muteUser = (store, args) => {
store.commit('updateUserRelationship', [predictedRelationship]) store.commit('updateUserRelationship', [predictedRelationship])
store.commit('addMuteId', id) store.commit('addMuteId', id)
return store.rootState.api.backendInteractor return muteUser({
.muteUser({ id, expiresIn }) id,
.then((relationship) => { expiresIn,
store.commit('updateUserRelationship', [relationship]) credentials: useCredentialsStore().current,
store.commit('addMuteId', id) }).then((relationship) => {
}) store.commit('updateUserRelationship', [relationship])
store.commit('addMuteId', id)
})
} }
const unmuteUser = (store, id) => { const unmuteUser = (store, id) => {
@ -132,39 +145,43 @@ const unmuteUser = (store, id) => {
predictedRelationship.muting = false predictedRelationship.muting = false
store.commit('updateUserRelationship', [predictedRelationship]) store.commit('updateUserRelationship', [predictedRelationship])
return store.rootState.api.backendInteractor return unmuteUser({ id }).then((relationship) =>
.unmuteUser({ id }) store.commit('updateUserRelationship', [relationship]),
.then((relationship) => )
store.commit('updateUserRelationship', [relationship]),
)
} }
const hideReblogs = (store, userId) => { const hideReblogs = (store, userId) => {
return store.rootState.api.backendInteractor return followUser({
.followUser({ id: userId, reblogs: false }) id: userId,
.then((relationship) => { reblogs: false,
store.commit('updateUserRelationship', [relationship]) credentials: useCredentialsStore().current,
}) }).then((relationship) => {
store.commit('updateUserRelationship', [relationship])
})
} }
const showReblogs = (store, userId) => { const showReblogs = (store, userId) => {
return store.rootState.api.backendInteractor return followUser({
.followUser({ id: userId, reblogs: true }) id: userId,
.then((relationship) => reblogs: true,
store.commit('updateUserRelationship', [relationship]), credentials: useCredentialsStore().current,
) }).then((relationship) =>
store.commit('updateUserRelationship', [relationship]),
)
} }
const muteDomain = (store, domain) => { const muteDomain = (store, domain) => {
return store.rootState.api.backendInteractor return muteDomain({
.muteDomain({ domain }) domain,
.then(() => store.commit('addDomainMute', domain)) credentials: useCredentialsStore().current,
}).then(() => store.commit('addDomainMute', domain))
} }
const unmuteDomain = (store, domain) => { const unmuteDomain = (store, domain) => {
return store.rootState.api.backendInteractor return unmuteDomain({
.unmuteDomain({ domain }) domain,
.then(() => store.commit('removeDomainMute', domain)) credentials: useCredentialsStore().current,
}).then(() => store.commit('removeDomainMute', domain))
} }
export const mutations = { export const mutations = {
@ -385,55 +402,60 @@ const users = {
}) })
}, },
fetchUser(store, id) { fetchUser(store, id) {
return store.rootState.api.backendInteractor return fetchUser({
.fetchUser({ id }) id,
.then((user) => { credentials: useCredentialsStore().current,
store.commit('addNewUsers', [user]) }).then((user) => {
return user store.commit('addNewUsers', [user])
}) return user
})
}, },
fetchUserByName(store, name) { fetchUserByName(store, name) {
return store.rootState.api.backendInteractor return fetchUserByName({
.fetchUserByName({ name }) name,
.then((user) => { credentials: useCredentialsStore().current,
store.commit('addNewUsers', [user]) }).then((user) => {
return user store.commit('addNewUsers', [user])
}) return user
})
}, },
fetchUserRelationship(store, id) { fetchUserRelationship(store, id) {
if (store.state.currentUser) { if (store.state.currentUser) {
store.rootState.api.backendInteractor fetchUserRelationship({
.fetchUserRelationship({ id }) id,
.then((relationships) => credentials: useCredentialsStore().current,
store.commit('updateUserRelationship', relationships), }).then((relationships) =>
) store.commit('updateUserRelationship', relationships),
)
} }
}, },
fetchUserInLists(store, id) { fetchUserInLists(store, id) {
if (store.state.currentUser) { if (store.state.currentUser) {
store.rootState.api.backendInteractor fetchUserInLists({
.fetchUserInLists({ id }) id,
.then((inLists) => store.commit('updateUserInLists', { id, inLists })) credentials: useCredentialsStore().current,
}).then((inLists) => store.commit('updateUserInLists', { id, inLists }))
} }
}, },
fetchBlocks(store, args) { fetchBlocks(store, args) {
const { reset } = args || {} const { reset } = args || {}
const maxId = store.state.currentUser.blockIdsMaxId const maxId = store.state.currentUser.blockIdsMaxId
return store.rootState.api.backendInteractor return fetchBlocks({
.fetchBlocks({ maxId }) maxId,
.then((blocks) => { credentials: useCredentialsStore().current,
if (reset) { }).then((blocks) => {
store.commit('saveBlockIds', map(blocks, 'id')) if (reset) {
} else { store.commit('saveBlockIds', map(blocks, 'id'))
map(blocks, 'id').map((id) => store.commit('addBlockId', id)) } else {
} map(blocks, 'id').map((id) => store.commit('addBlockId', id))
if (blocks.length) { }
store.commit('setBlockIdsMaxId', last(blocks).id) if (blocks.length) {
} store.commit('setBlockIdsMaxId', last(blocks).id)
store.commit('addNewUsers', blocks) }
return blocks store.commit('addNewUsers', blocks)
}) return blocks
})
}, },
blockUser(store, data) { blockUser(store, data) {
return blockUser(store, data) return blockUser(store, data)
@ -457,23 +479,24 @@ const users = {
const { reset } = args || {} const { reset } = args || {}
const maxId = store.state.currentUser.muteIdsMaxId const maxId = store.state.currentUser.muteIdsMaxId
return store.rootState.api.backendInteractor return fetchMutes({
.fetchMutes({ maxId }) maxId,
.then((mutes) => { credentials: useCredentialsStore().current,
if (reset) { }).then((mutes) => {
store.commit('saveMuteIds', map(mutes, 'id')) if (reset) {
} else { store.commit('saveMuteIds', map(mutes, 'id'))
map(mutes, 'id').map((id) => store.commit('addMuteId', id)) } else {
} map(mutes, 'id').map((id) => store.commit('addMuteId', id))
if (mutes.length) { }
store.commit('setMuteIdsMaxId', last(mutes).id) if (mutes.length) {
} store.commit('setMuteIdsMaxId', last(mutes).id)
store.commit('addNewUsers', mutes) }
return mutes store.commit('addNewUsers', mutes)
}) return mutes
})
}, },
muteUser(store, data) { muteUser(store, data) {
return muteUser(store, data) return localMuteUser(store, data)
}, },
unmuteUser(store, id) { unmuteUser(store, id) {
return unmuteUser(store, id) return unmuteUser(store, id)
@ -485,18 +508,18 @@ const users = {
return showReblogs(store, id) return showReblogs(store, id)
}, },
muteUsers(store, data = []) { muteUsers(store, data = []) {
return Promise.all(data.map((d) => muteUser(store, d))) return Promise.all(data.map((d) => localMuteUser(store, d)))
}, },
unmuteUsers(store, ids = []) { unmuteUsers(store, ids = []) {
return Promise.all(ids.map((d) => unmuteUser(store, d))) return Promise.all(ids.map((d) => unmuteUser(store, d)))
}, },
fetchDomainMutes(store) { fetchDomainMutes(store) {
return store.rootState.api.backendInteractor return fetchDomainMutes({
.fetchDomainMutes() credentials: useCredentialsStore().current,
.then((domainMutes) => { }).then((domainMutes) => {
store.commit('saveDomainMutes', domainMutes) store.commit('saveDomainMutes', domainMutes)
return domainMutes return domainMutes
}) })
}, },
muteDomain(store, domain) { muteDomain(store, domain) {
return muteDomain(store, domain) return muteDomain(store, domain)
@ -513,24 +536,28 @@ const users = {
fetchFriends({ rootState, commit }, id) { fetchFriends({ rootState, commit }, id) {
const user = rootState.users.usersObject[id] const user = rootState.users.usersObject[id]
const maxId = last(user.friendIds) const maxId = last(user.friendIds)
return rootState.api.backendInteractor return fetchFriends({
.fetchFriends({ id, maxId }) id,
.then((friends) => { maxId,
commit('addNewUsers', friends) credentials: useCredentialsStore().current,
commit('saveFriendIds', { id, friendIds: map(friends, 'id') }) }).then((friends) => {
return friends commit('addNewUsers', friends)
}) commit('saveFriendIds', { id, friendIds: map(friends, 'id') })
return friends
})
}, },
fetchFollowers({ rootState, commit }, id) { fetchFollowers({ rootState, commit }, id) {
const user = rootState.users.usersObject[id] const user = rootState.users.usersObject[id]
const maxId = last(user.followerIds) const maxId = last(user.followerIds)
return rootState.api.backendInteractor return fetchFollowers({
.fetchFollowers({ id, maxId }) id,
.then((followers) => { maxId,
commit('addNewUsers', followers) credentials: useCredentialsStore().current,
commit('saveFollowerIds', { id, followerIds: map(followers, 'id') }) }).then((followers) => {
return followers commit('addNewUsers', followers)
}) commit('saveFollowerIds', { id, followerIds: map(followers, 'id') })
return followers
})
}, },
clearFriends({ commit }, userId) { clearFriends({ commit }, userId) {
commit('clearFriends', userId) commit('clearFriends', userId)
@ -539,18 +566,22 @@ const users = {
commit('clearFollowers', userId) commit('clearFollowers', userId)
}, },
subscribeUser({ rootState, commit }, id) { subscribeUser({ rootState, commit }, id) {
return rootState.api.backendInteractor return followUser({
.followUser({ id, notify: true }) id,
.then((relationship) => notify: true,
commit('updateUserRelationship', [relationship]), credentials: useCredentialsStore().current,
) }).then((relationship) =>
commit('updateUserRelationship', [relationship]),
)
}, },
unsubscribeUser({ rootState, commit }, id) { unsubscribeUser({ rootState, commit }, id) {
return rootState.api.backendInteractor return followUser({
.followUser({ id, notify: false }) id,
.then((relationship) => notify: false,
commit('updateUserRelationship', [relationship]), credentials: useCredentialsStore().current,
) }).then((relationship) =>
commit('updateUserRelationship', [relationship]),
)
}, },
registerPushNotifications(store) { registerPushNotifications(store) {
const token = store.state.currentUser.credentials const token = store.state.currentUser.credentials
@ -611,12 +642,13 @@ const users = {
}) })
}, },
searchUsers({ rootState, commit }, { query }) { searchUsers({ rootState, commit }, { query }) {
return rootState.api.backendInteractor return searchUsers({
.searchUsers({ query }) query,
.then((users) => { credentials: useCredentialsStore().current,
commit('addNewUsers', users) }).then((users) => {
return users commit('addNewUsers', users)
}) return users
})
}, },
async signUp(store, userInfo) { async signUp(store, userInfo) {
const oauthStore = useOAuthStore() const oauthStore = useOAuthStore()
@ -645,8 +677,10 @@ const users = {
throw e throw e
} }
}, },
async getCaptcha(store) { getCaptcha(store) {
return store.rootState.api.backendInteractor.getCaptcha() return getCaptcha({
credentials: useCredentialsStore().current,
})
}, },
logout(store) { logout(store) {
@ -670,13 +704,10 @@ const users = {
store.dispatch('disconnectFromSocket') store.dispatch('disconnectFromSocket')
oauth.clearToken() oauth.clearToken()
store.dispatch('stopFetchingTimeline', 'friends') store.dispatch('stopFetchingTimeline', 'friends')
store.commit( useCredentialsStore().setCredentials(null)
'setBackendInteractor',
backendInteractorService(oauth.getToken),
)
store.dispatch('stopFetchingNotifications') store.dispatch('stopFetchingNotifications')
store.dispatch('stopFetchingLists') useListsStore().stopFetching()
store.dispatch('stopFetchingBookmarkFolders') useBookmarkFoldersStore().stopFetching()
store.dispatch('stopFetchingFollowRequests') store.dispatch('stopFetchingFollowRequests')
store.commit('clearNotifications') store.commit('clearNotifications')
store.commit('resetStatuses') store.commit('resetStatuses')
@ -691,8 +722,9 @@ const users = {
const commit = store.commit const commit = store.commit
const dispatch = store.dispatch const dispatch = store.dispatch
commit('beginLogin') commit('beginLogin')
store.rootState.api.backendInteractor verifyCredentials({
.verifyCredentials(accessToken) credentials: useCredentialsStore().current,
})
.then((data) => { .then((data) => {
if (!data.error) { if (!data.error) {
const user = data const user = data
@ -721,11 +753,8 @@ const users = {
useInterfaceStore().setNotificationPermission(permission), useInterfaceStore().setNotificationPermission(permission),
) )
// Set our new backend interactor // Update credentials
commit( useCredentialsStore().setCredentials(accessToken)
'setBackendInteractor',
backendInteractorService(accessToken),
)
// Do server-side storage migrations // Do server-side storage migrations
@ -764,8 +793,8 @@ const users = {
} }
} }
dispatch('startFetchingLists') useListsStore().startFetching()
dispatch('startFetchingBookmarkFolders') useBookmarkFoldersStore().startFetching()
if (user.locked) { if (user.locked) {
dispatch('startFetchingFollowRequests') dispatch('startFetchingFollowRequests')
@ -799,9 +828,9 @@ const users = {
useInterfaceStore().setLayoutHeight(windowHeight()) useInterfaceStore().setLayoutHeight(windowHeight())
// Fetch our friends // Fetch our friends
store.rootState.api.backendInteractor fetchFriends({ id: user.id }).then((friends) =>
.fetchFriends({ id: user.id }) commit('addNewUsers', friends),
.then((friends) => commit('addNewUsers', friends)) )
} else { } else {
const response = data.error const response = data.error
// Authentication failed // Authentication failed

View file

@ -126,6 +126,10 @@ const PLEROMA_USER_FAVORITES_TIMELINE_URL = (id) =>
const PLEROMA_BOOKMARK_FOLDERS_URL = '/api/v1/pleroma/bookmark_folders' const PLEROMA_BOOKMARK_FOLDERS_URL = '/api/v1/pleroma/bookmark_folders'
const PLEROMA_BOOKMARK_FOLDER_URL = (id) => const PLEROMA_BOOKMARK_FOLDER_URL = (id) =>
`/api/v1/pleroma/bookmark_folders/${id}` `/api/v1/pleroma/bookmark_folders/${id}`
const EMOJI_PACKS_URL = (page, pageSize) =>
`/api/v1/pleroma/emoji/packs?page=${page}&page_size=${pageSize}`
export const updateNotificationSettings = ({ credentials, settings }) => { export const updateNotificationSettings = ({ credentials, settings }) => {
const form = new FormData() const form = new FormData()
@ -682,6 +686,11 @@ export const fetchTimeline = ({
}) })
} }
export const listEmojiPacks = ({ page, pageSize, credentials }) =>
promisedRequest({
url: EMOJI_PACKS_URL(page, pageSize),
})
export const fetchPinnedStatuses = ({ id, credentials }) => export const fetchPinnedStatuses = ({ id, credentials }) =>
promisedRequest({ promisedRequest({
url: MASTODON_USER_TIMELINE_URL(id) + '?pinned=true', url: MASTODON_USER_TIMELINE_URL(id) + '?pinned=true',

View file

@ -1,72 +0,0 @@
import bookmarkFoldersFetcher from '../../services/bookmark_folders_fetcher/bookmark_folders_fetcher.service.js'
import followRequestFetcher from '../../services/follow_request_fetcher/follow_request_fetcher.service'
import listsFetcher from '../../services/lists_fetcher/lists_fetcher.service.js'
import * as apiService from '../api/api.service.js'
import notificationsFetcher from '../notifications_fetcher/notifications_fetcher.service.js'
import timelineFetcher from '../timeline_fetcher/timeline_fetcher.service.js'
import { useInstanceStore } from 'src/stores/instance.js'
const backendInteractorService = (credentials) => ({
startFetchingTimeline({
timeline,
store,
userId = false,
listId = false,
statusId = false,
bookmarkFolderId = false,
tag,
}) {
return timelineFetcher.startFetching({
timeline,
store,
credentials,
userId,
listId,
statusId,
bookmarkFolderId,
tag,
})
},
fetchTimeline(args) {
return timelineFetcher.fetchAndUpdate({ ...args, credentials })
},
startFetchingNotifications({ store }) {
return notificationsFetcher.startFetching({ store, credentials })
},
fetchNotifications(args) {
return notificationsFetcher.fetchAndUpdate({ ...args, credentials })
},
startFetchingFollowRequests({ store }) {
return followRequestFetcher.startFetching({ store, credentials })
},
startFetchingLists({ store }) {
return listsFetcher.startFetching({ store, credentials })
},
startFetchingBookmarkFolders({ store }) {
return bookmarkFoldersFetcher.startFetching({ store, credentials })
},
startUserSocket({ store }) {
const serv = useInstanceStore().server.replace('http', 'ws')
const url = apiService.getMastodonSocketURI({}, serv)
return apiService.ProcessedWS({ url, id: 'Unified', credentials })
},
...Object.entries(apiService).reduce((acc, [key, func]) => {
return {
...acc,
[key]: (args) => func({ credentials, ...args }),
}
}, {}),
verifyCredentials: apiService.verifyCredentials,
})
export default backendInteractorService

View file

@ -1,31 +0,0 @@
import { fetchBookmarkFolders } from '../api/api.service.js'
import { promiseInterval } from '../promise_interval/promise_interval.js'
import { useBookmarkFoldersStore } from 'src/stores/bookmark_folders.js'
const fetchAndUpdate = ({ credentials }) => {
return fetchBookmarkFolders({ credentials })
.then(
(bookmarkFolders) => {
useBookmarkFoldersStore().setBookmarkFolders(bookmarkFolders)
},
(rej) => {
console.error(rej)
},
)
.catch((e) => {
console.error(e)
})
}
const startFetching = ({ credentials, store }) => {
const boundFetchAndUpdate = () => fetchAndUpdate({ credentials, store })
boundFetchAndUpdate()
return promiseInterval(boundFetchAndUpdate, 240000)
}
const bookmarkFoldersFetcher = {
startFetching,
}
export default bookmarkFoldersFetcher

View file

@ -1,8 +1,18 @@
import { useCredentialsStore } from 'src/stores/credentials.js'
import {
fetchUserRelationship,
followUser,
unfollowUser,
} from 'src/services/api/api.service.js'
const fetchRelationship = (attempt, userId, store) => const fetchRelationship = (attempt, userId, store) =>
new Promise((resolve, reject) => { new Promise((resolve, reject) => {
setTimeout(() => { setTimeout(() => {
store.state.api.backendInteractor fetchUserRelationship({
.fetchUserRelationship({ id: userId }) id: userId,
credentials: useCredentialsStore().current,
})
.then((relationship) => { .then((relationship) => {
store.commit('updateUserRelationship', [relationship]) store.commit('updateUserRelationship', [relationship])
return relationship return relationship
@ -27,38 +37,40 @@ const fetchRelationship = (attempt, userId, store) =>
export const requestFollow = (userId, store) => export const requestFollow = (userId, store) =>
new Promise((resolve) => { new Promise((resolve) => {
store.state.api.backendInteractor followUser({
.followUser({ id: userId }) id: userId,
.then((updated) => { credentials: useCredentialsStore().current,
store.commit('updateUserRelationship', [updated]) }).then((updated) => {
store.commit('updateUserRelationship', [updated])
if (updated.following || (updated.locked && updated.requested)) { if (updated.following || (updated.locked && updated.requested)) {
// If we get result immediately or the account is locked, just stop. // If we get result immediately or the account is locked, just stop.
resolve() resolve()
return return
} }
// But usually we don't get result immediately, so we ask server // But usually we don't get result immediately, so we ask server
// for updated user profile to confirm if we are following them // for updated user profile to confirm if we are following them
// Sometimes it takes several tries. Sometimes we end up not following // Sometimes it takes several tries. Sometimes we end up not following
// user anyway, probably because they locked themselves and we // user anyway, probably because they locked themselves and we
// don't know that yet. // don't know that yet.
// Recursive Promise, it will call itself up to 3 times. // Recursive Promise, it will call itself up to 3 times.
return fetchRelationship(1, updated, store).then(() => { return fetchRelationship(1, updated, store).then(() => {
resolve() resolve()
})
}) })
})
}) })
export const requestUnfollow = (userId, store) => export const requestUnfollow = (userId, store) =>
new Promise((resolve) => { new Promise((resolve) => {
store.state.api.backendInteractor unfollowUser({
.unfollowUser({ id: userId }) id: userId,
.then((updated) => { credentials: useCredentialsStore().current,
store.commit('updateUserRelationship', [updated]) }).then((updated) => {
resolve({ store.commit('updateUserRelationship', [updated])
updated, resolve({
}) updated,
}) })
})
}) })

View file

@ -1,31 +0,0 @@
import { fetchLists } from '../api/api.service.js'
import { promiseInterval } from '../promise_interval/promise_interval.js'
import { useListsStore } from 'src/stores/lists.js'
const fetchAndUpdate = ({ credentials }) => {
return fetchLists({ credentials })
.then(
(lists) => {
useListsStore().setLists(lists)
},
(rej) => {
console.error(rej)
},
)
.catch((e) => {
console.error(e)
})
}
const startFetching = ({ credentials, store }) => {
const boundFetchAndUpdate = () => fetchAndUpdate({ credentials, store })
boundFetchAndUpdate()
return promiseInterval(boundFetchAndUpdate, 240000)
}
const listsFetcher = {
startFetching,
}
export default listsFetcher

View file

@ -4,16 +4,26 @@ import { defineStore } from 'pinia'
import { useCredentialsStore } from 'src/stores/credentials.js' import { useCredentialsStore } from 'src/stores/credentials.js'
import { import {
addNewEmojiFile,
changeStatusScope, changeStatusScope,
createEmojiPack,
deleteAccounts, deleteAccounts,
deleteEmojiPack,
disableMFA, disableMFA,
downloadRemoteEmojiPack,
downloadRemoteEmojiPackZIP,
getAvailableFrontends, getAvailableFrontends,
getInstanceConfigDescriptions, getInstanceConfigDescriptions,
getInstanceDBConfig, getInstanceDBConfig,
getUserData, getUserData,
importEmojiFromFS,
installFrontend,
listEmojiPacks,
listRemoteEmojiPacks,
listStatuses, listStatuses,
listUsers, listUsers,
pushInstanceDBConfig, pushInstanceDBConfig,
reloadEmoji,
requirePasswordChange, requirePasswordChange,
resendConfirmationEmail, resendConfirmationEmail,
setUsersActivationStatus, setUsersActivationStatus,
@ -342,6 +352,12 @@ export const useAdminSettingsStore = defineStore('adminSettings', {
}) })
}, },
installFrontend() {
return installFrontend({
credentials: useCredentialsStore().current,
})
},
// Statuses stuff // Statuses stuff
async fetchStatuses(opts) { async fetchStatuses(opts) {
const { total, activities } = await listStatuses({ const { total, activities } = await listStatuses({
@ -526,5 +542,62 @@ export const useAdminSettingsStore = defineStore('adminSettings', {
window.vuex.commit('updateUserAdminData', { user }) window.vuex.commit('updateUserAdminData', { user })
}) })
}, },
reloadEmoji() {
return reloadEmoji({ credentials: useCredentialsStore().current })
},
importEmojiFromFS() {
return importEmojiFromFS({ credentials: useCredentialsStore().current })
},
listEmojiPacks() {
return listEmojiPacks({ credentials: useCredentialsStore().current })
},
listRemoteEmojiPacks() {
return listRemoteEmojiPacks({
credentials: useCredentialsStore().current,
})
},
addNewEmojiFile({ packName, file, shortcode, filename }) {
return addNewEmojiFile({
packName,
file,
shortcode,
filename,
credentials: useCredentialsStore().current,
})
},
downloadRemoteEmojiPack({ instance, packName, as }) {
return downloadRemoteEmojiPack({
instance,
packName,
as,
credentials: useCredentialsStore().current,
})
},
downloadRemoteEmojiPackZIP({ url, packName }) {
return downloadRemoteEmojiPackZIP({
url,
packName,
credentials: useCredentialsStore().current,
})
},
createEmojiPack({ name }) {
return createEmojiPack({
name,
credentials: useCredentialsStore().current,
})
},
deleteEmojiPack({ name }) {
return createEmojiPack({
name,
credentials: useCredentialsStore().current,
})
},
saveEmojiPackMetadata({ name, newData }) {
return createEmojiPack({
name,
newData,
credentials: useCredentialsStore().current,
})
},
}, },
}) })

View file

@ -6,8 +6,10 @@ import { useCredentialsStore } from 'src/stores/credentials.js'
import { import {
createBookmarkFolder, createBookmarkFolder,
deleteBookmarkFolder, deleteBookmarkFolder,
fetchBookmarkFolders,
updateBookmarkFolder, updateBookmarkFolder,
} from 'src/services/api/api.service.js' } from 'src/services/api/api.service.js'
import { promiseInterval } from 'src/services/promise_interval/promise_interval.js'
export const useBookmarkFoldersStore = defineStore('bookmarkFolders', { export const useBookmarkFoldersStore = defineStore('bookmarkFolders', {
state: () => ({ state: () => ({
@ -24,6 +26,23 @@ export const useBookmarkFoldersStore = defineStore('bookmarkFolders', {
}, },
}, },
actions: { actions: {
startFetching() {
promiseInterval(() => {
this.fetcher = fetchBookmarkFolders({
credentials: useCredentialsStore().current,
})
.then(
(folders) => this.setBookmarkFolders(folders),
(rej) => console.error(rej),
)
.catch((e) => {
console.error(e)
})
}, 240000)
},
stopFetching() {
this.fetcher?.stop()
},
setBookmarkFolders(value) { setBookmarkFolders(value) {
this.allFolders = value this.allFolders = value
}, },

View file

@ -1,9 +1,11 @@
import { merge } from 'lodash' import { merge } from 'lodash'
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { useCredentialsStore } from 'src/stores/credentials.js'
import { useInstanceStore } from 'src/stores/instance.js' import { useInstanceStore } from 'src/stores/instance.js'
import { ensureFinalFallback } from 'src/i18n/languages.js' import { ensureFinalFallback } from 'src/i18n/languages.js'
import { listEmojiPacks } from 'src/services/api/api.service.js'
import { annotationsLoader } from 'virtual:pleroma-fe/emoji-annotations' import { annotationsLoader } from 'virtual:pleroma-fe/emoji-annotations'
@ -183,13 +185,13 @@ export const useEmojiStore = defineStore('emoji', {
async getAdminPacksLocal(refresh) { async getAdminPacksLocal(refresh) {
if (!refresh && this.adminPacksLocal) return this.adminPacksLocal if (!refresh && this.adminPacksLocal) return this.adminPacksLocal
const backendInteractor = window.vuex.state.api.backendInteractor
const listFunction = backendInteractor.listEmojiPacks
this.adminPacksLocalLoading = true this.adminPacksLocalLoading = true
this.adminPacksLocal = await this.getAdminPacks( this.adminPacksLocal = await this.getAdminPacks(
useInstanceStore().server, useInstanceStore().server,
listFunction, () =>
listEmojiPacks({
credentials: useCredentialsStore().current,
}),
) )
this.adminPacksLocalLoading = false this.adminPacksLocalLoading = false
}, },

View file

@ -1,8 +1,23 @@
import { find, remove } from 'lodash' import { find, remove } from 'lodash'
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { useCredentialsStore } from 'src/stores/credentials.js'
import {
addAccountsToList,
createList,
deleteList,
fetchLists,
getList,
getListAccounts,
removeAccountsFromList,
updateList,
} from 'src/services/api/api.service.js'
import { promiseInterval } from 'src/services/promise_interval/promise_interval.js'
export const useListsStore = defineStore('lists', { export const useListsStore = defineStore('lists', {
state: () => ({ state: () => ({
fetcher: null,
allLists: [], allLists: [],
allListsObject: {}, allListsObject: {},
}), }),
@ -18,34 +33,58 @@ export const useListsStore = defineStore('lists', {
}, },
}, },
actions: { actions: {
startFetching() {
promiseInterval(() => {
this.fetcher = fetchLists({
credentials: useCredentialsStore().current,
})
.then(
(lists) => this.setLists(lists),
(rej) => console.error(rej),
)
.catch((e) => {
console.error(e)
})
}, 240000)
},
stopFetching() {
this.fetcher?.stop()
},
setLists(value) { setLists(value) {
this.allLists = value this.allLists = value
}, },
createList({ title }) { createList({ title }) {
return window.vuex.state.api.backendInteractor return createList({
.createList({ title }) title,
.then((list) => { credentials: useCredentialsStore().current,
this.setList({ listId: list.id, title }) }).then((list) => {
return list this.setList({ listId: list.id, title })
}) return list
})
}, },
fetchList({ listId }) { fetchList({ listId }) {
return window.vuex.state.api.backendInteractor return getList({
.getList({ listId }) listId,
.then((list) => this.setList({ listId: list.id, title: list.title })) credentials: useCredentialsStore().current,
}).then((list) => this.setList({ listId: list.id, title: list.title }))
}, },
fetchListAccounts({ listId }) { fetchListAccounts({ listId }) {
return window.vuex.state.api.backendInteractor return getListAccounts({
.getListAccounts({ listId }) listId,
.then((accountIds) => { credentials: useCredentialsStore().current,
if (!this.allListsObject[listId]) { }).then((accountIds) => {
this.allListsObject[listId] = { accountIds: [] } if (!this.allListsObject[listId]) {
} this.allListsObject[listId] = { accountIds: [] }
this.allListsObject[listId].accountIds = accountIds }
}) this.allListsObject[listId].accountIds = accountIds
})
}, },
setList({ listId, title }) { setList({ listId, title }) {
window.vuex.state.api.backendInteractor.updateList({ listId, title }) updateList({
listId,
title,
credentials: useCredentialsStore().current,
})
if (!this.allListsObject[listId]) { if (!this.allListsObject[listId]) {
this.allListsObject[listId] = { accountIds: [] } this.allListsObject[listId] = { accountIds: [] }
@ -68,46 +107,55 @@ export const useListsStore = defineStore('lists', {
} }
this.allListsObject[listId].accountIds = accountIds this.allListsObject[listId].accountIds = accountIds
if (added.length > 0) { if (added.length > 0) {
window.vuex.state.api.backendInteractor.addAccountsToList({ addAccountsToList({
listId, listId,
accountIds: added, accountIds: added,
credentials: useCredentialsStore().current,
}) })
} }
if (removed.length > 0) { if (removed.length > 0) {
window.vuex.state.api.backendInteractor.removeAccountsFromList({ removeAccountsFromList({
listId, listId,
accountIds: removed, accountIds: removed,
credentials: useCredentialsStore().current,
}) })
} }
}, },
addListAccount({ listId, accountId }) { addListAccount({ listId, accountId }) {
return window.vuex.state.api.backendInteractor return addAccountsToList({
.addAccountsToList({ listId, accountIds: [accountId] }) listId,
.then((result) => { accountIds: [accountId],
if (!this.allListsObject[listId]) { credentials: useCredentialsStore().current,
this.allListsObject[listId] = { accountIds: [] } }).then((result) => {
} if (!this.allListsObject[listId]) {
this.allListsObject[listId].accountIds.push(accountId) this.allListsObject[listId] = { accountIds: [] }
return result }
}) this.allListsObject[listId].accountIds.push(accountId)
return result
})
}, },
removeListAccount({ listId, accountId }) { removeListAccount({ listId, accountId }) {
return window.vuex.state.api.backendInteractor return removeAccountsFromList({
.removeAccountsFromList({ listId, accountIds: [accountId] }) listId,
.then((result) => { accountIds: [accountId],
if (!this.allListsObject[listId]) { credentials: useCredentialsStore().current,
this.allListsObject[listId] = { accountIds: [] } }).then((result) => {
} if (!this.allListsObject[listId]) {
const { accountIds } = this.allListsObject[listId] this.allListsObject[listId] = { accountIds: [] }
const set = new Set(accountIds) }
set.delete(accountId) const { accountIds } = this.allListsObject[listId]
this.allListsObject[listId].accountIds = [...set] const set = new Set(accountIds)
set.delete(accountId)
this.allListsObject[listId].accountIds = [...set]
return result return result
}) })
}, },
deleteList({ listId }) { deleteList({ listId }) {
window.vuex.state.api.backendInteractor.deleteList({ listId }) deleteList({
listId,
credentials: useCredentialsStore().current,
})
delete this.allListsObject[listId] delete this.allListsObject[listId]
remove(this.allLists, (list) => list.id === listId) remove(this.allLists, (list) => list.id === listId)

View file

@ -1,25 +1,33 @@
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { useCredentialsStore } from 'src/stores/credentials.js'
import {
fetchOAuthTokens,
revokeOAuthToken,
} from 'src/services/api/api.service.js'
export const useOAuthTokensStore = defineStore('oauthTokens', { export const useOAuthTokensStore = defineStore('oauthTokens', {
state: () => ({ state: () => ({
tokens: [], tokens: [],
}), }),
actions: { actions: {
fetchTokens() { fetchTokens() {
window.vuex.state.api.backendInteractor fetchOAuthTokens({
.fetchOAuthTokens() credentials: useCredentialsStore().current,
.then((tokens) => { }).then((tokens) => {
this.swapTokens(tokens) this.swapTokens(tokens)
}) })
}, },
revokeToken(id) { revokeToken(id) {
window.vuex.state.api.backendInteractor revokeOAuthToken({
.revokeOAuthToken({ id }) id,
.then((response) => { credentials: useCredentialsStore().current,
if (response.status === 201) { }).then((response) => {
this.swapTokens(this.tokens.filter((token) => token.id !== id)) if (response.status === 201) {
} this.swapTokens(this.tokens.filter((token) => token.id !== id))
}) }
})
}, },
swapTokens(tokens) { swapTokens(tokens) {
this.tokens = tokens this.tokens = tokens

View file

@ -1,6 +1,10 @@
import { merge } from 'lodash' import { merge } from 'lodash'
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { useCredentialsStore } from 'src/stores/credentials.js'
import { fetchPoll, vote } from 'src/services/api/api.service.js'
export const usePollsStore = defineStore('polls', { export const usePollsStore = defineStore('polls', {
state: () => ({ state: () => ({
// Contains key = id, value = number of trackers for this poll // Contains key = id, value = number of trackers for this poll
@ -19,16 +23,17 @@ export const usePollsStore = defineStore('polls', {
} }
}, },
updateTrackedPoll(pollId) { updateTrackedPoll(pollId) {
window.vuex.state.api.backendInteractor fetchPoll({
.fetchPoll({ pollId }) pollId,
.then((poll) => { credentials: useCredentialsStore().current,
setTimeout(() => { }).then((poll) => {
if (this.trackedPolls[pollId]) { setTimeout(() => {
this.updateTrackedPoll(pollId) if (this.trackedPolls[pollId]) {
} this.updateTrackedPoll(pollId)
}, 30 * 1000) }
this.mergeOrAddPoll(poll) }, 30 * 1000)
}) this.mergeOrAddPoll(poll)
})
}, },
trackPoll(pollId) { trackPoll(pollId) {
if (!this.trackedPolls[pollId]) { if (!this.trackedPolls[pollId]) {
@ -50,12 +55,14 @@ export const usePollsStore = defineStore('polls', {
} }
}, },
votePoll({ pollId, choices }) { votePoll({ pollId, choices }) {
return window.vuex.state.api.backendInteractor return vote({
.vote({ pollId, choices }) pollId,
.then((poll) => { choices,
this.mergeOrAddPoll(poll) credentials: useCredentialsStore().current,
return poll }).then((poll) => {
}) this.mergeOrAddPoll(poll)
return poll
})
}, },
}, },
}) })

View file

@ -20,6 +20,7 @@ import { toRaw } from 'vue'
import { CURRENT_UPDATE_COUNTER } from 'src/components/update_notification/update_notification.js' import { CURRENT_UPDATE_COUNTER } from 'src/components/update_notification/update_notification.js'
import { useCredentialsStore } from 'src/stores/credentials.js'
import { useInstanceStore } from 'src/stores/instance.js' import { useInstanceStore } from 'src/stores/instance.js'
import { useLocalConfigStore } from 'src/stores/local_config.js' import { useLocalConfigStore } from 'src/stores/local_config.js'
@ -31,6 +32,7 @@ import {
validateSetting, validateSetting,
} from 'src/modules/default_config_state.js' } from 'src/modules/default_config_state.js'
import { oldDefaultConfigSync } from 'src/modules/old_default_config_state.js' import { oldDefaultConfigSync } from 'src/modules/old_default_config_state.js'
import { updateProfileJSON } from 'src/services/api/api.service.js'
export const VERSION = 2 export const VERSION = 2
export const NEW_USER_DATE = new Date('2026-03-16') // date of writing this, basically export const NEW_USER_DATE = new Date('2026-03-16') // date of writing this, basically
@ -789,7 +791,10 @@ export const useSyncConfigStore = defineStore('sync_config', {
if (!needPush) return if (!needPush) return
this.updateCache({ username: window.vuex.state.users.currentUser.fqn }) this.updateCache({ username: window.vuex.state.users.currentUser.fqn })
const params = { pleroma_settings_store: { 'pleroma-fe': this.cache } } const params = { pleroma_settings_store: { 'pleroma-fe': this.cache } }
window.vuex.state.api.backendInteractor.updateProfileJSON({ params }) updateProfileJSON({
params,
credentials: useCredentialsStore().current,
})
}, },
}, },
persist: { persist: {

View file

@ -14,7 +14,10 @@ import {
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { toRaw } from 'vue' import { toRaw } from 'vue'
import { useCredentialsStore } from 'src/stores/credentials.js'
import { storage } from 'src/lib/storage.js' import { storage } from 'src/lib/storage.js'
import { updateProfileJSON } from 'src/services/api/api.service.js'
export const NEW_USER_DATE = new Date('2022-08-04') // date of writing this, basically export const NEW_USER_DATE = new Date('2022-08-04') // date of writing this, basically
@ -344,12 +347,13 @@ export const useUserHighlightStore = defineStore('user_highlight', {
const params = { const params = {
pleroma_settings_store: { user_highlight: this.cache }, pleroma_settings_store: { user_highlight: this.cache },
} }
window.vuex.state.api.backendInteractor updateProfileJSON({
.updateProfileJSON({ params }) params,
.then((user) => { credentials: useCredentialsStore().current,
this.initUserHighlight(user) }).then((user) => {
this.dirty = false this.initUserHighlight(user)
}) this.dirty = false
})
}, },
}, },
persist: { persist: {

View file

@ -4,7 +4,6 @@ import { createStore } from 'vuex'
import UserProfile from 'src/components/user_profile/user_profile.vue' import UserProfile from 'src/components/user_profile/user_profile.vue'
import { getters } from 'src/modules/users.js' import { getters } from 'src/modules/users.js'
import backendInteractorService from 'src/services/backend_interactor_service/backend_interactor_service.js'
const mutations = { const mutations = {
clearTimeline: () => { clearTimeline: () => {
@ -53,10 +52,6 @@ const externalProfileStore = createStore({
actions, actions,
getters: testGetters, getters: testGetters,
state: { state: {
api: {
fetchers: {},
backendInteractor: backendInteractorService(''),
},
interface: { interface: {
browserSupport: '', browserSupport: '',
}, },
@ -116,10 +111,6 @@ const localProfileStore = createStore({
actions, actions,
getters: testGetters, getters: testGetters,
state: { state: {
api: {
fetchers: {},
backendInteractor: backendInteractorService(''),
},
interface: { interface: {
browserSupport: '', browserSupport: '',
}, },