Merge branch 'api-refactor' into shigusegubu-themes3
This commit is contained in:
commit
2e47ce0942
76 changed files with 2737 additions and 2704 deletions
|
|
@ -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'
|
||||||
|
|
@ -38,7 +37,7 @@ import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.j
|
||||||
import { useInterfaceStore } from 'src/stores/interface.js'
|
import { useInterfaceStore } from 'src/stores/interface.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 { useOAuthStore } from 'src/stores/oauth'
|
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'
|
||||||
|
|
||||||
|
|
@ -261,16 +260,6 @@ const getStickers = async ({ store }) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const getAppSecret = async ({ store }) => {
|
|
||||||
const oauth = useOAuthStore()
|
|
||||||
if (oauth.userToken) {
|
|
||||||
store.commit(
|
|
||||||
'setBackendInteractor',
|
|
||||||
backendInteractorService(oauth.getToken),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const resolveStaffAccounts = ({ store, accounts }) => {
|
const resolveStaffAccounts = ({ store, accounts }) => {
|
||||||
const nicknames = accounts.map((uri) => uri.split('/').pop())
|
const nicknames = accounts.map((uri) => uri.split('/').pop())
|
||||||
useInstanceStore().set({
|
useInstanceStore().set({
|
||||||
|
|
@ -461,14 +450,13 @@ const setConfig = async ({ store }) => {
|
||||||
const apiConfig = configInfos[0]
|
const apiConfig = configInfos[0]
|
||||||
const staticConfig = configInfos[1]
|
const staticConfig = configInfos[1]
|
||||||
|
|
||||||
getAppSecret({ store })
|
|
||||||
await setSettings({ store, apiConfig, staticConfig })
|
await setSettings({ store, apiConfig, staticConfig })
|
||||||
}
|
}
|
||||||
|
|
||||||
const checkOAuthToken = async ({ store }) => {
|
const checkOAuthToken = async ({ store }) => {
|
||||||
const oauth = useOAuthStore()
|
const oauth = useOAuthStore()
|
||||||
if (oauth.getUserToken) {
|
if (oauth.userToken) {
|
||||||
return store.dispatch('loginUser', oauth.getUserToken)
|
return store.dispatch('loginUser', oauth.userToken)
|
||||||
}
|
}
|
||||||
return Promise.resolve()
|
return Promise.resolve()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ const AnnouncementsPage = {
|
||||||
canPostAnnouncement() {
|
canPostAnnouncement() {
|
||||||
return (
|
return (
|
||||||
this.currentUser &&
|
this.currentUser &&
|
||||||
this.currentUser.privileges.includes(
|
this.currentUser.privileges.has(
|
||||||
'announcements_manage_announcements',
|
'announcements_manage_announcements',
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
|
||||||
import { faEllipsisH } from '@fortawesome/free-solid-svg-icons'
|
|
||||||
|
|
||||||
library.add(faEllipsisH)
|
|
||||||
|
|
||||||
const BookmarkFolderCard = {
|
|
||||||
props: ['folder', 'allBookmarks'],
|
|
||||||
computed: {
|
|
||||||
firstLetter() {
|
|
||||||
return this.folder ? this.folder.name[0] : null
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
export default BookmarkFolderCard
|
|
||||||
|
|
@ -1,111 +0,0 @@
|
||||||
<template>
|
|
||||||
<div
|
|
||||||
v-if="allBookmarks"
|
|
||||||
class="bookmark-folder-card"
|
|
||||||
>
|
|
||||||
<router-link
|
|
||||||
:to="{ name: 'bookmarks' }"
|
|
||||||
class="bookmark-folder-name"
|
|
||||||
>
|
|
||||||
<span class="icon">
|
|
||||||
<FAIcon
|
|
||||||
fixed-width
|
|
||||||
class="fa-scale-110 menu-icon"
|
|
||||||
icon="bookmark"
|
|
||||||
/>
|
|
||||||
</span>{{ $t('nav.all_bookmarks') }}
|
|
||||||
</router-link>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
v-else
|
|
||||||
class="bookmark-folder-card"
|
|
||||||
>
|
|
||||||
<router-link
|
|
||||||
:to="{ name: 'bookmark-folder', params: { id: folder.id } }"
|
|
||||||
class="bookmark-folder-name"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
v-if="folder.emoji_url"
|
|
||||||
class="iconEmoji iconEmoji-image"
|
|
||||||
:src="folder.emoji_url"
|
|
||||||
:alt="folder.emoji"
|
|
||||||
:title="folder.emoji"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
v-else-if="folder.emoji"
|
|
||||||
class="iconEmoji"
|
|
||||||
>
|
|
||||||
<span>
|
|
||||||
{{ folder.emoji }}
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
v-else-if="firstLetter"
|
|
||||||
class="icon iconLetter fa-scale-110"
|
|
||||||
>{{ firstLetter }}</span>{{ folder.name }}
|
|
||||||
</router-link>
|
|
||||||
<router-link
|
|
||||||
:to="{ name: 'bookmark-folder-edit', params: { id: folder.id } }"
|
|
||||||
class="button-folder-edit"
|
|
||||||
>
|
|
||||||
<FAIcon
|
|
||||||
class="fa-scale-110 fa-old-padding"
|
|
||||||
icon="ellipsis-h"
|
|
||||||
/>
|
|
||||||
</router-link>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script src="./bookmark_folder_card.js"></script>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
.bookmark-folder-card {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
a.bookmark-folder-name {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
flex-grow: 1;
|
|
||||||
|
|
||||||
.icon,
|
|
||||||
.iconLetter,
|
|
||||||
.iconEmoji {
|
|
||||||
display: inline-block;
|
|
||||||
height: 2.5rem;
|
|
||||||
width: 2.5rem;
|
|
||||||
margin-right: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon,
|
|
||||||
.iconLetter {
|
|
||||||
font-size: 1.5rem;
|
|
||||||
line-height: 2.5rem;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconEmoji {
|
|
||||||
text-align: center;
|
|
||||||
object-fit: contain;
|
|
||||||
vertical-align: middle;
|
|
||||||
|
|
||||||
> span {
|
|
||||||
font-size: 1.5rem;
|
|
||||||
line-height: 2.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
img.iconEmoji {
|
|
||||||
padding: 0.25em;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.bookmark-folder-name,
|
|
||||||
.button-folder-edit {
|
|
||||||
margin: 0;
|
|
||||||
padding: 1em;
|
|
||||||
color: var(--link);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
import EmojiPicker from 'src/components/emoji_picker/emoji_picker.vue'
|
import EmojiPicker from 'src/components/emoji_picker/emoji_picker.vue'
|
||||||
import apiService from '../../services/api/api.service'
|
|
||||||
|
|
||||||
import { useBookmarkFoldersStore } from 'src/stores/bookmark_folders.js'
|
import { useBookmarkFoldersStore } from 'src/stores/bookmark_folders.js'
|
||||||
import { useInterfaceStore } from 'src/stores/interface.js'
|
import { useInterfaceStore } from 'src/stores/interface.js'
|
||||||
|
import { useOAuthStore } from 'src/stores/oauth.js'
|
||||||
|
|
||||||
|
import { fetchBookmarkFolders } from 'src/services/api/api.service.js'
|
||||||
|
|
||||||
const BookmarkFolderEdit = {
|
const BookmarkFolderEdit = {
|
||||||
data() {
|
data() {
|
||||||
|
|
@ -22,8 +24,10 @@ const BookmarkFolderEdit = {
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
if (!this.id) return
|
if (!this.id) return
|
||||||
const credentials = this.$store.state.users.currentUser.credentials
|
|
||||||
apiService.fetchBookmarkFolders({ credentials }).then((folders) => {
|
fetchBookmarkFolders({
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
|
}).then((folders) => {
|
||||||
const folder = folders.find((folder) => folder.id === this.id)
|
const folder = folders.find((folder) => folder.id === this.id)
|
||||||
if (!folder) return
|
if (!folder) return
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import BookmarkFolderCard from 'src/components/bookmark_folder_card/bookmark_folder_card.vue'
|
import FolderCard from 'src/components/folder_card/folder_card.vue'
|
||||||
|
|
||||||
import { useBookmarkFoldersStore } from 'src/stores/bookmark_folders.js'
|
import { useBookmarkFoldersStore } from 'src/stores/bookmark_folders.js'
|
||||||
|
|
||||||
|
|
@ -9,7 +9,7 @@ const BookmarkFolders = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
BookmarkFolderCard,
|
FolderCard,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
bookmarkFolders() {
|
bookmarkFolders() {
|
||||||
|
|
|
||||||
|
|
@ -12,14 +12,28 @@
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<BookmarkFolderCard
|
<div class="list-item FolderCard">
|
||||||
:all-bookmarks="true"
|
<router-link
|
||||||
class="list-item"
|
:to="{ name: 'bookmarks' }"
|
||||||
/>
|
class="folder-name"
|
||||||
<BookmarkFolderCard
|
>
|
||||||
|
<span class="icon">
|
||||||
|
<FAIcon
|
||||||
|
fixed-width
|
||||||
|
class="fa-scale-110 menu-icon"
|
||||||
|
icon="bookmark"
|
||||||
|
/>
|
||||||
|
</span>{{ $t('nav.all_bookmarks') }}
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
|
<FolderCard
|
||||||
v-for="folder in bookmarkFolders.slice().reverse()"
|
v-for="folder in bookmarkFolders.slice().reverse()"
|
||||||
:key="folder"
|
:key="folder"
|
||||||
:folder="folder"
|
:name="folder.name"
|
||||||
|
:emoji="folder.emoji"
|
||||||
|
:emoji-url="folder.emoji_url"
|
||||||
|
:link="{ name: 'bookmark-folder', params: { id: folder.id } }"
|
||||||
|
:link-edit="{ name: 'bookmark-folder-edit', params: { id: folder.id } }"
|
||||||
class="list-item"
|
class="list-item"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,13 @@ import {
|
||||||
} from './chat_layout_utils.js'
|
} from './chat_layout_utils.js'
|
||||||
|
|
||||||
import { useInterfaceStore } from 'src/stores/interface.js'
|
import { useInterfaceStore } from 'src/stores/interface.js'
|
||||||
|
import { useOAuthStore } from 'src/stores/oauth.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: useOAuthStore().token,
|
||||||
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: useOAuthStore().token,
|
||||||
})
|
})
|
||||||
} 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: useOAuthStore().token,
|
||||||
|
})
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
this.$store.dispatch('addChatMessages', {
|
this.$store.dispatch('addChatMessages', {
|
||||||
chatId: this.currentChat.id,
|
chatId: this.currentChat.id,
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
:focus {
|
:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
|
|
|
||||||
|
|
@ -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 { useOAuthStore } from 'src/stores/oauth.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: useOAuthStore().token,
|
||||||
|
})
|
||||||
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']),
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,9 @@ import { WSConnectionStatus } from '../../services/api/api.service.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 { useOAuthStore } from 'src/stores/oauth.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 {
|
||||||
|
|
@ -436,22 +439,26 @@ 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: useOAuthStore().token,
|
||||||
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: useOAuthStore().token,
|
||||||
|
})
|
||||||
.then((status) => {
|
.then((status) => {
|
||||||
this.$store.dispatch('addNewStatuses', { statuses: [status] })
|
this.$store.dispatch('addNewStatuses', { statuses: [status] })
|
||||||
this.fetchConversation()
|
this.fetchConversation()
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
|
console.error(error)
|
||||||
this.loadStatusError = error
|
this.loadStatusError = error
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
38
src/components/folder_card/folder_card.js
Normal file
38
src/components/folder_card/folder_card.js
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
|
import { faEllipsisH } from '@fortawesome/free-solid-svg-icons'
|
||||||
|
|
||||||
|
library.add(faEllipsisH)
|
||||||
|
|
||||||
|
const FolderCard = {
|
||||||
|
props: {
|
||||||
|
name: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
emoji: {
|
||||||
|
type: String,
|
||||||
|
required: false,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
emojiUrl: {
|
||||||
|
type: String,
|
||||||
|
required: false,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
link: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
linkEdit: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
firstLetter() {
|
||||||
|
return this.name[0]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FolderCard
|
||||||
84
src/components/folder_card/folder_card.vue
Normal file
84
src/components/folder_card/folder_card.vue
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
<template>
|
||||||
|
<div class="FolderCard">
|
||||||
|
<router-link
|
||||||
|
:to="link"
|
||||||
|
class="folder-name"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
v-if="emojiUrl"
|
||||||
|
class="iconEmoji iconEmoji-image"
|
||||||
|
:src="emojiUrl"
|
||||||
|
:alt="emoji"
|
||||||
|
:title="emoji"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
v-else-if="emoji"
|
||||||
|
class="iconEmoji"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
{{ emoji }}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
v-else-if="firstLetter"
|
||||||
|
class="icon iconLetter fa-scale-110"
|
||||||
|
>{{ firstLetter }}</span>{{ name }}
|
||||||
|
</router-link>
|
||||||
|
<router-link
|
||||||
|
:to="linkEdit"
|
||||||
|
class="button-folder-edit"
|
||||||
|
>
|
||||||
|
<FAIcon
|
||||||
|
class="fa-scale-110 fa-old-padding"
|
||||||
|
icon="ellipsis-h"
|
||||||
|
/>
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script src="./folder_card.js"></script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.FolderCard {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.folder-name {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-grow: 1;
|
||||||
|
|
||||||
|
.icon,
|
||||||
|
.iconLetter,
|
||||||
|
.iconEmoji {
|
||||||
|
display: inline-block;
|
||||||
|
height: 2.5rem;
|
||||||
|
width: 2.5rem;
|
||||||
|
margin-right: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon,
|
||||||
|
.iconLetter {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
line-height: 2.5rem;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.iconEmoji {
|
||||||
|
text-align: center;
|
||||||
|
object-fit: contain;
|
||||||
|
vertical-align: middle;
|
||||||
|
|
||||||
|
> span {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
line-height: 2.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
img.iconEmoji {
|
||||||
|
padding: 0.25em;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -4,6 +4,9 @@ import { notificationsFromStore } from '../../services/notification_utils/notifi
|
||||||
import BasicUserCard from '../basic_user_card/basic_user_card.vue'
|
import BasicUserCard from '../basic_user_card/basic_user_card.vue'
|
||||||
|
|
||||||
import { useMergedConfigStore } from 'src/stores/merged_config.js'
|
import { useMergedConfigStore } from 'src/stores/merged_config.js'
|
||||||
|
import { useOAuthStore } from 'src/stores/oauth.js'
|
||||||
|
|
||||||
|
import { approveUser, denyUser } from 'src/services/api/api.service.js'
|
||||||
|
|
||||||
const FollowRequestCard = {
|
const FollowRequestCard = {
|
||||||
props: ['user'],
|
props: ['user'],
|
||||||
|
|
@ -48,7 +51,10 @@ const FollowRequestCard = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
doApprove() {
|
doApprove() {
|
||||||
this.$store.state.api.backendInteractor.approveUser({ id: this.user.id })
|
approveUser({
|
||||||
|
id: this.user.id,
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
|
})
|
||||||
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: useOAuthStore().token,
|
||||||
this.$store.dispatch('removeFollowRequest', this.user)
|
}).then(() => {
|
||||||
})
|
this.$store.dispatch('dismissNotificationLocal', { id: notifId })
|
||||||
|
this.$store.dispatch('removeFollowRequest', this.user)
|
||||||
|
})
|
||||||
this.hideDenyConfirmDialog()
|
this.hideDenyConfirmDialog()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,10 @@
|
||||||
&:not(:last-child) {
|
&:not(:last-child) {
|
||||||
border-bottom: 1px dotted var(--border);
|
border-bottom: 1px dotted var(--border);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:empty {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import ListsCard from 'src/components/lists_card/lists_card.vue'
|
import FolderCard from 'src/components/folder_card/folder_card.vue'
|
||||||
|
|
||||||
import { useListsStore } from 'src/stores/lists.js'
|
import { useListsStore } from 'src/stores/lists.js'
|
||||||
|
|
||||||
|
|
@ -9,7 +9,7 @@ const Lists = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
ListsCard,
|
FolderCard,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
lists() {
|
lists() {
|
||||||
|
|
|
||||||
|
|
@ -14,10 +14,12 @@
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<ListsCard
|
<FolderCard
|
||||||
v-for="list in lists.slice().reverse()"
|
v-for="list in lists.slice().reverse()"
|
||||||
:key="list"
|
:key="list"
|
||||||
:list="list"
|
:name="list.title"
|
||||||
|
:link="{ name: 'lists-timeline', params: { id: list.id } }"
|
||||||
|
:link-edit="{ name: 'lists-edit', params: { id: list.id } }"
|
||||||
class="list-item"
|
class="list-item"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
|
||||||
import { faEllipsisH } from '@fortawesome/free-solid-svg-icons'
|
|
||||||
|
|
||||||
library.add(faEllipsisH)
|
|
||||||
|
|
||||||
const ListsCard = {
|
|
||||||
props: ['list'],
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ListsCard
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="list-card">
|
|
||||||
<router-link
|
|
||||||
:to="{ name: 'lists-timeline', params: { id: list.id } }"
|
|
||||||
class="list-name"
|
|
||||||
>
|
|
||||||
{{ list.title }}
|
|
||||||
</router-link>
|
|
||||||
<router-link
|
|
||||||
:to="{ name: 'lists-edit', params: { id: list.id } }"
|
|
||||||
class="button-list-edit"
|
|
||||||
>
|
|
||||||
<FAIcon
|
|
||||||
class="fa-scale-110 fa-old-padding"
|
|
||||||
icon="ellipsis-h"
|
|
||||||
/>
|
|
||||||
</router-link>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script src="./lists_card.js"></script>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
.list-card {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-name {
|
|
||||||
flex-grow: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-name,
|
|
||||||
.button-list-edit {
|
|
||||||
margin: 0;
|
|
||||||
padding: 1em;
|
|
||||||
color: var(--link);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -15,8 +15,10 @@ import {
|
||||||
|
|
||||||
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 { useOAuthStore } from 'src/stores/oauth.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: useOAuthStore().token,
|
||||||
|
})
|
||||||
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: useOAuthStore().token,
|
||||||
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()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
import { useOAuthStore } from 'src/stores/oauth.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: useOAuthStore().token,
|
||||||
|
})
|
||||||
.then((externalUser) => {
|
.then((externalUser) => {
|
||||||
if (externalUser.error) {
|
if (externalUser.error) {
|
||||||
this.error = true
|
this.error = true
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
.FrontendsTab {
|
.FrontendsTab {
|
||||||
padding: 0 1em;
|
padding: 0 1em;
|
||||||
|
|
||||||
.cards-list {
|
.cards-list {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,7 @@
|
||||||
<AdminUserCard :user-id="item.id" />
|
<AdminUserCard :user-id="item.id" />
|
||||||
</template>
|
</template>
|
||||||
<template #empty>
|
<template #empty>
|
||||||
<span>{{ $t('admin_dash.users.no_users_found')}}</span>
|
<span>{{ $t('admin_dash.users.no_users_found') }}</span>
|
||||||
</template>
|
</template>
|
||||||
</List>
|
</List>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -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 { useOAuthStore } from 'src/stores/oauth.js'
|
||||||
|
|
||||||
|
import {
|
||||||
|
addNewEmojiFile,
|
||||||
|
deleteEmojiFile,
|
||||||
|
updateEmojiFile,
|
||||||
|
} from 'src/services/api/admin.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: useOAuthStore().token,
|
||||||
})
|
})
|
||||||
.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: useOAuthStore().token,
|
||||||
})
|
})
|
||||||
.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: useOAuthStore().token,
|
||||||
|
})
|
||||||
.then((resp) => resp.json())
|
.then((resp) => resp.json())
|
||||||
.then((resp) => {
|
.then((resp) => {
|
||||||
if (resp.error !== undefined) {
|
if (resp.error !== undefined) {
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,9 @@ import Preview from './old_theme_tab/theme_preview.vue'
|
||||||
|
|
||||||
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 { useOAuthStore } from 'src/stores/oauth.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: useOAuthStore().token,
|
||||||
|
})
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
this.$store.commit('addNewUsers', [data])
|
this.$store.commit('addNewUsers', [data])
|
||||||
this.$store.commit('setCurrentUser', data)
|
this.$store.commit('setCurrentUser', data)
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,10 @@ import UnitSetting from '../helpers/unit_setting.vue'
|
||||||
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 { useOAuthStore } from 'src/stores/oauth.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: useOAuthStore().token,
|
||||||
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({
|
||||||
|
|
|
||||||
|
|
@ -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 { useOAuthStore } from 'src/stores/oauth.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: useOAuthStore().token,
|
||||||
|
}).then(this.generateExportableUsersContent)
|
||||||
},
|
},
|
||||||
getBlocksContent() {
|
getBlocksContent() {
|
||||||
return this.backendInteractor
|
return fetchBlocks({
|
||||||
.fetchBlocks()
|
credentials: useOAuthStore().token,
|
||||||
.then(this.generateExportableUsersContent)
|
}).then(this.generateExportableUsersContent)
|
||||||
},
|
},
|
||||||
getMutesContent() {
|
getMutesContent() {
|
||||||
return this.backendInteractor
|
return fetchMutes({
|
||||||
.fetchMutes()
|
credentials: useOAuthStore().token,
|
||||||
.then(this.generateExportableUsersContent)
|
}).then(this.generateExportableUsersContent)
|
||||||
},
|
},
|
||||||
importFollows(file) {
|
importFollows(file) {
|
||||||
return this.backendInteractor.importFollows({ file }).then((status) => {
|
return importFollows({
|
||||||
|
file,
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
|
}).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: useOAuthStore().token,
|
||||||
|
}).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: useOAuthStore().token,
|
||||||
|
}).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: useOAuthStore().token,
|
||||||
|
})
|
||||||
.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: useOAuthStore().token,
|
||||||
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.backups = res
|
this.backups = res
|
||||||
this.listBackupsError = false
|
this.listBackupsError = false
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,10 @@ 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 { useOAuthStore } from 'src/stores/oauth.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: useOAuthStore().token,
|
||||||
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 })
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,11 @@ 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 { useInstanceStore } from 'src/stores/instance.js'
|
import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
|
import { useOAuthStore } from 'src/stores/oauth.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: useOAuthStore().token,
|
||||||
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: useOAuthStore().token,
|
||||||
if (!status) {
|
}).then((status) => {
|
||||||
throw new Error('failed')
|
if (!status) {
|
||||||
}
|
throw new Error('failed')
|
||||||
})
|
}
|
||||||
|
})
|
||||||
},
|
},
|
||||||
generateExportableUsersContent(users) {
|
generateExportableUsersContent(users) {
|
||||||
// Get addresses
|
// Get addresses
|
||||||
|
|
|
||||||
|
|
@ -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 { useOAuthStore } from 'src/stores/oauth.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: useOAuthStore().token,
|
||||||
settings: this.notificationSettings,
|
settings: this.notificationSettings,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -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 { useOAuthStore } from 'src/stores/oauth.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: useOAuthStore().token,
|
||||||
|
})
|
||||||
.then((user) => {
|
.then((user) => {
|
||||||
this.$store.commit('addNewUsers', [user])
|
this.$store.commit('addNewUsers', [user])
|
||||||
this.$store.commit('setCurrentUser', user)
|
this.$store.commit('setCurrentUser', user)
|
||||||
|
|
|
||||||
|
|
@ -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 { useOAuthStore } from 'src/stores/oauth.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: useOAuthStore().token,
|
||||||
|
}).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: useOAuthStore().token,
|
||||||
|
}).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: useOAuthStore().token,
|
||||||
})
|
}).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: useOAuthStore().token,
|
||||||
|
})
|
||||||
if (result.error) return
|
if (result.error) return
|
||||||
this.settings = result.settings
|
this.settings = result.settings
|
||||||
this.settings.available = true
|
this.settings.available = true
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,10 @@ import { mapState } from 'vuex'
|
||||||
|
|
||||||
import Confirm from './confirm.vue'
|
import Confirm from './confirm.vue'
|
||||||
|
|
||||||
|
import { useOAuthStore } from 'src/stores/oauth.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: useOAuthStore().token,
|
||||||
})
|
}).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')
|
})
|
||||||
})
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,18 @@ import Mfa from './mfa.vue'
|
||||||
|
|
||||||
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 { useOAuthStore } from 'src/stores/oauth.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: useOAuthStore().token,
|
||||||
.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: useOAuthStore().token,
|
||||||
}
|
}
|
||||||
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: useOAuthStore().token,
|
||||||
}
|
}
|
||||||
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: useOAuthStore().token,
|
||||||
}
|
}
|
||||||
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: useOAuthStore().token,
|
||||||
|
}).then(() => this.fetchAliases())
|
||||||
},
|
},
|
||||||
addAlias() {
|
addAlias() {
|
||||||
this.$store.state.api.backendInteractor
|
addAlias({
|
||||||
.addAlias({ alias: this.addAliasTarget })
|
alias: this.addAliasTarget,
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
|
})
|
||||||
.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: useOAuthStore().token,
|
||||||
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.aliases = res.aliases
|
this.aliases = res.aliases
|
||||||
this.listAliasesError = false
|
this.listAliasesError = false
|
||||||
|
|
|
||||||
|
|
@ -131,40 +131,41 @@ const Status = {
|
||||||
Quote: defineAsyncComponent(() => import('src/components/quote/quote.vue')),
|
Quote: defineAsyncComponent(() => import('src/components/quote/quote.vue')),
|
||||||
StatusActionButtons,
|
StatusActionButtons,
|
||||||
},
|
},
|
||||||
props: [
|
props: {
|
||||||
'statusoid',
|
statusoid: Object,
|
||||||
'replies',
|
replies: Array,
|
||||||
|
|
||||||
'expandable',
|
expandable: Boolean,
|
||||||
'focused',
|
focused: Boolean,
|
||||||
'highlight',
|
highlight: Boolean,
|
||||||
'compact',
|
compact: Boolean,
|
||||||
'isPreview',
|
isPreview: Boolean,
|
||||||
'noHeading',
|
noHeading: Boolean,
|
||||||
'inlineExpanded',
|
inlineExpanded: Boolean,
|
||||||
'showPinned',
|
showPinned: Boolean,
|
||||||
'inProfile',
|
inProfile: Boolean,
|
||||||
'inConversation',
|
inConversation: Boolean,
|
||||||
'inQuote',
|
inQuote: Boolean,
|
||||||
'profileUserId',
|
|
||||||
'simpleTree',
|
|
||||||
'showOtherRepliesAsButton',
|
|
||||||
'dive',
|
|
||||||
'ignoreMute',
|
|
||||||
|
|
||||||
'controlledThreadDisplayStatus',
|
profileUserId: String,
|
||||||
'controlledToggleThreadDisplay',
|
simpleTree: Boolean,
|
||||||
'controlledShowingTall',
|
showOtherRepliesAsButton: Boolean,
|
||||||
'controlledToggleShowingTall',
|
dive: Function,
|
||||||
'controlledExpandingSubject',
|
ignoreMute: Boolean,
|
||||||
'controlledToggleExpandingSubject',
|
|
||||||
'controlledShowingLongSubject',
|
controlledThreadDisplayStatus: String,
|
||||||
'controlledToggleShowingLongSubject',
|
controlledToggleThreadDisplay: Function,
|
||||||
'controlledReplying',
|
controlledShowingTall: Boolean,
|
||||||
'controlledToggleReplying',
|
controlledToggleShowingTall: Function,
|
||||||
'controlledMediaPlaying',
|
controlledExpandingSubject: Boolean,
|
||||||
'controlledSetMediaPlaying',
|
controlledToggleExpandingSubject: Function,
|
||||||
],
|
controlledShowingLongSubject: Boolean,
|
||||||
|
controlledToggleShowingLongSubject: Function,
|
||||||
|
controlledReplying: Boolean,
|
||||||
|
controlledToggleReplying: Function,
|
||||||
|
controlledMediaPlaying: Boolean,
|
||||||
|
controlledSetMediaPlaying: Function,
|
||||||
|
},
|
||||||
emits: ['goto', 'toggleExpanded'],
|
emits: ['goto', 'toggleExpanded'],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ const StatusActionButtons = {
|
||||||
button
|
button
|
||||||
.action?.(this.funcArg)
|
.action?.(this.funcArg)
|
||||||
.then(() => this.$emit('onSuccess'))
|
.then(() => this.$emit('onSuccess'))
|
||||||
.catch((err) => this.$emit('onError', err.error.error))
|
.catch((err) => this.$emit('onError', err))
|
||||||
},
|
},
|
||||||
onExtraClose() {
|
onExtraClose() {
|
||||||
this.showPin = false
|
this.showPin = false
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,7 @@
|
||||||
.contents {
|
.contents {
|
||||||
flex: 1 0 auto;
|
flex: 1 0 auto;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
.hidden {
|
.hidden {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,11 @@ import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.j
|
||||||
import { useInterfaceStore } from 'src/stores/interface'
|
import { useInterfaceStore } from 'src/stores/interface'
|
||||||
import { useMediaViewerStore } from 'src/stores/media_viewer'
|
import { useMediaViewerStore } from 'src/stores/media_viewer'
|
||||||
import { useMergedConfigStore } from 'src/stores/merged_config.js'
|
import { useMergedConfigStore } from 'src/stores/merged_config.js'
|
||||||
|
import { useOAuthStore } from 'src/stores/oauth.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'
|
||||||
|
|
@ -307,9 +309,9 @@ export default {
|
||||||
const privileges = this.loggedIn.privileges
|
const privileges = this.loggedIn.privileges
|
||||||
return (
|
return (
|
||||||
this.loggedIn.role === 'admin' ||
|
this.loggedIn.role === 'admin' ||
|
||||||
privileges.includes('users_manage_activation_state') ||
|
privileges.has('users_manage_activation_state') ||
|
||||||
privileges.includes('users_delete') ||
|
privileges.has('users_delete') ||
|
||||||
privileges.includes('users_manage_tags')
|
privileges.has('users_manage_tags')
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
hasNote() {
|
hasNote() {
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@
|
||||||
:statusoid="item"
|
:statusoid="item"
|
||||||
:in-conversation="false"
|
:in-conversation="false"
|
||||||
:focused="false"
|
:focused="false"
|
||||||
|
ignore-mute
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</List>
|
</List>
|
||||||
|
|
|
||||||
|
|
@ -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 { useOAuthStore } from 'src/stores/oauth.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,
|
||||||
|
|
@ -28,6 +31,7 @@ const UserReportingModal = {
|
||||||
return !!this.$store.state.users.currentUser
|
return !!this.$store.state.users.currentUser
|
||||||
},
|
},
|
||||||
isOpen() {
|
isOpen() {
|
||||||
|
console.log(this.reportModal)
|
||||||
return this.isLoggedIn && this.reportModal.activated
|
return this.isLoggedIn && this.reportModal.activated
|
||||||
},
|
},
|
||||||
userId() {
|
userId() {
|
||||||
|
|
@ -70,9 +74,9 @@ const UserReportingModal = {
|
||||||
comment: this.comment,
|
comment: this.comment,
|
||||||
forward: this.forward,
|
forward: this.forward,
|
||||||
statusIds: [...this.statusIdsToReport],
|
statusIds: [...this.statusIdsToReport],
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
}
|
}
|
||||||
this.$store.state.api.backendInteractor
|
reportUser({ ...params })
|
||||||
.reportUser({ ...params })
|
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.processing = false
|
this.processing = false
|
||||||
this.resetState()
|
this.resetState()
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,9 @@ 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 { useInstanceStore } from 'src/stores/instance.js'
|
import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
|
import { useOAuthStore } from 'src/stores/oauth.js'
|
||||||
|
|
||||||
|
import { fetchUser, suggestions } from 'src/services/api/api.service.js'
|
||||||
|
|
||||||
const WhoToFollow = {
|
const WhoToFollow = {
|
||||||
components: {
|
components: {
|
||||||
|
|
@ -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: useOAuthStore().token,
|
||||||
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 = useOAuthStore().token
|
||||||
if (credentials) {
|
if (credentials) {
|
||||||
apiService.suggestions({ credentials }).then((reply) => {
|
suggestions({ credentials }).then((reply) => {
|
||||||
this.showWhoToFollow(reply)
|
this.showWhoToFollow(reply)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
import { shuffle } from 'lodash'
|
import { shuffle } from 'lodash'
|
||||||
|
|
||||||
import apiService from '../../services/api/api.service.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 { useOAuthStore } from 'src/stores/oauth.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: useOAuthStore().token,
|
||||||
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)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 { 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 { useOAuthStore } from 'src/stores/oauth.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 = useOAuthStore().token
|
||||||
|
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: useOAuthStore().token,
|
||||||
})
|
})
|
||||||
|
|
||||||
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: useOAuthStore().token,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
// 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: useOAuthStore().token,
|
||||||
})
|
})
|
||||||
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: useOAuthStore().token,
|
||||||
|
})
|
||||||
|
|
||||||
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) {
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,14 @@ import {
|
||||||
} from '../services/entity_normalizer/entity_normalizer.service.js'
|
} from '../services/entity_normalizer/entity_normalizer.service.js'
|
||||||
import { promiseInterval } from '../services/promise_interval/promise_interval.js'
|
import { promiseInterval } from '../services/promise_interval/promise_interval.js'
|
||||||
|
|
||||||
|
import { useOAuthStore } from 'src/stores/oauth.js'
|
||||||
|
|
||||||
|
import {
|
||||||
|
chats,
|
||||||
|
deleteChatMessage,
|
||||||
|
readChat,
|
||||||
|
} from 'src/services/api/api.service.js'
|
||||||
|
|
||||||
const emptyChatList = () => ({
|
const emptyChatList = () => ({
|
||||||
data: [],
|
data: [],
|
||||||
idStore: {},
|
idStore: {},
|
||||||
|
|
@ -36,7 +44,7 @@ const unreadChatCount = (state) => {
|
||||||
return sumBy(state.chatList.data, 'unread')
|
return sumBy(state.chatList.data, 'unread')
|
||||||
}
|
}
|
||||||
|
|
||||||
const chats = {
|
const chatsModule = {
|
||||||
state: { ...defaultState },
|
state: { ...defaultState },
|
||||||
getters: {
|
getters: {
|
||||||
currentChat: (state) => state.openedChats[state.currentChatId],
|
currentChat: (state) => state.openedChats[state.currentChatId],
|
||||||
|
|
@ -51,7 +59,6 @@ const chats = {
|
||||||
// Chat list
|
// Chat list
|
||||||
startFetchingChats({ dispatch, commit }) {
|
startFetchingChats({ dispatch, commit }) {
|
||||||
const fetcher = () => dispatch('fetchChats', { latest: true })
|
const fetcher = () => dispatch('fetchChats', { latest: true })
|
||||||
fetcher()
|
|
||||||
commit('setChatListFetcher', {
|
commit('setChatListFetcher', {
|
||||||
fetcher: () => promiseInterval(fetcher, 5000),
|
fetcher: () => promiseInterval(fetcher, 5000),
|
||||||
})
|
})
|
||||||
|
|
@ -60,8 +67,10 @@ const chats = {
|
||||||
commit('setChatListFetcher', { fetcher: undefined })
|
commit('setChatListFetcher', { fetcher: undefined })
|
||||||
},
|
},
|
||||||
fetchChats({ dispatch, rootState }) {
|
fetchChats({ dispatch, rootState }) {
|
||||||
return rootState.api.backendInteractor.chats().then(({ chats }) => {
|
return chats({
|
||||||
dispatch('addNewChats', { chats })
|
credentials: useOAuthStore().token,
|
||||||
|
}).then(({ chatList }) => {
|
||||||
|
dispatch('addNewChats', { chats: chatList })
|
||||||
return chats
|
return chats
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
@ -113,11 +122,18 @@ const chats = {
|
||||||
commit('readChat', { id, lastReadId })
|
commit('readChat', { id, lastReadId })
|
||||||
|
|
||||||
if (isNewMessage) {
|
if (isNewMessage) {
|
||||||
rootState.api.backendInteractor.readChat({ id, lastReadId })
|
readChat({
|
||||||
|
id,
|
||||||
|
lastReadId,
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
deleteChatMessage({ rootState, commit }, value) {
|
deleteChatMessage({ rootState, commit }, value) {
|
||||||
rootState.api.backendInteractor.deleteChatMessage(value)
|
deleteChatMessage({
|
||||||
|
...value,
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
|
})
|
||||||
commit('deleteChatMessage', { commit, ...value })
|
commit('deleteChatMessage', { commit, ...value })
|
||||||
},
|
},
|
||||||
resetChats({ commit, dispatch }) {
|
resetChats({ commit, dispatch }) {
|
||||||
|
|
@ -262,4 +278,4 @@ const chats = {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
export default chats
|
export default chatsModule
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import apiService from '../services/api/api.service.js'
|
import { markNotificationsAsSeen } from '../services/api/api.service.js'
|
||||||
import {
|
import {
|
||||||
closeAllDesktopNotifications,
|
closeAllDesktopNotifications,
|
||||||
closeDesktopNotification,
|
closeDesktopNotification,
|
||||||
|
|
@ -11,9 +11,12 @@ import {
|
||||||
|
|
||||||
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 { useOAuthStore } from 'src/stores/oauth.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,
|
||||||
|
|
@ -154,33 +157,32 @@ export const notifications = {
|
||||||
},
|
},
|
||||||
markNotificationsAsSeen({ rootState, state, commit }) {
|
markNotificationsAsSeen({ rootState, state, commit }) {
|
||||||
commit('markNotificationsAsSeen')
|
commit('markNotificationsAsSeen')
|
||||||
apiService
|
markNotificationsAsSeen({
|
||||||
.markNotificationsAsSeen({
|
id: state.maxId,
|
||||||
id: state.maxId,
|
credentials: rootState.users.currentUser.credentials,
|
||||||
credentials: rootState.users.currentUser.credentials,
|
}).then(() => {
|
||||||
})
|
closeAllDesktopNotifications(rootState)
|
||||||
.then(() => {
|
})
|
||||||
closeAllDesktopNotifications(rootState)
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
markSingleNotificationAsSeen({ rootState, commit }, { id }) {
|
markSingleNotificationAsSeen({ rootState, commit }, { id }) {
|
||||||
commit('markSingleNotificationAsSeen', { id })
|
commit('markSingleNotificationAsSeen', { id })
|
||||||
apiService
|
markNotificationsAsSeen({
|
||||||
.markNotificationsAsSeen({
|
single: true,
|
||||||
single: true,
|
id,
|
||||||
id,
|
credentials: rootState.users.currentUser.credentials,
|
||||||
credentials: rootState.users.currentUser.credentials,
|
}).then(() => {
|
||||||
})
|
closeDesktopNotification(rootState, { id })
|
||||||
.then(() => {
|
})
|
||||||
closeDesktopNotification(rootState, { id })
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
dismissNotificationLocal({ commit }, { id }) {
|
dismissNotificationLocal({ commit }, { id }) {
|
||||||
commit('dismissNotification', { id })
|
commit('dismissNotification', { id })
|
||||||
},
|
},
|
||||||
dismissNotification({ rootState, commit }, { id }) {
|
dismissNotification({ rootState, commit }, { id }) {
|
||||||
commit('dismissNotification', { id })
|
commit('dismissNotification', { id })
|
||||||
rootState.api.backendInteractor.dismissNotification({ id })
|
dismissNotification({
|
||||||
|
id,
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
|
})
|
||||||
},
|
},
|
||||||
updateNotification({ commit }, { id, updater }) {
|
updateNotification({ commit }, { id, updater }) {
|
||||||
commit('updateNotification', { id, updater })
|
commit('updateNotification', { id, updater })
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,37 @@
|
||||||
import { get, set } from 'lodash'
|
import { get, set } from 'lodash'
|
||||||
|
|
||||||
|
import { useOAuthStore } from 'src/stores/oauth.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: useOAuthStore().token,
|
||||||
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: useOAuthStore().token,
|
||||||
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 })
|
||||||
})
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,34 @@ import {
|
||||||
slice,
|
slice,
|
||||||
} from 'lodash'
|
} from 'lodash'
|
||||||
|
|
||||||
import apiService from '../services/api/api.service.js'
|
import {
|
||||||
|
bookmarkStatus,
|
||||||
|
deleteStatus,
|
||||||
|
favorite,
|
||||||
|
fetchEmojiReactions,
|
||||||
|
fetchFavoritedByUsers,
|
||||||
|
fetchPinnedStatuses,
|
||||||
|
fetchRebloggedByUsers,
|
||||||
|
fetchScrobbles,
|
||||||
|
fetchStatus,
|
||||||
|
fetchStatusHistory,
|
||||||
|
fetchStatusSource,
|
||||||
|
muteConversation,
|
||||||
|
pinOwnStatus,
|
||||||
|
reactWithEmoji,
|
||||||
|
retweet,
|
||||||
|
search2,
|
||||||
|
unbookmarkStatus,
|
||||||
|
unfavorite,
|
||||||
|
unmuteConversation,
|
||||||
|
unpinOwnStatus,
|
||||||
|
unreactWithEmoji,
|
||||||
|
unretweet,
|
||||||
|
} from '../services/api/api.service.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 { useOAuthStore } from 'src/stores/oauth.js'
|
||||||
|
|
||||||
const emptyTl = (userId = 0) => ({
|
const emptyTl = (userId = 0) => ({
|
||||||
statuses: [],
|
statuses: [],
|
||||||
|
|
@ -131,8 +155,7 @@ const getLatestScrobble = (state, user) => {
|
||||||
|
|
||||||
state.scrobblesNextFetch[user.id] = Date.now() + 24 * 60 * 60 * 1000
|
state.scrobblesNextFetch[user.id] = Date.now() + 24 * 60 * 60 * 1000
|
||||||
if (!scrobblesSupport) return
|
if (!scrobblesSupport) return
|
||||||
apiService
|
fetchScrobbles({ accountId: user.id })
|
||||||
.fetchScrobbles({ accountId: user.id })
|
|
||||||
.then((scrobbles) => {
|
.then((scrobbles) => {
|
||||||
if (scrobbles?.error) {
|
if (scrobbles?.error) {
|
||||||
useInstanceCapabilitiesStore().set('pleromaScrobblesAvailable', false)
|
useInstanceCapabilitiesStore().set('pleromaScrobblesAvailable', false)
|
||||||
|
|
@ -602,25 +625,24 @@ 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 apiService.fetchStatusSource({
|
return fetchStatusSource({
|
||||||
id: status.id,
|
id: status.id,
|
||||||
credentials: rootState.users.currentUser.credentials,
|
credentials: useOAuthStore().token,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
fetchStatusHistory(_, status) {
|
fetchStatusHistory(_, status) {
|
||||||
return apiService.fetchStatusHistory({ status })
|
return fetchStatusHistory({ status })
|
||||||
},
|
},
|
||||||
deleteStatus({ rootState, commit }, status) {
|
deleteStatus({ rootState, commit }, status) {
|
||||||
apiService
|
deleteStatus({
|
||||||
.deleteStatus({
|
id: status.id,
|
||||||
id: status.id,
|
credentials: useOAuthStore().token,
|
||||||
credentials: rootState.users.currentUser.credentials,
|
})
|
||||||
})
|
|
||||||
.then(() => {
|
.then(() => {
|
||||||
commit('setDeleted', { status })
|
commit('setDeleted', { status })
|
||||||
})
|
})
|
||||||
|
|
@ -643,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: useOAuthStore().token,
|
||||||
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: useOAuthStore().token,
|
||||||
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: useOAuthStore().token,
|
||||||
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: useOAuthStore().token,
|
||||||
|
}).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: useOAuthStore().token,
|
||||||
|
}).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: useOAuthStore().token,
|
||||||
|
}).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: useOAuthStore().token,
|
||||||
|
}).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: useOAuthStore().token,
|
||||||
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: useOAuthStore().token,
|
||||||
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: useOAuthStore().token,
|
||||||
})
|
}).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: useOAuthStore().token,
|
||||||
commit('setBookmarkedConfirm', { status })
|
}).then((status) => {
|
||||||
})
|
commit('setBookmarkedConfirm', { status })
|
||||||
|
})
|
||||||
},
|
},
|
||||||
queueFlush({ commit }, { timeline, id }) {
|
queueFlush({ commit }, { timeline, id }) {
|
||||||
commit('queueFlush', { timeline, id })
|
commit('queueFlush', { timeline, id })
|
||||||
|
|
@ -745,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: useOAuthStore().token,
|
||||||
|
}),
|
||||||
|
fetchRebloggedByUsers({
|
||||||
|
id,
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
|
}),
|
||||||
]).then(([favoritedByUsers, rebloggedByUsers]) => {
|
]).then(([favoritedByUsers, rebloggedByUsers]) => {
|
||||||
commit('addFavs', {
|
commit('addFavs', {
|
||||||
id,
|
id,
|
||||||
|
|
@ -765,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: useOAuthStore().token,
|
||||||
|
}).then(() => {
|
||||||
dispatch('fetchEmojiReactionsBy', id)
|
dispatch('fetchEmojiReactionsBy', id)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
@ -774,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: useOAuthStore().token,
|
||||||
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: useOAuthStore().token,
|
||||||
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: useOAuthStore().token,
|
||||||
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: useOAuthStore().token,
|
||||||
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 })
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,7 @@ import {
|
||||||
uniq,
|
uniq,
|
||||||
} from 'lodash'
|
} from 'lodash'
|
||||||
|
|
||||||
import apiService 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,34 @@ import {
|
||||||
windowWidth,
|
windowWidth,
|
||||||
} from '../services/window_utils/window_utils'
|
} from '../services/window_utils/window_utils'
|
||||||
|
|
||||||
|
import { useBookmarkFoldersStore } from 'src/stores/bookmark_folders.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 +90,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 +129,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: useOAuthStore().token,
|
||||||
store.commit('addMuteId', id)
|
}).then((relationship) => {
|
||||||
})
|
store.commit('updateUserRelationship', [relationship])
|
||||||
|
store.commit('addMuteId', id)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const unmuteUser = (store, id) => {
|
const unmuteUser = (store, id) => {
|
||||||
|
|
@ -132,39 +144,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: useOAuthStore().token,
|
||||||
})
|
}).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: useOAuthStore().token,
|
||||||
)
|
}).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: useOAuthStore().token,
|
||||||
|
}).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: useOAuthStore().token,
|
||||||
|
}).then(() => store.commit('removeDomainMute', domain))
|
||||||
}
|
}
|
||||||
|
|
||||||
export const mutations = {
|
export const mutations = {
|
||||||
|
|
@ -385,55 +401,60 @@ const users = {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
fetchUser(store, id) {
|
fetchUser(store, id) {
|
||||||
return store.rootState.api.backendInteractor
|
return fetchUser({
|
||||||
.fetchUser({ id })
|
id,
|
||||||
.then((user) => {
|
credentials: useOAuthStore().token,
|
||||||
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: useOAuthStore().token,
|
||||||
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: useOAuthStore().token,
|
||||||
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: useOAuthStore().token,
|
||||||
|
}).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: useOAuthStore().token,
|
||||||
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 +478,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: useOAuthStore().token,
|
||||||
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 +507,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: useOAuthStore().token,
|
||||||
.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 +535,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: useOAuthStore().token,
|
||||||
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: useOAuthStore().token,
|
||||||
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 +565,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: useOAuthStore().token,
|
||||||
)
|
}).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: useOAuthStore().token,
|
||||||
)
|
}).then((relationship) =>
|
||||||
|
commit('updateUserRelationship', [relationship]),
|
||||||
|
)
|
||||||
},
|
},
|
||||||
registerPushNotifications(store) {
|
registerPushNotifications(store) {
|
||||||
const token = store.state.currentUser.credentials
|
const token = store.state.currentUser.credentials
|
||||||
|
|
@ -611,12 +641,13 @@ const users = {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
searchUsers({ rootState, commit }, { query }) {
|
searchUsers({ rootState, commit }, { query }) {
|
||||||
return rootState.api.backendInteractor
|
return searchUsers({
|
||||||
.searchUsers({ query })
|
query,
|
||||||
.then((users) => {
|
credentials: useOAuthStore().token,
|
||||||
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()
|
||||||
|
|
@ -624,7 +655,7 @@ const users = {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const token = await oauthStore.ensureAppToken()
|
const token = await oauthStore.ensureAppToken()
|
||||||
const data = await apiService.register({
|
const data = await register({
|
||||||
credentials: token,
|
credentials: token,
|
||||||
params: { ...userInfo },
|
params: { ...userInfo },
|
||||||
})
|
})
|
||||||
|
|
@ -645,8 +676,10 @@ const users = {
|
||||||
throw e
|
throw e
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async getCaptcha(store) {
|
getCaptcha(store) {
|
||||||
return store.rootState.api.backendInteractor.getCaptcha()
|
return getCaptcha({
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
logout(store) {
|
logout(store) {
|
||||||
|
|
@ -670,13 +703,9 @@ const users = {
|
||||||
store.dispatch('disconnectFromSocket')
|
store.dispatch('disconnectFromSocket')
|
||||||
oauth.clearToken()
|
oauth.clearToken()
|
||||||
store.dispatch('stopFetchingTimeline', 'friends')
|
store.dispatch('stopFetchingTimeline', 'friends')
|
||||||
store.commit(
|
|
||||||
'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')
|
||||||
|
|
@ -690,9 +719,12 @@ const users = {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
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(accessToken)
|
verifyCredentials({
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
|
})
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
if (!data.error) {
|
if (!data.error) {
|
||||||
const user = data
|
const user = data
|
||||||
|
|
@ -721,12 +753,6 @@ const users = {
|
||||||
useInterfaceStore().setNotificationPermission(permission),
|
useInterfaceStore().setNotificationPermission(permission),
|
||||||
)
|
)
|
||||||
|
|
||||||
// Set our new backend interactor
|
|
||||||
commit(
|
|
||||||
'setBackendInteractor',
|
|
||||||
backendInteractorService(accessToken),
|
|
||||||
)
|
|
||||||
|
|
||||||
// Do server-side storage migrations
|
// Do server-side storage migrations
|
||||||
|
|
||||||
// Debug snippet to clean up storage and reset migrations
|
// Debug snippet to clean up storage and reset migrations
|
||||||
|
|
@ -764,8 +790,8 @@ const users = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch('startFetchingLists')
|
useListsStore().startFetching()
|
||||||
dispatch('startFetchingBookmarkFolders')
|
useBookmarkFoldersStore().startFetching()
|
||||||
|
|
||||||
if (user.locked) {
|
if (user.locked) {
|
||||||
dispatch('startFetchingFollowRequests')
|
dispatch('startFetchingFollowRequests')
|
||||||
|
|
@ -799,9 +825,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
|
||||||
|
|
|
||||||
509
src/services/api/admin.js
Normal file
509
src/services/api/admin.js
Normal file
|
|
@ -0,0 +1,509 @@
|
||||||
|
import { promisedRequest } from './helpers.js'
|
||||||
|
|
||||||
|
import { RegistrationError, StatusCodeError } from 'src/services/errors/errors'
|
||||||
|
|
||||||
|
const REPORTS = '/api/v1/pleroma/admin/reports'
|
||||||
|
const CONFIG_URL = '/api/v1/pleroma/admin/config'
|
||||||
|
const DESCRIPTIONS_URL = '/api/v1/pleroma/admin/config/descriptions'
|
||||||
|
|
||||||
|
const ANNOUNCEMENTS_URL = (id = '') =>
|
||||||
|
`/api/v1/pleroma/admin/announcements/${id}`
|
||||||
|
|
||||||
|
const FRONTENDS_URL = '/api/v1/pleroma/admin/frontends'
|
||||||
|
const FRONTENDS_INSTALL_URL = '/api/v1/pleroma/admin/frontends/install'
|
||||||
|
|
||||||
|
const USERS_URL = (nickname = '') => `/api/v1/pleroma/admin/users/${nickname}`
|
||||||
|
const USERS_URL_LIST = ({
|
||||||
|
page,
|
||||||
|
pageSize,
|
||||||
|
filters = {},
|
||||||
|
query = '',
|
||||||
|
name = '',
|
||||||
|
email = '',
|
||||||
|
}) => {
|
||||||
|
const {
|
||||||
|
local = false,
|
||||||
|
external = false,
|
||||||
|
active = false,
|
||||||
|
needApproval = false,
|
||||||
|
unconfirmed = false,
|
||||||
|
deactivated = false,
|
||||||
|
isAdmin = true,
|
||||||
|
isModerator = true,
|
||||||
|
} = filters
|
||||||
|
const filters_str = [
|
||||||
|
local && 'local',
|
||||||
|
external && 'external',
|
||||||
|
active && 'active',
|
||||||
|
needApproval && 'need_approval',
|
||||||
|
unconfirmed && 'unconfirmed',
|
||||||
|
deactivated && 'deactivated',
|
||||||
|
isAdmin && 'is_admin',
|
||||||
|
isModerator && 'is_moderator',
|
||||||
|
]
|
||||||
|
.filter((x) => x)
|
||||||
|
.join(',')
|
||||||
|
return `/api/v1/pleroma/admin/users?page=${page}&page_size=${pageSize}&filters=${filters_str}&query=${query}&name=${name}&email=${email}`
|
||||||
|
}
|
||||||
|
|
||||||
|
const TAG_USER_URL = '/api/pleroma/admin/users/tag'
|
||||||
|
|
||||||
|
const PERMISSION_GROUP_URL = (right) =>
|
||||||
|
`/api/pleroma/admin/users/permission_group/${right}`
|
||||||
|
const ACTIVATE_USERS_URL = '/api/pleroma/admin/users/activate'
|
||||||
|
const DEACTIVATE_USERS_URL = '/api/pleroma/admin/users/deactivate'
|
||||||
|
const SUGGEST_USERS_URL = '/api/pleroma/admin/users/suggest'
|
||||||
|
const UNSUGGEST_USERS_URL = '/api/pleroma/admin/users/unsuggest'
|
||||||
|
const APPROVE_USERS_URL = '/api/v1/pleroma/admin/users/approve'
|
||||||
|
const CONFIRM_USERS_URL = '/api/v1/pleroma/admin/users/confirm_email'
|
||||||
|
const RESEND_CONFIRMATION_EMAIL_URL =
|
||||||
|
'/api/v1/pleroma/admin/users/resend_confirmation_email'
|
||||||
|
const LIST_STATUSES_URL = ({ id, page, pageSize, godmode, withReblogs }) =>
|
||||||
|
`/api/v1/pleroma/admin/users/${id}/statuses?page_size=${pageSize}&page=${page}&godmode=${godmode}&with_reblogs=${withReblogs}`
|
||||||
|
const CHANGE_STATUS_SCOPE_URL = (id) => `/api/v1/pleroma/admin/statuses/${id}`
|
||||||
|
const REQUIRE_PASSWORD_CHANGE_URL =
|
||||||
|
'/api/v1/pleroma/admin/users/force_password_reset'
|
||||||
|
|
||||||
|
const DISABLE_MFA_URL = '/api/v1/pleroma/admin/users/disable_mfa'
|
||||||
|
const EMOJI_RELOAD_URL = '/api/pleroma/admin/reload_emoji'
|
||||||
|
const EMOJI_IMPORT_FS_URL = '/api/pleroma/emoji/packs/import'
|
||||||
|
const EMOJI_PACK_URL = (name) => `/api/v1/pleroma/emoji/pack?name=${name}`
|
||||||
|
const EMOJI_PACKS_DL_REMOTE_URL = '/api/v1/pleroma/emoji/packs/download'
|
||||||
|
const EMOJI_PACKS_DL_REMOTE_ZIP_URL = '/api/v1/pleroma/emoji/packs/download_zip'
|
||||||
|
const EMOJI_PACKS_LS_REMOTE_URL = (url, page, pageSize) =>
|
||||||
|
`/api/v1/pleroma/emoji/packs/remote?url=${url}&page=${page}&page_size=${pageSize}`
|
||||||
|
const EMOJI_UPDATE_FILE_URL = (name) =>
|
||||||
|
`/api/v1/pleroma/emoji/packs/files?name=${name}`
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
export const setUsersTags = ({
|
||||||
|
tags,
|
||||||
|
credentials,
|
||||||
|
value,
|
||||||
|
screen_names: nicknames,
|
||||||
|
}) =>
|
||||||
|
promisedRequest({
|
||||||
|
url: TAG_USER_URL,
|
||||||
|
method: value ? 'PUT' : 'DELETE',
|
||||||
|
credentials,
|
||||||
|
payload: {
|
||||||
|
nicknames,
|
||||||
|
tags,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
export const setUsersRight = ({
|
||||||
|
right,
|
||||||
|
credentials,
|
||||||
|
value,
|
||||||
|
screen_names: nicknames,
|
||||||
|
}) =>
|
||||||
|
promisedRequest({
|
||||||
|
url: PERMISSION_GROUP_URL(right),
|
||||||
|
method: value ? 'POST' : 'DELETE',
|
||||||
|
credentials,
|
||||||
|
payload: {
|
||||||
|
nicknames,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
export const setUsersActivationStatus = ({
|
||||||
|
credentials,
|
||||||
|
screen_names: nicknames,
|
||||||
|
value,
|
||||||
|
}) =>
|
||||||
|
promisedRequest({
|
||||||
|
url: value ? ACTIVATE_USERS_URL : DEACTIVATE_USERS_URL,
|
||||||
|
method: 'PATCH',
|
||||||
|
credentials,
|
||||||
|
payload: {
|
||||||
|
nicknames,
|
||||||
|
},
|
||||||
|
}).then((response) => response.users)
|
||||||
|
|
||||||
|
export const setUsersApprovalStatus = ({
|
||||||
|
credentials,
|
||||||
|
screen_names: nicknames,
|
||||||
|
}) =>
|
||||||
|
promisedRequest({
|
||||||
|
url: APPROVE_USERS_URL,
|
||||||
|
method: 'PATCH',
|
||||||
|
credentials,
|
||||||
|
payload: {
|
||||||
|
nicknames,
|
||||||
|
},
|
||||||
|
}).then((response) => response.users)
|
||||||
|
|
||||||
|
export const setUsersConfirmationStatus = ({
|
||||||
|
credentials,
|
||||||
|
screen_names: nicknames,
|
||||||
|
}) =>
|
||||||
|
promisedRequest({
|
||||||
|
url: CONFIRM_USERS_URL,
|
||||||
|
method: 'PATCH',
|
||||||
|
credentials,
|
||||||
|
payload: {
|
||||||
|
nicknames,
|
||||||
|
},
|
||||||
|
}).then((response) => response.users)
|
||||||
|
|
||||||
|
export const setUsersSuggestionStatus = ({
|
||||||
|
credentials,
|
||||||
|
screen_names: nicknames,
|
||||||
|
value,
|
||||||
|
}) =>
|
||||||
|
promisedRequest({
|
||||||
|
url: value ? SUGGEST_USERS_URL : UNSUGGEST_USERS_URL,
|
||||||
|
method: 'PATCH',
|
||||||
|
credentials,
|
||||||
|
payload: {
|
||||||
|
nicknames,
|
||||||
|
},
|
||||||
|
}).then((response) => response.users)
|
||||||
|
|
||||||
|
export const getUserData = ({ credentials, screen_name: nickname }) =>
|
||||||
|
promisedRequest({
|
||||||
|
url: USERS_URL(nickname),
|
||||||
|
method: 'GET',
|
||||||
|
credentials,
|
||||||
|
})
|
||||||
|
|
||||||
|
export const deleteAccounts = ({ credentials, screen_names: nicknames }) =>
|
||||||
|
promisedRequest({
|
||||||
|
url: USERS_URL(),
|
||||||
|
method: 'DELETE',
|
||||||
|
credentials,
|
||||||
|
payload: {
|
||||||
|
nicknames,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
export const getAnnouncements = ({ id, credentials }) =>
|
||||||
|
promisedRequest({ url: ANNOUNCEMENTS_URL(id), credentials })
|
||||||
|
|
||||||
|
// the reported list is hardly useful because standards are for dating i guess,
|
||||||
|
// so make sure to fetchIfMissing right afterward using this call
|
||||||
|
export const listUsers = ({ opts, credentials }) =>
|
||||||
|
promisedRequest({
|
||||||
|
url: USERS_URL_LIST(opts),
|
||||||
|
credentials,
|
||||||
|
method: 'GET',
|
||||||
|
})
|
||||||
|
|
||||||
|
export const resendConfirmationEmail = ({
|
||||||
|
screen_names: nicknames,
|
||||||
|
credentials,
|
||||||
|
}) =>
|
||||||
|
promisedRequest({
|
||||||
|
url: RESEND_CONFIRMATION_EMAIL_URL,
|
||||||
|
credentials,
|
||||||
|
method: 'PATCH',
|
||||||
|
payload: {
|
||||||
|
nicknames,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
export const requirePasswordChange = ({
|
||||||
|
screen_names: nicknames,
|
||||||
|
credentials,
|
||||||
|
}) =>
|
||||||
|
promisedRequest({
|
||||||
|
url: REQUIRE_PASSWORD_CHANGE_URL,
|
||||||
|
credentials,
|
||||||
|
method: 'PATCH',
|
||||||
|
payload: {
|
||||||
|
nicknames,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
export const disableMFA = ({ screen_name: nickname, credentials }) =>
|
||||||
|
promisedRequest({
|
||||||
|
url: DISABLE_MFA_URL,
|
||||||
|
credentials,
|
||||||
|
method: 'PUT',
|
||||||
|
payload: {
|
||||||
|
nickname,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
export const listStatuses = ({ opts, credentials }) =>
|
||||||
|
promisedRequest({
|
||||||
|
url: LIST_STATUSES_URL(opts),
|
||||||
|
credentials,
|
||||||
|
method: 'GET',
|
||||||
|
})
|
||||||
|
|
||||||
|
export const changeStatusScope = ({
|
||||||
|
opts: { id, sensitive, visibility },
|
||||||
|
credentials,
|
||||||
|
}) => {
|
||||||
|
var payload = {}
|
||||||
|
if (typeof sensitive !== 'undefined') {
|
||||||
|
payload['sensitive'] = sensitive
|
||||||
|
}
|
||||||
|
if (typeof visibility !== 'undefined') {
|
||||||
|
payload['visibility'] = visibility
|
||||||
|
}
|
||||||
|
|
||||||
|
return promisedRequest({
|
||||||
|
url: CHANGE_STATUS_SCOPE_URL(id),
|
||||||
|
credentials,
|
||||||
|
method: 'PUT',
|
||||||
|
payload,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const announcementToPayload = ({
|
||||||
|
content,
|
||||||
|
startsAt,
|
||||||
|
endsAt,
|
||||||
|
allDay,
|
||||||
|
}) => {
|
||||||
|
const payload = { content }
|
||||||
|
|
||||||
|
if (typeof startsAt !== 'undefined') {
|
||||||
|
payload.starts_at = startsAt ? new Date(startsAt).toISOString() : null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof endsAt !== 'undefined') {
|
||||||
|
payload.ends_at = endsAt ? new Date(endsAt).toISOString() : null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof allDay !== 'undefined') {
|
||||||
|
payload.all_day = allDay
|
||||||
|
}
|
||||||
|
|
||||||
|
return payload
|
||||||
|
}
|
||||||
|
|
||||||
|
export const postAnnouncement = ({
|
||||||
|
credentials,
|
||||||
|
content,
|
||||||
|
startsAt,
|
||||||
|
endsAt,
|
||||||
|
allDay,
|
||||||
|
}) =>
|
||||||
|
promisedRequest({
|
||||||
|
url: ANNOUNCEMENTS_URL(),
|
||||||
|
credentials,
|
||||||
|
method: 'POST',
|
||||||
|
payload: announcementToPayload({ content, startsAt, endsAt, allDay }),
|
||||||
|
})
|
||||||
|
|
||||||
|
export const editAnnouncement = ({
|
||||||
|
id,
|
||||||
|
credentials,
|
||||||
|
content,
|
||||||
|
startsAt,
|
||||||
|
endsAt,
|
||||||
|
allDay,
|
||||||
|
}) =>
|
||||||
|
promisedRequest({
|
||||||
|
url: ANNOUNCEMENTS_URL(id),
|
||||||
|
credentials,
|
||||||
|
method: 'PATCH',
|
||||||
|
payload: announcementToPayload({ content, startsAt, endsAt, allDay }),
|
||||||
|
})
|
||||||
|
|
||||||
|
export const deleteAnnouncement = ({ id, credentials }) =>
|
||||||
|
promisedRequest({
|
||||||
|
url: ANNOUNCEMENTS_URL(id),
|
||||||
|
credentials,
|
||||||
|
method: 'DELETE',
|
||||||
|
})
|
||||||
|
|
||||||
|
export const setReportState = ({ id, state, credentials }) => {
|
||||||
|
// TODO: Can't use promisedRequest because on OK this does not return json
|
||||||
|
// See https://git.pleroma.social/pleroma/pleroma-fe/-/merge_requests/1322
|
||||||
|
|
||||||
|
return promisedRequest({
|
||||||
|
url: REPORTS,
|
||||||
|
credentials,
|
||||||
|
method: 'PATCH',
|
||||||
|
payload: {
|
||||||
|
reports: [
|
||||||
|
{
|
||||||
|
id,
|
||||||
|
state,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
if (data.status >= 500) {
|
||||||
|
throw Error(data.statusText)
|
||||||
|
} else if (data.status >= 400) {
|
||||||
|
return data.json()
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
if (data.errors) {
|
||||||
|
throw Error(data.errors[0].message)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getInstanceDBConfig = ({ credentials }) =>
|
||||||
|
promisedRequest({
|
||||||
|
url: CONFIG_URL,
|
||||||
|
credentials,
|
||||||
|
})
|
||||||
|
|
||||||
|
export const getInstanceConfigDescriptions = ({ credentials }) =>
|
||||||
|
promisedRequest({
|
||||||
|
url: DESCRIPTIONS_URL,
|
||||||
|
credentials,
|
||||||
|
})
|
||||||
|
|
||||||
|
export const getAvailableFrontends = ({ credentials }) =>
|
||||||
|
promisedRequest({
|
||||||
|
url: FRONTENDS_URL,
|
||||||
|
credentials,
|
||||||
|
})
|
||||||
|
|
||||||
|
export const pushInstanceDBConfig = ({ credentials, payload }) =>
|
||||||
|
promisedRequest({
|
||||||
|
url: CONFIG_URL,
|
||||||
|
method: 'POST',
|
||||||
|
credentials,
|
||||||
|
payload,
|
||||||
|
})
|
||||||
|
|
||||||
|
export const installFrontend = ({ credentials, payload }) =>
|
||||||
|
promisedRequest({
|
||||||
|
url: FRONTENDS_INSTALL_URL,
|
||||||
|
credentials,
|
||||||
|
method: 'POST',
|
||||||
|
payload,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Emoji packs
|
||||||
|
export const deleteEmojiPack = ({ name }) =>
|
||||||
|
promisedRequest({
|
||||||
|
url: EMOJI_PACK_URL(name),
|
||||||
|
method: 'DELETE',
|
||||||
|
})
|
||||||
|
|
||||||
|
export const reloadEmoji = ({ credentials }) =>
|
||||||
|
promisedRequest({
|
||||||
|
url: EMOJI_RELOAD_URL,
|
||||||
|
method: 'POST',
|
||||||
|
credentials,
|
||||||
|
})
|
||||||
|
|
||||||
|
export const importEmojiFromFS = ({ credentials }) =>
|
||||||
|
promisedRequest({
|
||||||
|
url: EMOJI_IMPORT_FS_URL,
|
||||||
|
credentials,
|
||||||
|
})
|
||||||
|
|
||||||
|
export const createEmojiPack = ({ name, credentials }) =>
|
||||||
|
promisedRequest({
|
||||||
|
url: EMOJI_PACK_URL(name),
|
||||||
|
method: 'POST',
|
||||||
|
credentials,
|
||||||
|
})
|
||||||
|
|
||||||
|
export const listRemoteEmojiPacks = ({
|
||||||
|
instance,
|
||||||
|
page,
|
||||||
|
pageSize,
|
||||||
|
credentials,
|
||||||
|
}) => {
|
||||||
|
if (!instance.startsWith('http')) {
|
||||||
|
instance = 'https://' + instance
|
||||||
|
}
|
||||||
|
|
||||||
|
return promisedRequest({
|
||||||
|
url: EMOJI_PACKS_LS_REMOTE_URL(instance, page, pageSize),
|
||||||
|
credentials,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const downloadRemoteEmojiPack = ({
|
||||||
|
instance,
|
||||||
|
packName,
|
||||||
|
as,
|
||||||
|
credentials,
|
||||||
|
}) =>
|
||||||
|
promisedRequest({
|
||||||
|
url: EMOJI_PACKS_DL_REMOTE_URL,
|
||||||
|
credentials,
|
||||||
|
method: 'POST',
|
||||||
|
payload: {
|
||||||
|
url: instance,
|
||||||
|
name: packName,
|
||||||
|
as,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
export const downloadRemoteEmojiPackZIP = ({
|
||||||
|
url,
|
||||||
|
packName,
|
||||||
|
file,
|
||||||
|
credentials,
|
||||||
|
}) => {
|
||||||
|
const data = new FormData()
|
||||||
|
if (file) data.set('file', file)
|
||||||
|
if (url) data.set('url', url)
|
||||||
|
data.set('name', packName)
|
||||||
|
|
||||||
|
return promisedRequest({
|
||||||
|
url: EMOJI_PACKS_DL_REMOTE_ZIP_URL,
|
||||||
|
method: 'POST',
|
||||||
|
payload: data,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const saveEmojiPackMetadata = ({ name, newData, credentials }) =>
|
||||||
|
promisedRequest({
|
||||||
|
url: EMOJI_PACK_URL(name),
|
||||||
|
credentials,
|
||||||
|
method: 'PATCH',
|
||||||
|
payload: { metadata: newData },
|
||||||
|
})
|
||||||
|
|
||||||
|
export const addNewEmojiFile = ({ packName, file, shortcode, filename }) => {
|
||||||
|
const data = new FormData()
|
||||||
|
if (filename.trim() !== '') {
|
||||||
|
data.set('filename', filename)
|
||||||
|
}
|
||||||
|
if (shortcode.trim() !== '') {
|
||||||
|
data.set('shortcode', shortcode)
|
||||||
|
}
|
||||||
|
data.set('file', file)
|
||||||
|
|
||||||
|
return promisedRequest({
|
||||||
|
url: EMOJI_UPDATE_FILE_URL(packName),
|
||||||
|
method: 'POST',
|
||||||
|
payload: data,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const updateEmojiFile = ({
|
||||||
|
packName,
|
||||||
|
shortcode,
|
||||||
|
newShortcode,
|
||||||
|
newFilename,
|
||||||
|
credentials,
|
||||||
|
force,
|
||||||
|
}) =>
|
||||||
|
promisedRequest({
|
||||||
|
url: EMOJI_UPDATE_FILE_URL(packName),
|
||||||
|
credentials,
|
||||||
|
method: 'PATCH',
|
||||||
|
payload: {
|
||||||
|
shortcode,
|
||||||
|
new_shortcode: newShortcode,
|
||||||
|
new_filename: newFilename,
|
||||||
|
force,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
export const deleteEmojiFile = ({ packName, shortcode }) =>
|
||||||
|
promisedRequest({
|
||||||
|
url: `${EMOJI_UPDATE_FILE_URL(packName)}&shortcode=${shortcode}`,
|
||||||
|
method: 'DELETE',
|
||||||
|
})
|
||||||
File diff suppressed because it is too large
Load diff
87
src/services/api/helpers.js
Normal file
87
src/services/api/helpers.js
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
import { RegistrationError, StatusCodeError } from 'src/services/errors/errors'
|
||||||
|
|
||||||
|
export const promisedRequest = ({
|
||||||
|
method,
|
||||||
|
url,
|
||||||
|
params,
|
||||||
|
payload,
|
||||||
|
formData,
|
||||||
|
credentials,
|
||||||
|
headers = {},
|
||||||
|
}) => {
|
||||||
|
const options = {
|
||||||
|
method,
|
||||||
|
credentials: 'same-origin',
|
||||||
|
headers: {
|
||||||
|
Accept: 'application/json',
|
||||||
|
...headers,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if (!formData) {
|
||||||
|
options.headers['Content-Type'] = 'application/json'
|
||||||
|
}
|
||||||
|
if (params) {
|
||||||
|
url +=
|
||||||
|
'?' +
|
||||||
|
Object.entries(params)
|
||||||
|
.map(
|
||||||
|
([key, value]) =>
|
||||||
|
encodeURIComponent(key) + '=' + encodeURIComponent(value),
|
||||||
|
)
|
||||||
|
.join('&')
|
||||||
|
}
|
||||||
|
if (formData || payload) {
|
||||||
|
options.body = formData || JSON.stringify(payload)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (credentials) {
|
||||||
|
options.headers = {
|
||||||
|
...options.headers,
|
||||||
|
...authHeaders(credentials),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fetch(url, options).then((response) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
// 204 is "No content", which fails to parse json (as you'd might think)
|
||||||
|
if (response.ok && response.status === 204) resolve()
|
||||||
|
|
||||||
|
return response
|
||||||
|
.json()
|
||||||
|
.then((json) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
return reject(
|
||||||
|
new StatusCodeError(
|
||||||
|
response.status,
|
||||||
|
json,
|
||||||
|
{ url, options },
|
||||||
|
response,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
json._response = response
|
||||||
|
|
||||||
|
return resolve(json)
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
return reject(
|
||||||
|
new StatusCodeError(
|
||||||
|
response.status,
|
||||||
|
error,
|
||||||
|
{ url, options },
|
||||||
|
response,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const authHeaders = (accessToken) => {
|
||||||
|
if (accessToken) {
|
||||||
|
return { Authorization: `Bearer ${accessToken}` }
|
||||||
|
} else {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,75 +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 apiService, {
|
|
||||||
getMastodonSocketURI,
|
|
||||||
ProcessedWS,
|
|
||||||
} 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 = getMastodonSocketURI({}, serv)
|
|
||||||
return 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
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
import apiService 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 apiService
|
|
||||||
.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
|
|
||||||
|
|
@ -1,8 +1,18 @@
|
||||||
|
import { useOAuthStore } from 'src/stores/oauth.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: useOAuthStore().token,
|
||||||
|
})
|
||||||
.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: useOAuthStore().token,
|
||||||
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: useOAuthStore().token,
|
||||||
store.commit('updateUserRelationship', [updated])
|
}).then((updated) => {
|
||||||
resolve({
|
store.commit('updateUserRelationship', [updated])
|
||||||
updated,
|
resolve({
|
||||||
})
|
updated,
|
||||||
})
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
import apiService from '../api/api.service.js'
|
import { fetchFollowRequests } from '../api/api.service.js'
|
||||||
import { promiseInterval } from '../promise_interval/promise_interval.js'
|
import { promiseInterval } from '../promise_interval/promise_interval.js'
|
||||||
|
|
||||||
const fetchAndUpdate = ({ store, credentials }) => {
|
const fetchAndUpdate = ({ store, credentials }) => {
|
||||||
return apiService
|
return fetchFollowRequests({ credentials })
|
||||||
.fetchFollowRequests({ credentials })
|
|
||||||
.then(
|
.then(
|
||||||
(requests) => {
|
(requests) => {
|
||||||
store.commit('setFollowRequests', requests)
|
store.commit('setFollowRequests', requests)
|
||||||
|
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
import apiService from '../api/api.service.js'
|
|
||||||
import { promiseInterval } from '../promise_interval/promise_interval.js'
|
|
||||||
|
|
||||||
import { useListsStore } from 'src/stores/lists.js'
|
|
||||||
|
|
||||||
const fetchAndUpdate = ({ credentials }) => {
|
|
||||||
return apiService
|
|
||||||
.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
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import apiService from '../api/api.service.js'
|
import { fetchTimeline } from '../api/api.service.js'
|
||||||
import { promiseInterval } from '../promise_interval/promise_interval.js'
|
import { promiseInterval } from '../promise_interval/promise_interval.js'
|
||||||
|
|
||||||
import { useInstanceStore } from 'src/stores/instance.js'
|
import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
|
|
@ -80,8 +80,7 @@ const fetchAndUpdate = ({ store, credentials, older = false, since }) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const fetchNotifications = ({ store, args, older }) => {
|
const fetchNotifications = ({ store, args, older }) => {
|
||||||
return apiService
|
return fetchTimeline(args)
|
||||||
.fetchTimeline(args)
|
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
if (response.errors) {
|
if (response.errors) {
|
||||||
if (
|
if (
|
||||||
|
|
|
||||||
|
|
@ -4,32 +4,39 @@
|
||||||
// time after the first interval.
|
// time after the first interval.
|
||||||
// - interval is the interval delay in ms.
|
// - interval is the interval delay in ms.
|
||||||
|
|
||||||
|
const wait = (timeout) => {
|
||||||
|
let timeoutId
|
||||||
|
const promise = () =>
|
||||||
|
new Promise((resolve) => {
|
||||||
|
timeoutId = window.setTimeout(() => resolve(), timeout)
|
||||||
|
})
|
||||||
|
return { timeoutId, promise }
|
||||||
|
}
|
||||||
|
|
||||||
export const promiseInterval = (promiseCall, interval) => {
|
export const promiseInterval = (promiseCall, interval) => {
|
||||||
let stopped = false
|
let stopped = false
|
||||||
let timeout = null
|
let timeout = null
|
||||||
|
|
||||||
const func = () => {
|
|
||||||
const promise = promiseCall()
|
|
||||||
// something unexpected happened and promiseCall did not
|
|
||||||
// return a promise, abort the loop.
|
|
||||||
if (!(promise && promise.finally)) {
|
|
||||||
console.warn(
|
|
||||||
'promiseInterval: promise call did not return a promise, stopping interval.',
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
promise.finally(() => {
|
|
||||||
if (stopped) return
|
|
||||||
timeout = window.setTimeout(func, interval)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const stopFetcher = () => {
|
const stopFetcher = () => {
|
||||||
stopped = true
|
stopped = true
|
||||||
window.clearTimeout(timeout)
|
window.clearTimeout(timeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
timeout = window.setTimeout(func, interval)
|
const loop = new Promise(async (resolve, reject) => {
|
||||||
|
try {
|
||||||
|
while (!stopped) {
|
||||||
|
await promiseCall()
|
||||||
|
const { timeoutId, promise } = wait(interval)
|
||||||
|
timeout = timeoutId
|
||||||
|
await promise()
|
||||||
|
}
|
||||||
|
resolve()
|
||||||
|
} catch (e) {
|
||||||
|
reject(e)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
loop.then()
|
||||||
|
|
||||||
return { stop: stopFetcher }
|
return { stop: stopFetcher }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,11 @@
|
||||||
import { map } from 'lodash'
|
import { map } from 'lodash'
|
||||||
|
|
||||||
import apiService from '../api/api.service.js'
|
import {
|
||||||
|
editStatus as apiEditStatus,
|
||||||
|
postStatus as apiPostStatus,
|
||||||
|
setMediaDescription as apiSetMediaDescription,
|
||||||
|
uploadMedia as apiUploadMedia,
|
||||||
|
} from '../api/api.service.js'
|
||||||
|
|
||||||
const postStatus = ({
|
const postStatus = ({
|
||||||
store,
|
store,
|
||||||
|
|
@ -18,21 +23,20 @@ const postStatus = ({
|
||||||
}) => {
|
}) => {
|
||||||
const mediaIds = map(media, 'id')
|
const mediaIds = map(media, 'id')
|
||||||
|
|
||||||
return apiService
|
return apiPostStatus({
|
||||||
.postStatus({
|
credentials: store.state.users.currentUser.credentials,
|
||||||
credentials: store.state.users.currentUser.credentials,
|
status,
|
||||||
status,
|
spoilerText,
|
||||||
spoilerText,
|
visibility,
|
||||||
visibility,
|
sensitive,
|
||||||
sensitive,
|
mediaIds,
|
||||||
mediaIds,
|
inReplyToStatusId,
|
||||||
inReplyToStatusId,
|
quoteId,
|
||||||
quoteId,
|
contentType,
|
||||||
contentType,
|
poll,
|
||||||
poll,
|
preview,
|
||||||
preview,
|
idempotencyKey,
|
||||||
idempotencyKey,
|
})
|
||||||
})
|
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
if (!data.error && !preview) {
|
if (!data.error && !preview) {
|
||||||
store.dispatch('addNewStatuses', {
|
store.dispatch('addNewStatuses', {
|
||||||
|
|
@ -63,17 +67,16 @@ const editStatus = ({
|
||||||
}) => {
|
}) => {
|
||||||
const mediaIds = map(media, 'id')
|
const mediaIds = map(media, 'id')
|
||||||
|
|
||||||
return apiService
|
return editStatus({
|
||||||
.editStatus({
|
id: statusId,
|
||||||
id: statusId,
|
credentials: store.state.users.currentUser.credentials,
|
||||||
credentials: store.state.users.currentUser.credentials,
|
status,
|
||||||
status,
|
spoilerText,
|
||||||
spoilerText,
|
sensitive,
|
||||||
sensitive,
|
poll,
|
||||||
poll,
|
mediaIds,
|
||||||
mediaIds,
|
contentType,
|
||||||
contentType,
|
})
|
||||||
})
|
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
if (!data.error) {
|
if (!data.error) {
|
||||||
store.dispatch('addNewStatuses', {
|
store.dispatch('addNewStatuses', {
|
||||||
|
|
@ -95,12 +98,12 @@ const editStatus = ({
|
||||||
|
|
||||||
const uploadMedia = ({ store, formData }) => {
|
const uploadMedia = ({ store, formData }) => {
|
||||||
const credentials = store.state.users.currentUser.credentials
|
const credentials = store.state.users.currentUser.credentials
|
||||||
return apiService.uploadMedia({ credentials, formData })
|
return apiUploadMedia({ credentials, formData })
|
||||||
}
|
}
|
||||||
|
|
||||||
const setMediaDescription = ({ store, id, description }) => {
|
const setMediaDescription = ({ store, id, description }) => {
|
||||||
const credentials = store.state.users.currentUser.credentials
|
const credentials = store.state.users.currentUser.credentials
|
||||||
return apiService.setMediaDescription({ credentials, id, description })
|
return apiSetMediaDescription({ credentials, id, description })
|
||||||
}
|
}
|
||||||
|
|
||||||
const statusPosterService = {
|
const statusPosterService = {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { camelCase } from 'lodash'
|
import { camelCase } from 'lodash'
|
||||||
|
|
||||||
import apiService from '../api/api.service.js'
|
import { fetchTimeline } from '../api/api.service.js'
|
||||||
import { promiseInterval } from '../promise_interval/promise_interval.js'
|
import { promiseInterval } from '../promise_interval/promise_interval.js'
|
||||||
|
|
||||||
import { useInstanceStore } from 'src/stores/instance.js'
|
import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
|
|
@ -75,8 +75,7 @@ const fetchAndUpdate = ({
|
||||||
|
|
||||||
const numStatusesBeforeFetch = timelineData.statuses.length
|
const numStatusesBeforeFetch = timelineData.statuses.length
|
||||||
|
|
||||||
return apiService
|
return fetchTimeline(args)
|
||||||
.fetchTimeline(args)
|
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
if (response.errors) {
|
if (response.errors) {
|
||||||
if (timeline === 'favorites') {
|
if (timeline === 'favorites') {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,38 @@
|
||||||
import { cloneDeep, differenceWith, flatten, get, isEqual, set } from 'lodash'
|
import { cloneDeep, differenceWith, flatten, get, isEqual, set } from 'lodash'
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
|
import { useOAuthStore } from 'src/stores/oauth.js'
|
||||||
|
|
||||||
|
import {
|
||||||
|
addNewEmojiFile,
|
||||||
|
changeStatusScope,
|
||||||
|
createEmojiPack,
|
||||||
|
deleteAccounts,
|
||||||
|
deleteEmojiPack,
|
||||||
|
disableMFA,
|
||||||
|
downloadRemoteEmojiPack,
|
||||||
|
downloadRemoteEmojiPackZIP,
|
||||||
|
getAvailableFrontends,
|
||||||
|
getInstanceConfigDescriptions,
|
||||||
|
getInstanceDBConfig,
|
||||||
|
getUserData,
|
||||||
|
importEmojiFromFS,
|
||||||
|
installFrontend,
|
||||||
|
listRemoteEmojiPacks,
|
||||||
|
listStatuses,
|
||||||
|
listUsers,
|
||||||
|
pushInstanceDBConfig,
|
||||||
|
reloadEmoji,
|
||||||
|
requirePasswordChange,
|
||||||
|
resendConfirmationEmail,
|
||||||
|
setUsersActivationStatus,
|
||||||
|
setUsersApprovalStatus,
|
||||||
|
setUsersConfirmationStatus,
|
||||||
|
setUsersRight,
|
||||||
|
setUsersSuggestionStatus,
|
||||||
|
setUsersTags,
|
||||||
|
} from 'src/services/api/admin.js'
|
||||||
|
import { listEmojiPacks } from 'src/services/api/api.service.js'
|
||||||
import { parseStatus } from 'src/services/entity_normalizer/entity_normalizer.service.js'
|
import { parseStatus } from 'src/services/entity_normalizer/entity_normalizer.service.js'
|
||||||
|
|
||||||
export const defaultState = {
|
export const defaultState = {
|
||||||
|
|
@ -21,7 +53,6 @@ export const newUserFlags = {
|
||||||
export const useAdminSettingsStore = defineStore('adminSettings', {
|
export const useAdminSettingsStore = defineStore('adminSettings', {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
...cloneDeep(defaultState),
|
...cloneDeep(defaultState),
|
||||||
backendInteractor: window.vuex.state.api.backendInteractor,
|
|
||||||
}),
|
}),
|
||||||
actions: {
|
actions: {
|
||||||
// Configuration Stuff
|
// Configuration Stuff
|
||||||
|
|
@ -54,7 +85,9 @@ export const useAdminSettingsStore = defineStore('adminSettings', {
|
||||||
},
|
},
|
||||||
|
|
||||||
loadAdminStuff() {
|
loadAdminStuff() {
|
||||||
this.backendInteractor.fetchInstanceDBConfig().then((backendDbConfig) => {
|
getInstanceDBConfig({
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
|
}).then((backendDbConfig) => {
|
||||||
if (backendDbConfig.error) {
|
if (backendDbConfig.error) {
|
||||||
if (backendDbConfig.error.status === 400) {
|
if (backendDbConfig.error.status === 400) {
|
||||||
backendDbConfig.error.json().then((errorJson) => {
|
backendDbConfig.error.json().then((errorJson) => {
|
||||||
|
|
@ -64,15 +97,21 @@ export const useAdminSettingsStore = defineStore('adminSettings', {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.setInstanceAdminSettings({ backendDbConfig })
|
this.setInstanceAdminSettings({
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
|
backendDbConfig,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if (this.descriptions === null) {
|
if (this.descriptions === null) {
|
||||||
this.backendInteractor
|
getInstanceConfigDescriptions({
|
||||||
.fetchInstanceConfigDescriptions()
|
credentials: useOAuthStore().token,
|
||||||
.then((backendDescriptions) =>
|
}).then((backendDescriptions) =>
|
||||||
this.setInstanceAdminDescriptions({ backendDescriptions }),
|
this.setInstanceAdminDescriptions({
|
||||||
)
|
credentials: useOAuthStore().token,
|
||||||
|
backendDescriptions,
|
||||||
|
}),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setInstanceAdminSettings({ backendDbConfig }) {
|
setInstanceAdminSettings({ backendDbConfig }) {
|
||||||
|
|
@ -203,17 +242,23 @@ export const useAdminSettingsStore = defineStore('adminSettings', {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
window.vuex.state.api.backendInteractor
|
pushInstanceDBConfig({
|
||||||
.pushInstanceDBConfig({
|
credentials: useOAuthStore().token,
|
||||||
payload: {
|
payload: {
|
||||||
configs: changed,
|
configs: changed,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then(() =>
|
.then(() =>
|
||||||
window.vuex.state.api.backendInteractor.fetchInstanceDBConfig(),
|
getInstanceDBConfig({
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
.then((backendDbConfig) =>
|
.then((backendDbConfig) =>
|
||||||
this.setInstanceAdminSettings({ backendDbConfig }),
|
this.setInstanceAdminSettings({
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
|
|
||||||
|
backendDbConfig,
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
pushAdminSetting({ path, value }) {
|
pushAdminSetting({ path, value }) {
|
||||||
|
|
@ -234,23 +279,28 @@ export const useAdminSettingsStore = defineStore('adminSettings', {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.vuex.state.api.backendInteractor
|
pushInstanceDBConfig({
|
||||||
.pushInstanceDBConfig({
|
credentials: useOAuthStore().token,
|
||||||
payload: {
|
payload: {
|
||||||
configs: [
|
configs: [
|
||||||
{
|
{
|
||||||
group,
|
group,
|
||||||
key,
|
key,
|
||||||
value: convert(clone),
|
value: convert(clone),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then(() =>
|
.then(() =>
|
||||||
window.vuex.state.api.backendInteractor.fetchInstanceDBConfig(),
|
getInstanceDBConfig({
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
.then((backendDbConfig) =>
|
.then((backendDbConfig) =>
|
||||||
this.setInstanceAdminSettings({ backendDbConfig }),
|
this.setInstanceAdminSettings({
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
|
backendDbConfig,
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
resetAdminSetting({ path }) {
|
resetAdminSetting({ path }) {
|
||||||
|
|
@ -260,21 +310,23 @@ export const useAdminSettingsStore = defineStore('adminSettings', {
|
||||||
|
|
||||||
this.modifiedPaths.delete(path)
|
this.modifiedPaths.delete(path)
|
||||||
|
|
||||||
return window.vuex.state.api.backendInteractor
|
return pushInstanceDBConfig({
|
||||||
.pushInstanceDBConfig({
|
credentials: useOAuthStore().token,
|
||||||
payload: {
|
payload: {
|
||||||
configs: [
|
configs: [
|
||||||
{
|
{
|
||||||
group,
|
group,
|
||||||
key,
|
key,
|
||||||
delete: true,
|
delete: true,
|
||||||
subkeys: [subkey],
|
subkeys: [subkey],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then(() =>
|
.then(() =>
|
||||||
window.vuex.state.api.backendInteractor.fetchInstanceDBConfig(),
|
getInstanceDBConfig({
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
.then((backendDbConfig) =>
|
.then((backendDbConfig) =>
|
||||||
this.setInstanceAdminSettings({ backendDbConfig }),
|
this.setInstanceAdminSettings({ backendDbConfig }),
|
||||||
|
|
@ -283,9 +335,9 @@ export const useAdminSettingsStore = defineStore('adminSettings', {
|
||||||
|
|
||||||
// Frontends Stuff
|
// Frontends Stuff
|
||||||
loadFrontendsStuff() {
|
loadFrontendsStuff() {
|
||||||
this.backendInteractor
|
getAvailableFrontends({
|
||||||
.fetchAvailableFrontends()
|
credentials: useOAuthStore().token,
|
||||||
.then((frontends) => this.setAvailableFrontends({ frontends }))
|
}).then((frontends) => this.setAvailableFrontends({ frontends }))
|
||||||
},
|
},
|
||||||
|
|
||||||
setAvailableFrontends({ frontends }) {
|
setAvailableFrontends({ frontends }) {
|
||||||
|
|
@ -300,12 +352,18 @@ export const useAdminSettingsStore = defineStore('adminSettings', {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
installFrontend() {
|
||||||
|
return installFrontend({
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
// Statuses stuff
|
// Statuses stuff
|
||||||
async fetchStatuses(opts) {
|
async fetchStatuses(opts) {
|
||||||
const { total, activities } =
|
const { total, activities } = await listStatuses({
|
||||||
await this.backendInteractor.adminListStatuses({
|
credentials: useOAuthStore().token,
|
||||||
opts,
|
opts,
|
||||||
})
|
})
|
||||||
|
|
||||||
const statuses = activities.map(parseStatus)
|
const statuses = activities.map(parseStatus)
|
||||||
|
|
||||||
|
|
@ -317,7 +375,8 @@ export const useAdminSettingsStore = defineStore('adminSettings', {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async changeStatusScope(opts) {
|
async changeStatusScope(opts) {
|
||||||
const raw = await this.backendInteractor.adminChangeStatusScope({
|
const raw = await changeStatusScope({
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
opts,
|
opts,
|
||||||
})
|
})
|
||||||
const status = parseStatus(raw)
|
const status = parseStatus(raw)
|
||||||
|
|
@ -327,7 +386,9 @@ export const useAdminSettingsStore = defineStore('adminSettings', {
|
||||||
|
|
||||||
// Users stuff
|
// Users stuff
|
||||||
async fetchUsers(opts) {
|
async fetchUsers(opts) {
|
||||||
const { users, count } = await this.backendInteractor.adminListUsers({
|
const { users, count } = await listUsers({
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
|
|
||||||
opts,
|
opts,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -344,17 +405,23 @@ export const useAdminSettingsStore = defineStore('adminSettings', {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async getUserData({ user }) {
|
async getUserData({ user }) {
|
||||||
const api = this.backendInteractor.adminGetUserData
|
const api = getUserData
|
||||||
const { screen_name } = user
|
const { screen_name } = user
|
||||||
|
|
||||||
const result = await api({ screen_name })
|
const result = await api({
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
|
screen_name,
|
||||||
|
})
|
||||||
window.vuex.commit('updateUserAdminData', { user: result })
|
window.vuex.commit('updateUserAdminData', { user: result })
|
||||||
},
|
},
|
||||||
async deleteUsers({ users }) {
|
async deleteUsers({ users }) {
|
||||||
const screen_names = users.map((u) => u.screen_name)
|
const screen_names = users.map((u) => u.screen_name)
|
||||||
const api = this.backendInteractor.adminDeleteAccounts
|
const api = deleteAccounts
|
||||||
|
|
||||||
const resultUserIds = await api({ screen_names })
|
const resultUserIds = await api({
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
|
screen_names,
|
||||||
|
})
|
||||||
|
|
||||||
resultUserIds.forEach((userId) => {
|
resultUserIds.forEach((userId) => {
|
||||||
window.vuex.dispatch(
|
window.vuex.dispatch(
|
||||||
|
|
@ -369,14 +436,16 @@ export const useAdminSettingsStore = defineStore('adminSettings', {
|
||||||
resendConfirmationEmail({ users }) {
|
resendConfirmationEmail({ users }) {
|
||||||
const screen_names = users.map((u) => u.screen_name)
|
const screen_names = users.map((u) => u.screen_name)
|
||||||
|
|
||||||
return this.backendInteractor.adminResendConfirmationEmail({
|
return resendConfirmationEmail({
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
screen_names,
|
screen_names,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
requirePasswordChange({ users }) {
|
requirePasswordChange({ users }) {
|
||||||
const screen_names = users.map((u) => u.screen_name)
|
const screen_names = users.map((u) => u.screen_name)
|
||||||
|
|
||||||
return this.backendInteractor.adminRequirePasswordChange({
|
return requirePasswordChange({
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
screen_names,
|
screen_names,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
@ -384,13 +453,17 @@ export const useAdminSettingsStore = defineStore('adminSettings', {
|
||||||
disableMFA({ user }) {
|
disableMFA({ user }) {
|
||||||
const { screen_name } = user
|
const { screen_name } = user
|
||||||
|
|
||||||
return this.backendInteractor.adminDisableMFA({ screen_name })
|
return disableMFA({
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
|
screen_name,
|
||||||
|
})
|
||||||
},
|
},
|
||||||
async setUsersTags({ users, tags, value }) {
|
async setUsersTags({ users, tags, value }) {
|
||||||
const screen_names = users.map((u) => u.screen_name)
|
const screen_names = users.map((u) => u.screen_name)
|
||||||
const api = this.backendInteractor.adminSetUsersTags
|
const api = setUsersTags
|
||||||
|
|
||||||
await api({
|
await api({
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
screen_names,
|
screen_names,
|
||||||
tags,
|
tags,
|
||||||
value,
|
value,
|
||||||
|
|
@ -402,9 +475,10 @@ export const useAdminSettingsStore = defineStore('adminSettings', {
|
||||||
},
|
},
|
||||||
async setUsersRight({ users, right, value }) {
|
async setUsersRight({ users, right, value }) {
|
||||||
const screen_names = users.map((u) => u.screen_name)
|
const screen_names = users.map((u) => u.screen_name)
|
||||||
const api = this.backendInteractor.adminSetUsersRight
|
const api = setUsersRight
|
||||||
|
|
||||||
await api({
|
await api({
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
screen_names,
|
screen_names,
|
||||||
right,
|
right,
|
||||||
value,
|
value,
|
||||||
|
|
@ -416,9 +490,10 @@ export const useAdminSettingsStore = defineStore('adminSettings', {
|
||||||
},
|
},
|
||||||
async setUsersActivationStatus({ users, value }) {
|
async setUsersActivationStatus({ users, value }) {
|
||||||
const screen_names = users.map((u) => u.screen_name)
|
const screen_names = users.map((u) => u.screen_name)
|
||||||
const api = this.backendInteractor.adminSetUsersActivationStatus
|
const api = setUsersActivationStatus
|
||||||
|
|
||||||
const resultUsers = await api({
|
const resultUsers = await api({
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
screen_names,
|
screen_names,
|
||||||
value,
|
value,
|
||||||
})
|
})
|
||||||
|
|
@ -429,9 +504,10 @@ export const useAdminSettingsStore = defineStore('adminSettings', {
|
||||||
},
|
},
|
||||||
async setUsersSuggestionStatus({ users, value }) {
|
async setUsersSuggestionStatus({ users, value }) {
|
||||||
const screen_names = users.map((u) => u.screen_name)
|
const screen_names = users.map((u) => u.screen_name)
|
||||||
const api = this.backendInteractor.adminSetUsersSuggestionStatus
|
const api = setUsersSuggestionStatus
|
||||||
|
|
||||||
const resultUsers = await api({
|
const resultUsers = await api({
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
screen_names,
|
screen_names,
|
||||||
value,
|
value,
|
||||||
})
|
})
|
||||||
|
|
@ -442,9 +518,12 @@ export const useAdminSettingsStore = defineStore('adminSettings', {
|
||||||
},
|
},
|
||||||
async setUsersConfirmationStatus({ users }) {
|
async setUsersConfirmationStatus({ users }) {
|
||||||
const screen_names = users.map((u) => u.screen_name)
|
const screen_names = users.map((u) => u.screen_name)
|
||||||
const api = this.backendInteractor.adminSetUsersConfirmationStatus
|
const api = setUsersConfirmationStatus
|
||||||
|
|
||||||
await api({ screen_names })
|
await api({
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
|
screen_names,
|
||||||
|
})
|
||||||
|
|
||||||
users.forEach((user) => {
|
users.forEach((user) => {
|
||||||
this.getUserData({ user })
|
this.getUserData({ user })
|
||||||
|
|
@ -452,9 +531,10 @@ export const useAdminSettingsStore = defineStore('adminSettings', {
|
||||||
},
|
},
|
||||||
async setUsersApprovalStatus({ users }) {
|
async setUsersApprovalStatus({ users }) {
|
||||||
const screen_names = users.map((u) => u.screen_name)
|
const screen_names = users.map((u) => u.screen_name)
|
||||||
const api = this.backendInteractor.adminSetUsersApprovalStatus
|
const api = setUsersApprovalStatus
|
||||||
|
|
||||||
const resultUsers = await api({
|
const resultUsers = await api({
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
screen_names,
|
screen_names,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -462,5 +542,66 @@ export const useAdminSettingsStore = defineStore('adminSettings', {
|
||||||
window.vuex.commit('updateUserAdminData', { user })
|
window.vuex.commit('updateUserAdminData', { user })
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
reloadEmoji() {
|
||||||
|
return reloadEmoji({ credentials: useOAuthStore().token })
|
||||||
|
},
|
||||||
|
importEmojiFromFS() {
|
||||||
|
return importEmojiFromFS({ credentials: useOAuthStore().token })
|
||||||
|
},
|
||||||
|
listEmojiPacks(params) {
|
||||||
|
return listEmojiPacks({
|
||||||
|
...params,
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
listRemoteEmojiPacks(params) {
|
||||||
|
return listRemoteEmojiPacks({
|
||||||
|
...params,
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
addNewEmojiFile({ packName, file, shortcode, filename }) {
|
||||||
|
return addNewEmojiFile({
|
||||||
|
packName,
|
||||||
|
file,
|
||||||
|
shortcode,
|
||||||
|
filename,
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
downloadRemoteEmojiPack({ instance, packName, as }) {
|
||||||
|
return downloadRemoteEmojiPack({
|
||||||
|
instance,
|
||||||
|
packName,
|
||||||
|
as,
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
downloadRemoteEmojiPackZIP({ url, packName }) {
|
||||||
|
return downloadRemoteEmojiPackZIP({
|
||||||
|
url,
|
||||||
|
packName,
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
createEmojiPack({ name }) {
|
||||||
|
return createEmojiPack({
|
||||||
|
name,
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
deleteEmojiPack({ name }) {
|
||||||
|
return createEmojiPack({
|
||||||
|
name,
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
saveEmojiPackMetadata({ name, newData }) {
|
||||||
|
return createEmojiPack({
|
||||||
|
name,
|
||||||
|
newData,
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
|
})
|
||||||
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,18 @@
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
|
import { useOAuthStore } from 'src/stores/oauth.js'
|
||||||
|
|
||||||
|
import {
|
||||||
|
getAnnouncements as adminGetAnnouncements,
|
||||||
|
deleteAnnouncement,
|
||||||
|
editAnnouncement,
|
||||||
|
postAnnouncement,
|
||||||
|
} from 'src/services/api/admin.js'
|
||||||
|
import {
|
||||||
|
dismissAnnouncement,
|
||||||
|
getAnnouncements,
|
||||||
|
} from 'src/services/api/api.service.js'
|
||||||
|
|
||||||
const FETCH_ANNOUNCEMENT_INTERVAL_MS = 1000 * 60 * 5
|
const FETCH_ANNOUNCEMENT_INTERVAL_MS = 1000 * 60 * 5
|
||||||
|
|
||||||
export const useAnnouncementsStore = defineStore('announcements', {
|
export const useAnnouncementsStore = defineStore('announcements', {
|
||||||
|
|
@ -31,15 +44,19 @@ export const useAnnouncementsStore = defineStore('announcements', {
|
||||||
currentUser &&
|
currentUser &&
|
||||||
currentUser.privileges.has('announcements_manage_announcements')
|
currentUser.privileges.has('announcements_manage_announcements')
|
||||||
|
|
||||||
const getAnnouncements = async () => {
|
const fetchAnnouncements = async () => {
|
||||||
if (!isAdmin) {
|
if (!isAdmin) {
|
||||||
return window.vuex.state.api.backendInteractor.fetchAnnouncements()
|
return getAnnouncements({
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const all =
|
const all = await adminGetAnnouncements({
|
||||||
await window.vuex.state.api.backendInteractor.adminFetchAnnouncements()
|
credentials: useOAuthStore().token,
|
||||||
const visible =
|
})
|
||||||
await window.vuex.state.api.backendInteractor.fetchAnnouncements()
|
const visible = await getAnnouncements({
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
|
})
|
||||||
const visibleObject = visible.reduce((a, c) => {
|
const visibleObject = visible.reduce((a, c) => {
|
||||||
a[c.id] = c
|
a[c.id] = c
|
||||||
return a
|
return a
|
||||||
|
|
@ -59,7 +76,7 @@ export const useAnnouncementsStore = defineStore('announcements', {
|
||||||
return all
|
return all
|
||||||
}
|
}
|
||||||
|
|
||||||
return getAnnouncements()
|
return fetchAnnouncements()
|
||||||
.then((announcements) => {
|
.then((announcements) => {
|
||||||
this.announcements = announcements
|
this.announcements = announcements
|
||||||
})
|
})
|
||||||
|
|
@ -74,17 +91,18 @@ export const useAnnouncementsStore = defineStore('announcements', {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
markAnnouncementAsRead(id) {
|
markAnnouncementAsRead(id) {
|
||||||
return window.vuex.state.api.backendInteractor
|
return dismissAnnouncement({
|
||||||
.dismissAnnouncement({ id })
|
id,
|
||||||
.then(() => {
|
credentials: useOAuthStore().token,
|
||||||
const index = this.announcements.findIndex((a) => a.id === id)
|
}).then(() => {
|
||||||
|
const index = this.announcements.findIndex((a) => a.id === id)
|
||||||
|
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
this.announcements[index].read = true
|
this.announcements[index].read = true
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
startFetchingAnnouncements() {
|
startFetchingAnnouncements() {
|
||||||
if (this.fetchAnnouncementsTimer) {
|
if (this.fetchAnnouncementsTimer) {
|
||||||
|
|
@ -105,25 +123,35 @@ export const useAnnouncementsStore = defineStore('announcements', {
|
||||||
clearInterval(interval)
|
clearInterval(interval)
|
||||||
},
|
},
|
||||||
postAnnouncement({ content, startsAt, endsAt, allDay }) {
|
postAnnouncement({ content, startsAt, endsAt, allDay }) {
|
||||||
return window.vuex.state.api.backendInteractor
|
return postAnnouncement({
|
||||||
.postAnnouncement({ content, startsAt, endsAt, allDay })
|
credentials: useOAuthStore().token,
|
||||||
.then(() => {
|
content,
|
||||||
return this.fetchAnnouncements()
|
startsAt,
|
||||||
})
|
endsAt,
|
||||||
|
allDay,
|
||||||
|
}).then(() => {
|
||||||
|
return this.fetchAnnouncements()
|
||||||
|
})
|
||||||
},
|
},
|
||||||
editAnnouncement({ id, content, startsAt, endsAt, allDay }) {
|
editAnnouncement({ id, content, startsAt, endsAt, allDay }) {
|
||||||
return window.vuex.state.api.backendInteractor
|
return editAnnouncement({
|
||||||
.editAnnouncement({ id, content, startsAt, endsAt, allDay })
|
id,
|
||||||
.then(() => {
|
content,
|
||||||
return this.fetchAnnouncements()
|
startsAt,
|
||||||
})
|
endsAt,
|
||||||
|
allDay,
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
|
}).then(() => {
|
||||||
|
return this.fetchAnnouncements()
|
||||||
|
})
|
||||||
},
|
},
|
||||||
deleteAnnouncement(id) {
|
deleteAnnouncement(id) {
|
||||||
return window.vuex.state.api.backendInteractor
|
return deleteAnnouncement({
|
||||||
.deleteAnnouncement({ id })
|
id,
|
||||||
.then(() => {
|
credentials: useOAuthStore().token,
|
||||||
return this.fetchAnnouncements()
|
}).then(() => {
|
||||||
})
|
return this.fetchAnnouncements()
|
||||||
|
})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,16 @@
|
||||||
import { find, remove } from 'lodash'
|
import { find, remove } from 'lodash'
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
|
import { useOAuthStore } from 'src/stores/oauth.js'
|
||||||
|
|
||||||
|
import {
|
||||||
|
createBookmarkFolder,
|
||||||
|
deleteBookmarkFolder,
|
||||||
|
fetchBookmarkFolders,
|
||||||
|
updateBookmarkFolder,
|
||||||
|
} 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: () => ({
|
||||||
allFolders: [],
|
allFolders: [],
|
||||||
|
|
@ -16,6 +26,23 @@ export const useBookmarkFoldersStore = defineStore('bookmarkFolders', {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
|
startFetching() {
|
||||||
|
promiseInterval(() => {
|
||||||
|
this.fetcher = fetchBookmarkFolders({
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
|
})
|
||||||
|
.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
|
||||||
},
|
},
|
||||||
|
|
@ -30,23 +57,31 @@ export const useBookmarkFoldersStore = defineStore('bookmarkFolders', {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
createBookmarkFolder({ name, emoji }) {
|
createBookmarkFolder({ name, emoji }) {
|
||||||
return window.vuex.state.api.backendInteractor
|
return createBookmarkFolder({
|
||||||
.createBookmarkFolder({ name, emoji })
|
name,
|
||||||
.then((folder) => {
|
emoji,
|
||||||
this.setBookmarkFolder(folder)
|
credentials: useOAuthStore().token,
|
||||||
return folder
|
}).then((folder) => {
|
||||||
})
|
this.setBookmarkFolder(folder)
|
||||||
|
return folder
|
||||||
|
})
|
||||||
},
|
},
|
||||||
updateBookmarkFolder({ folderId, name, emoji }) {
|
updateBookmarkFolder({ folderId, name, emoji }) {
|
||||||
return window.vuex.state.api.backendInteractor
|
return updateBookmarkFolder({
|
||||||
.updateBookmarkFolder({ folderId, name, emoji })
|
credentials: useOAuthStore().token,
|
||||||
.then((folder) => {
|
folderId,
|
||||||
this.setBookmarkFolder(folder)
|
name,
|
||||||
return folder
|
emoji,
|
||||||
})
|
}).then((folder) => {
|
||||||
|
this.setBookmarkFolder(folder)
|
||||||
|
return folder
|
||||||
|
})
|
||||||
},
|
},
|
||||||
deleteBookmarkFolder({ folderId }) {
|
deleteBookmarkFolder({ folderId }) {
|
||||||
window.vuex.state.api.backendInteractor.deleteBookmarkFolder({ folderId })
|
deleteBookmarkFolder({
|
||||||
|
folderId,
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
|
})
|
||||||
remove(this.allFolders, (folder) => folder.id === folderId)
|
remove(this.allFolders, (folder) => folder.id === folderId)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,10 @@ import { merge } from 'lodash'
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
import { useInstanceStore } from 'src/stores/instance.js'
|
import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
|
import { useOAuthStore } from 'src/stores/oauth.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,14 @@ 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,
|
(params) =>
|
||||||
|
listEmojiPacks({
|
||||||
|
...params,
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
this.adminPacksLocalLoading = false
|
this.adminPacksLocalLoading = false
|
||||||
},
|
},
|
||||||
|
|
@ -206,7 +209,6 @@ export const useEmojiStore = defineStore('emoji', {
|
||||||
page: 1,
|
page: 1,
|
||||||
pageSize: 0,
|
pageSize: 0,
|
||||||
})
|
})
|
||||||
.then((data) => data.json())
|
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
if (data.error !== undefined) {
|
if (data.error !== undefined) {
|
||||||
return Promise.reject(data.error)
|
return Promise.reject(data.error)
|
||||||
|
|
@ -220,15 +222,13 @@ export const useEmojiStore = defineStore('emoji', {
|
||||||
instance,
|
instance,
|
||||||
page: i,
|
page: i,
|
||||||
pageSize,
|
pageSize,
|
||||||
})
|
}).then((pageData) => {
|
||||||
.then((data) => data.json())
|
if (pageData.error !== undefined) {
|
||||||
.then((pageData) => {
|
return Promise.reject(pageData.error)
|
||||||
if (pageData.error !== undefined) {
|
}
|
||||||
return Promise.reject(pageData.error)
|
|
||||||
}
|
|
||||||
|
|
||||||
return pageData.packs
|
return pageData.packs
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -247,7 +247,7 @@ export const useEmojiStore = defineStore('emoji', {
|
||||||
}, {})
|
}, {})
|
||||||
})
|
})
|
||||||
.catch((data) => {
|
.catch((data) => {
|
||||||
this.displayError(data)
|
console.error(data)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import {
|
||||||
LOCAL_DEFAULT_CONFIG_DEFINITIONS,
|
LOCAL_DEFAULT_CONFIG_DEFINITIONS,
|
||||||
validateSetting,
|
validateSetting,
|
||||||
} from '../modules/default_config_state.js'
|
} from '../modules/default_config_state.js'
|
||||||
import apiService from '../services/api/api.service.js'
|
import { fetchKnownDomains } from '../services/api/api.service.js'
|
||||||
|
|
||||||
import { useInterfaceStore } from 'src/stores/interface.js'
|
import { useInterfaceStore } from 'src/stores/interface.js'
|
||||||
|
|
||||||
|
|
@ -210,7 +210,7 @@ export const useInstanceStore = defineStore('instance', {
|
||||||
},
|
},
|
||||||
async getKnownDomains() {
|
async getKnownDomains() {
|
||||||
try {
|
try {
|
||||||
this.knownDomains = await apiService.fetchKnownDomains({
|
this.knownDomains = await fetchKnownDomains({
|
||||||
credentials: window.vuex.state.users.currentUser.credentials,
|
credentials: window.vuex.state.users.currentUser.credentials,
|
||||||
})
|
})
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,23 @@
|
||||||
import { find, remove } from 'lodash'
|
import { find, remove } from 'lodash'
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
|
import { useOAuthStore } from 'src/stores/oauth.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: useOAuthStore().token,
|
||||||
|
})
|
||||||
|
.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: useOAuthStore().token,
|
||||||
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: useOAuthStore().token,
|
||||||
|
}).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: useOAuthStore().token,
|
||||||
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: useOAuthStore().token,
|
||||||
|
})
|
||||||
|
|
||||||
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: useOAuthStore().token,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (removed.length > 0) {
|
if (removed.length > 0) {
|
||||||
window.vuex.state.api.backendInteractor.removeAccountsFromList({
|
removeAccountsFromList({
|
||||||
listId,
|
listId,
|
||||||
accountIds: removed,
|
accountIds: removed,
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
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: useOAuthStore().token,
|
||||||
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: useOAuthStore().token,
|
||||||
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: useOAuthStore().token,
|
||||||
|
})
|
||||||
|
|
||||||
delete this.allListsObject[listId]
|
delete this.allListsObject[listId]
|
||||||
remove(this.allLists, (list) => list.id === listId)
|
remove(this.allLists, (list) => list.id === listId)
|
||||||
|
|
|
||||||
|
|
@ -41,12 +41,9 @@ export const useOAuthStore = defineStore('oauth', {
|
||||||
userToken: false,
|
userToken: false,
|
||||||
}),
|
}),
|
||||||
getters: {
|
getters: {
|
||||||
getToken() {
|
token() {
|
||||||
return this.userToken || this.appToken
|
return this.userToken || this.appToken
|
||||||
},
|
},
|
||||||
getUserToken() {
|
|
||||||
return this.userToken
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
setClientData({ clientId, clientSecret }) {
|
setClientData({ clientId, clientSecret }) {
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,33 @@
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
|
import { useOAuthStore } from 'src/stores/oauth.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: useOAuthStore().token,
|
||||||
.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: useOAuthStore().token,
|
||||||
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
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,10 @@
|
||||||
import { merge } from 'lodash'
|
import { merge } from 'lodash'
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
|
import { useOAuthStore } from 'src/stores/oauth.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: useOAuthStore().token,
|
||||||
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: useOAuthStore().token,
|
||||||
return poll
|
}).then((poll) => {
|
||||||
})
|
this.mergeOrAddPoll(poll)
|
||||||
|
return poll
|
||||||
|
})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,9 @@ import { filter } from 'lodash'
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
import { useInterfaceStore } from 'src/stores/interface.js'
|
import { useInterfaceStore } from 'src/stores/interface.js'
|
||||||
|
import { useOAuthStore } from 'src/stores/oauth.js'
|
||||||
|
|
||||||
|
import { setReportState } from 'src/services/api/admin.js'
|
||||||
|
|
||||||
export const useReportsStore = defineStore('reports', {
|
export const useReportsStore = defineStore('reports', {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
|
|
@ -38,18 +41,21 @@ export const useReportsStore = defineStore('reports', {
|
||||||
setReportState({ id, state }) {
|
setReportState({ id, state }) {
|
||||||
const oldState = this.reports[id].state
|
const oldState = this.reports[id].state
|
||||||
this.reports[id].state = state
|
this.reports[id].state = state
|
||||||
window.vuex.state.api.backendInteractor
|
|
||||||
.setReportState({ id, state })
|
setReportState({
|
||||||
.catch((e) => {
|
id,
|
||||||
console.error('Failed to set report state', e)
|
state,
|
||||||
useInterfaceStore().pushGlobalNotice({
|
credentials: useOAuthStore().token,
|
||||||
level: 'error',
|
}).catch((e) => {
|
||||||
messageKey: 'general.generic_error_message',
|
console.error('Failed to set report state', e)
|
||||||
messageArgs: [e.message],
|
useInterfaceStore().pushGlobalNotice({
|
||||||
timeout: 5000,
|
level: 'error',
|
||||||
})
|
messageKey: 'general.generic_error_message',
|
||||||
this.reports[id].state = oldState
|
messageArgs: [e.message],
|
||||||
|
timeout: 5000,
|
||||||
})
|
})
|
||||||
|
this.reports[id].state = oldState
|
||||||
|
})
|
||||||
},
|
},
|
||||||
addReport(report) {
|
addReport(report) {
|
||||||
this.reports[report.id] = report
|
this.reports[report.id] = report
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ import { CURRENT_UPDATE_COUNTER } from 'src/components/update_notification/updat
|
||||||
|
|
||||||
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'
|
||||||
|
import { useOAuthStore } from 'src/stores/oauth.js'
|
||||||
|
|
||||||
import { storage } from 'src/lib/storage.js'
|
import { storage } from 'src/lib/storage.js'
|
||||||
import {
|
import {
|
||||||
|
|
@ -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: useOAuthStore().token,
|
||||||
|
})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
persist: {
|
persist: {
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,10 @@ import {
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import { toRaw } from 'vue'
|
import { toRaw } from 'vue'
|
||||||
|
|
||||||
|
import { useOAuthStore } from 'src/stores/oauth.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: useOAuthStore().token,
|
||||||
this.initUserHighlight(user)
|
}).then((user) => {
|
||||||
this.dirty = false
|
this.initUserHighlight(user)
|
||||||
})
|
this.dirty = false
|
||||||
|
})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
persist: {
|
persist: {
|
||||||
|
|
|
||||||
|
|
@ -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: '',
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue