Merge branch 'api-refactor' into shigusegubu-themes3

This commit is contained in:
Henry Jameson 2026-06-26 00:47:55 +03:00
commit d407a4e880
65 changed files with 235 additions and 330 deletions

View file

@ -73,7 +73,7 @@ test:
e2e-pleroma: e2e-pleroma:
stage: test stage: test
image: mcr.microsoft.com/playwright:v1.57.0-jammy image: mcr.microsoft.com/playwright:v1.61.0-jammy
services: services:
- name: postgres:15-alpine - name: postgres:15-alpine
alias: db alias: db

View file

@ -25,7 +25,7 @@ variables:
steps: steps:
test: test:
image: mcr.microsoft.com/playwright:v1.57.0-jammy image: mcr.microsoft.com/playwright:v1.61.0-jammy
entrypoint: *script_file_entrypoint entrypoint: *script_file_entrypoint
environment: environment:
APT_CACHE_DIR: apt-cache APT_CACHE_DIR: apt-cache

View file

@ -25,7 +25,7 @@ variables:
steps: steps:
test: test:
image: mcr.microsoft.com/playwright:v1.57.0-jammy image: mcr.microsoft.com/playwright:v1.61.0-jammy
environment: environment:
APT_CACHE_DIR: apt-cache APT_CACHE_DIR: apt-cache
DEBIAN_FRONTEND: noninteractive DEBIAN_FRONTEND: noninteractive

View file

@ -46,6 +46,7 @@
"noUnusedLabels": "error", "noUnusedLabels": "error",
"noUnusedPrivateClassMembers": "error", "noUnusedPrivateClassMembers": "error",
"noUnusedVariables": "error", "noUnusedVariables": "error",
"noUnusedImports": "error",
"useIsNan": "error", "useIsNan": "error",
"useValidForDirection": "error", "useValidForDirection": "error",
"useValidTypeof": "error", "useValidTypeof": "error",

View file

@ -1,4 +1,3 @@
import { readFile } from 'node:fs/promises'
import { dirname, resolve } from 'node:path' import { dirname, resolve } from 'node:path'
import { fileURLToPath } from 'node:url' import { fileURLToPath } from 'node:url'
import { exactRegex } from '@rolldown/pluginutils' import { exactRegex } from '@rolldown/pluginutils'

View file

@ -1,4 +1,4 @@
FROM mcr.microsoft.com/playwright:v1.57.0-jammy FROM mcr.microsoft.com/playwright:v1.61.0-jammy
WORKDIR /app WORKDIR /app

View file

@ -21,9 +21,6 @@ import { useInterfaceStore } from 'src/stores/interface.js'
import { useMergedConfigStore } from 'src/stores/merged_config.js' import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { useShoutStore } from 'src/stores/shout.js' import { useShoutStore } from 'src/stores/shout.js'
import messages from 'src/i18n/messages'
import localeService from 'src/services/locale/locale.service.js'
// Helper to unwrap reactive proxies // Helper to unwrap reactive proxies
window.toValue = (x) => JSON.parse(JSON.stringify(x)) window.toValue = (x) => JSON.parse(JSON.stringify(x))

View file

@ -1,7 +1,5 @@
import { promisedRequest } from './helpers.js' import { promisedRequest } from './helpers.js'
import { RegistrationError, StatusCodeError } from 'src/services/errors/errors'
const REPORTS = '/api/v1/pleroma/admin/reports' const REPORTS = '/api/v1/pleroma/admin/reports'
const CONFIG_URL = '/api/v1/pleroma/admin/config' const CONFIG_URL = '/api/v1/pleroma/admin/config'
const DESCRIPTIONS_URL = '/api/v1/pleroma/admin/config/descriptions' const DESCRIPTIONS_URL = '/api/v1/pleroma/admin/config/descriptions'

View file

@ -1,6 +1,6 @@
import { snakeCase } from 'lodash' import { snakeCase } from 'lodash'
import { RegistrationError, StatusCodeError } from 'src/services/errors/errors' import { StatusCodeError } from 'src/services/errors/errors'
export const paramsString = (params = {}) => { export const paramsString = (params = {}) => {
if (params == null || params === undefined) return '' if (params == null || params === undefined) return ''

View file

@ -1,5 +1,3 @@
import { reduce } from 'lodash'
import { paramsString, promisedRequest } from './helpers.js' import { paramsString, promisedRequest } from './helpers.js'
const REDIRECT_URI = `${window.location.origin}/oauth-callback` const REDIRECT_URI = `${window.location.origin}/oauth-callback`

View file

@ -1,13 +1,11 @@
import { paramsString, promisedRequest } from './helpers.js' import { paramsString, promisedRequest } from './helpers.js'
import { MASTODON_USER_TIMELINE_URL } from './timelines.js'
import { import {
parseLinkHeaderPagination,
parseNotification,
parseSource, parseSource,
parseStatus, parseStatus,
parseUser, parseUser,
} from 'src/services/entity_normalizer/entity_normalizer.service.js' } from 'src/services/entity_normalizer/entity_normalizer.service.js'
import { RegistrationError, StatusCodeError } from 'src/services/errors/errors'
const MASTODON_SUGGESTIONS_URL = '/api/v1/suggestions' const MASTODON_SUGGESTIONS_URL = '/api/v1/suggestions'
const MASTODON_LOGIN_URL = '/api/v1/accounts/verify_credentials' const MASTODON_LOGIN_URL = '/api/v1/accounts/verify_credentials'
@ -15,15 +13,6 @@ const MASTODON_REGISTRATION_URL = '/api/v1/accounts'
const MASTODON_PASSWORD_RESET_URL = ({ email }) => const MASTODON_PASSWORD_RESET_URL = ({ email }) =>
`/auth/password${paramsString({ email })}` `/auth/password${paramsString({ email })}`
const MASTODON_USER_NOTIFICATIONS_URL = ({
minId,
sinceId,
maxId,
limit,
includeTypes,
replyVisibility,
}) =>
`/api/v1/notifications${paramsString({ minId, sinceId, maxId, limit, includeTypes, replyVisibility })}`
const MASTODON_FOLLOWING_URL = ( const MASTODON_FOLLOWING_URL = (
id, id,
{ minId, maxId, sinceId, limit, withRelationships }, { minId, maxId, sinceId, limit, withRelationships },
@ -35,84 +24,6 @@ const MASTODON_FOLLOWERS_URL = (
) => ) =>
`/api/v1/accounts/${id}/followers${paramsString({ minId, maxId, sinceId, limit, withRelationships })}` `/api/v1/accounts/${id}/followers${paramsString({ minId, maxId, sinceId, limit, withRelationships })}`
const MASTODON_USER_HOME_TIMELINE_URL = ({
minId,
sinceId,
maxId,
limit,
replyVisibility,
}) =>
`/api/v1/timelines/home${paramsString({ minId, sinceId, maxId, limit, replyVisibility })}`
const MASTODON_LIST_TIMELINE_URL = (
id,
{ minId, sinceId, maxId, limit, replyVisibility },
) =>
`/api/v1/timelines/list/${id}${paramsString({ minId, sinceId, maxId, limit, replyVisibility })}`
const MASTODON_DIRECT_MESSAGES_TIMELINE_URL = ({
minId,
sinceId,
maxId,
limit,
replyVisibility,
}) =>
`/api/v1/timelines/direct${paramsString({ minId, sinceId, maxId, limit, replyVisibility })}`
const MASTODON_PUBLIC_TIMELINE = ({
minId,
sinceId,
maxId,
limit,
replyVisibility,
local,
remote,
onlyMedia,
}) =>
`/api/v1/timelines/public${paramsString({ minId, sinceId, maxId, limit, replyVisibility, local, remote, onlyMedia })}`
const MASTODON_TAG_TIMELINE_URL = (
tag,
{ minId, sinceId, maxId, limit, replyVisibility },
) =>
`/api/v1/timelines/tag/${tag}${paramsString({ minId, sinceId, maxId, limit, replyVisibility })}`
const MASTODON_USER_TIMELINE_URL = (
id,
{ minId, sinceId, maxId, limit, replyVisibility, pinned, onlyMedia },
) =>
`/api/v1/accounts/${id}/statuses${paramsString({ minId, sinceId, maxId, limit, replyVisibility, pinned, onlyMedia })}`
const MASTODON_USER_FAVORITES_TIMELINE_URL = ({
minId,
sinceId,
maxId,
limit,
replyVisibility,
}) =>
`/api/v1/favourites${paramsString({ minId, sinceId, maxId, limit, replyVisibility })}`
const MASTODON_BOOKMARK_TIMELINE_URL = ({
minId,
sinceId,
maxId,
limit,
replyVisibility,
folderId,
}) =>
`/api/v1/bookmarks${paramsString({ minId, sinceId, maxId, limit, replyVisibility, folderId })}`
const PLEROMA_STATUS_QUOTES_URL = (
id,
{ minId, sinceId, maxId, limit, replyVisibility },
) =>
`/api/v1/pleroma/statuses/${id}/quotes${paramsString({ minId, sinceId, maxId, limit, replyVisibility })}`
const PLEROMA_USER_FAVORITES_TIMELINE_URL = (
id,
{ minId, sinceId, maxId, limit, replyVisibility },
) =>
`/api/v1/pleroma/accounts/${id}/favourites${paramsString({ minId, sinceId, maxId, limit, replyVisibility })}`
const AKKOMA_BUBBLE_TIMELINE_URL = ({
minId,
sinceId,
maxId,
limit,
replyVisibility,
}) =>
`/api/v1/timelines/bubble${paramsString({ minId, sinceId, maxId, limit, replyVisibility })}`
export const MASTODON_STATUS_URL = (id) => `/api/v1/statuses/${id}` export const MASTODON_STATUS_URL = (id) => `/api/v1/statuses/${id}`
const MASTODON_STATUS_CONTEXT_URL = (id) => `/api/v1/statuses/${id}/context` const MASTODON_STATUS_CONTEXT_URL = (id) => `/api/v1/statuses/${id}/context`
const MASTODON_STATUS_SOURCE_URL = (id) => `/api/v1/statuses/${id}/source` const MASTODON_STATUS_SOURCE_URL = (id) => `/api/v1/statuses/${id}/source`
@ -231,38 +142,26 @@ export const fetchConversation = ({ id, credentials }) =>
promisedRequest({ promisedRequest({
url: MASTODON_STATUS_CONTEXT_URL(id), url: MASTODON_STATUS_CONTEXT_URL(id),
credentials, credentials,
}) }).then((result) => ({
.then((result) => ({ ...result,
...result, data: {
data: { ...result.data,
...result.data, ancestors: result.data.ancestors.map(parseStatus),
ancestors: result.data.ancestors.map(parseStatus), descendants: result.data.descendants.map(parseStatus),
descendants: result.data.descendants.map(parseStatus), },
}, }))
}))
.catch((error) => {
throw new Error('Error fetching timeline', error)
})
export const fetchStatus = ({ id, credentials }) => export const fetchStatus = ({ id, credentials }) =>
promisedRequest({ promisedRequest({
url: MASTODON_STATUS_URL(id), url: MASTODON_STATUS_URL(id),
credentials, credentials,
}) }).then(({ data, ...rest }) => ({ ...rest, data: parseStatus(data) }))
.then(({ data, ...rest }) => ({ ...rest, data: parseStatus(data) }))
.catch((error) => {
throw new Error('Error fetching timeline', error)
})
export const fetchStatusSource = ({ id, credentials }) => export const fetchStatusSource = ({ id, credentials }) =>
promisedRequest({ promisedRequest({
url: MASTODON_STATUS_SOURCE_URL(id), url: MASTODON_STATUS_SOURCE_URL(id),
credentials, credentials,
}) }).then(({ data, ...rest }) => ({ ...rest, data: parseSource(data) }))
.then(({ data, ...rest }) => ({ ...rest, data: parseSource(data) }))
.catch((error) => {
throw new Error('Error fetching timeline', error)
})
export const fetchStatusHistory = ({ status, credentials }) => export const fetchStatusHistory = ({ status, credentials }) =>
promisedRequest({ promisedRequest({
@ -275,109 +174,6 @@ export const fetchStatusHistory = ({ status, credentials }) =>
}) })
}) })
export const fetchTimeline = ({
timeline,
credentials,
sinceId,
minId,
maxId,
userId,
listId,
statusId,
tag,
withMuted,
replyVisibility = 'all',
includeTypes = [],
bookmarkFolderId,
}) => {
const timelineUrls = {
friends: MASTODON_USER_HOME_TIMELINE_URL,
public: MASTODON_PUBLIC_TIMELINE,
publicAndExternal: MASTODON_PUBLIC_TIMELINE,
dms: MASTODON_DIRECT_MESSAGES_TIMELINE_URL,
user: MASTODON_USER_TIMELINE_URL,
media: MASTODON_USER_TIMELINE_URL,
list: MASTODON_LIST_TIMELINE_URL,
favorites: MASTODON_USER_FAVORITES_TIMELINE_URL,
publicFavorites: PLEROMA_USER_FAVORITES_TIMELINE_URL,
bookmarks: MASTODON_BOOKMARK_TIMELINE_URL,
bubble: AKKOMA_BUBBLE_TIMELINE_URL,
tag: MASTODON_TAG_TIMELINE_URL,
quotes: PLEROMA_STATUS_QUOTES_URL,
notifications: MASTODON_USER_NOTIFICATIONS_URL,
}
const urlFunc = timelineUrls[timeline]
const twoArgs = new Set([
'user',
'media',
'list',
'publicFavorites',
'tag',
'quotes',
])
const params = {
minId,
sinceId,
maxId,
limit: 20,
}
const id = (() => {
switch (timeline) {
case 'user':
case 'media':
return userId
case 'list':
return listId
case 'quotes':
return statusId
case 'tag':
return tag
}
})()
const isNotifications = timeline === 'notifications'
if (timeline === 'media') {
params.onlyMedia = true
}
if (timeline === 'public') {
params.local = true
}
if (timeline !== 'favorites' && timeline !== 'bookmarks') {
params.withMuted = withMuted
}
if (replyVisibility !== 'all') {
params.replyVisibility = replyVisibility
}
if (timeline === 'bookmarks' && bookmarkFolderId) {
params.folderId = bookmarkFolderId
}
if (isNotifications && includeTypes.length > 0) {
params.includeTypes = includeTypes
}
const url = twoArgs.has(timeline) ? urlFunc(id, params) : urlFunc(params)
return promisedRequest({ url, credentials }).then((result) => {
const pagination = parseLinkHeaderPagination(
result.response.headers.get('Link'),
{
flakeId: timeline !== 'bookmarks' && timeline !== 'notifications',
},
)
return {
...result,
data: result.data.map(isNotifications ? parseNotification : parseStatus),
pagination,
}
})
}
export const listEmojiPacks = ({ page, pageSize, credentials }) => export const listEmojiPacks = ({ page, pageSize, credentials }) =>
promisedRequest({ promisedRequest({
url: EMOJI_PACKS_URL(page, pageSize), url: EMOJI_PACKS_URL(page, pageSize),
@ -467,15 +263,11 @@ export const search2 = ({
withRelationships: true, withRelationships: true,
}), }),
credentials, credentials,
}).then(({ data, ...rest }) => {
data.accounts = data.accounts.slice(0, limit).map((u) => parseUser(u))
data.statuses = data.statuses.slice(0, limit).map((s) => parseStatus(s))
return { ...rest, data }
}) })
.then(({ data, ...rest }) => {
data.accounts = data.accounts.slice(0, limit).map((u) => parseUser(u))
data.statuses = data.statuses.slice(0, limit).map((s) => parseStatus(s))
return { ...rest, data }
})
.catch((error) => {
throw new Error('Error fetching timeline', error)
})
} }
export const fetchKnownDomains = ({ credentials }) => export const fetchKnownDomains = ({ credentials }) =>

198
src/api/timelines.js Normal file
View file

@ -0,0 +1,198 @@
import { paramsString, promisedRequest } from './helpers.js'
import {
parseLinkHeaderPagination,
parseNotification,
parseStatus,
} from 'src/services/entity_normalizer/entity_normalizer.service.js'
const MASTODON_USER_HOME_TIMELINE_URL = ({
minId,
sinceId,
maxId,
limit,
replyVisibility,
}) =>
`/api/v1/timelines/home${paramsString({ minId, sinceId, maxId, limit, replyVisibility })}`
const MASTODON_LIST_TIMELINE_URL = (
id,
{ minId, sinceId, maxId, limit, replyVisibility },
) =>
`/api/v1/timelines/list/${id}${paramsString({ minId, sinceId, maxId, limit, replyVisibility })}`
const MASTODON_DIRECT_MESSAGES_TIMELINE_URL = ({
minId,
sinceId,
maxId,
limit,
replyVisibility,
}) =>
`/api/v1/timelines/direct${paramsString({ minId, sinceId, maxId, limit, replyVisibility })}`
const MASTODON_PUBLIC_TIMELINE = ({
minId,
sinceId,
maxId,
limit,
replyVisibility,
local,
remote,
onlyMedia,
}) =>
`/api/v1/timelines/public${paramsString({ minId, sinceId, maxId, limit, replyVisibility, local, remote, onlyMedia })}`
const MASTODON_TAG_TIMELINE_URL = (
tag,
{ minId, sinceId, maxId, limit, replyVisibility },
) =>
`/api/v1/timelines/tag/${tag}${paramsString({ minId, sinceId, maxId, limit, replyVisibility })}`
export const MASTODON_USER_TIMELINE_URL = (
id,
{ minId, sinceId, maxId, limit, replyVisibility, pinned, onlyMedia },
) =>
`/api/v1/accounts/${id}/statuses${paramsString({ minId, sinceId, maxId, limit, replyVisibility, pinned, onlyMedia })}`
const MASTODON_USER_FAVORITES_TIMELINE_URL = ({
minId,
sinceId,
maxId,
limit,
replyVisibility,
}) =>
`/api/v1/favourites${paramsString({ minId, sinceId, maxId, limit, replyVisibility })}`
const MASTODON_BOOKMARK_TIMELINE_URL = ({
minId,
sinceId,
maxId,
limit,
replyVisibility,
folderId,
}) =>
`/api/v1/bookmarks${paramsString({ minId, sinceId, maxId, limit, replyVisibility, folderId })}`
const PLEROMA_STATUS_QUOTES_URL = (
id,
{ minId, sinceId, maxId, limit, replyVisibility },
) =>
`/api/v1/pleroma/statuses/${id}/quotes${paramsString({ minId, sinceId, maxId, limit, replyVisibility })}`
const PLEROMA_USER_FAVORITES_TIMELINE_URL = (
id,
{ minId, sinceId, maxId, limit, replyVisibility },
) =>
`/api/v1/pleroma/accounts/${id}/favourites${paramsString({ minId, sinceId, maxId, limit, replyVisibility })}`
const AKKOMA_BUBBLE_TIMELINE_URL = ({
minId,
sinceId,
maxId,
limit,
replyVisibility,
}) =>
`/api/v1/timelines/bubble${paramsString({ minId, sinceId, maxId, limit, replyVisibility })}`
const MASTODON_USER_NOTIFICATIONS_URL = ({
minId,
sinceId,
maxId,
limit,
includeTypes,
replyVisibility,
}) =>
`/api/v1/notifications${paramsString({ minId, sinceId, maxId, limit, includeTypes, replyVisibility })}`
export const fetchTimeline = ({
timeline,
credentials,
sinceId,
minId,
maxId,
userId,
listId,
statusId,
tag,
withMuted,
replyVisibility = 'all',
includeTypes = [],
bookmarkFolderId,
}) => {
const timelineUrls = {
friends: MASTODON_USER_HOME_TIMELINE_URL,
public: MASTODON_PUBLIC_TIMELINE,
publicAndExternal: MASTODON_PUBLIC_TIMELINE,
dms: MASTODON_DIRECT_MESSAGES_TIMELINE_URL,
user: MASTODON_USER_TIMELINE_URL,
media: MASTODON_USER_TIMELINE_URL,
list: MASTODON_LIST_TIMELINE_URL,
favorites: MASTODON_USER_FAVORITES_TIMELINE_URL,
publicFavorites: PLEROMA_USER_FAVORITES_TIMELINE_URL,
bookmarks: MASTODON_BOOKMARK_TIMELINE_URL,
bubble: AKKOMA_BUBBLE_TIMELINE_URL,
tag: MASTODON_TAG_TIMELINE_URL,
quotes: PLEROMA_STATUS_QUOTES_URL,
notifications: MASTODON_USER_NOTIFICATIONS_URL,
}
const urlFunc = timelineUrls[timeline]
const twoArgs = new Set([
'user',
'media',
'list',
'publicFavorites',
'tag',
'quotes',
])
const params = {
minId,
sinceId,
maxId,
limit: 20,
}
const id = (() => {
switch (timeline) {
case 'user':
case 'media':
return userId
case 'list':
return listId
case 'quotes':
return statusId
case 'tag':
return tag
}
})()
const isNotifications = timeline === 'notifications'
if (timeline === 'media') {
params.onlyMedia = true
}
if (timeline === 'public') {
params.local = true
}
if (timeline !== 'favorites' && timeline !== 'bookmarks') {
params.withMuted = withMuted
}
if (replyVisibility !== 'all') {
params.replyVisibility = replyVisibility
}
if (timeline === 'bookmarks' && bookmarkFolderId) {
params.folderId = bookmarkFolderId
}
if (isNotifications && includeTypes.length > 0) {
params.includeTypes = includeTypes
}
const url = twoArgs.has(timeline) ? urlFunc(id, params) : urlFunc(params)
return promisedRequest({ url, credentials }).then((result) => {
const pagination = parseLinkHeaderPagination(
result.response.headers.get('Link'),
{
flakeId: timeline !== 'bookmarks' && timeline !== 'notifications',
},
)
return {
...result,
data: result.data.map(isNotifications ? parseNotification : parseStatus),
pagination,
}
})
}

View file

@ -1,4 +1,4 @@
import { paramsString, promisedRequest } from './helpers.js' import { paramsString } from './helpers.js'
import { import {
parseChat, parseChat,

View file

@ -28,7 +28,6 @@ import {
} from '../services/window_utils/window_utils' } from '../services/window_utils/window_utils'
import routes from './routes' import routes from './routes'
import { useAnnouncementsStore } from 'src/stores/announcements'
import { useAuthFlowStore } from 'src/stores/auth_flow' import { useAuthFlowStore } from 'src/stores/auth_flow'
import { useEmojiStore } from 'src/stores/emoji.js' import { useEmojiStore } from 'src/stores/emoji.js'
import { useI18nStore } from 'src/stores/i18n' import { useI18nStore } from 'src/stores/i18n'

View file

@ -2,7 +2,6 @@ import { mapState } from 'pinia'
import { defineAsyncComponent } from 'vue' import { defineAsyncComponent } from 'vue'
import Popover from 'src/components/popover/popover.vue' import Popover from 'src/components/popover/popover.vue'
import VideoAttachment from 'src/components/video_attachment/video_attachment.vue'
import nsfwImage from '../../assets/nsfw.png' import nsfwImage from '../../assets/nsfw.png'
import { useInstanceStore } from 'src/stores/instance.js' import { useInstanceStore } from 'src/stores/instance.js'

View file

@ -1,6 +1,5 @@
import { mapState as mapPiniaState } from 'pinia' import { mapState as mapPiniaState } from 'pinia'
import { defineAsyncComponent } from 'vue' import { mapState } from 'vuex'
import { mapGetters, mapState } from 'vuex'
import Attachment from 'src/components/attachment/attachment.vue' import Attachment from 'src/components/attachment/attachment.vue'
import ChatMessageDate from 'src/components/chat_message_date/chat_message_date.vue' import ChatMessageDate from 'src/components/chat_message_date/chat_message_date.vue'

View file

@ -5,8 +5,6 @@ import UserAvatar from 'src/components/user_avatar/user_avatar.vue'
import { useOAuthStore } from 'src/stores/oauth.js' import { useOAuthStore } from 'src/stores/oauth.js'
import { chats } from 'src/api/chats.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'

View file

@ -1,5 +1,3 @@
import { defineAsyncComponent } from 'vue'
import UserAvatar from 'src/components/user_avatar/user_avatar.vue' import UserAvatar from 'src/components/user_avatar/user_avatar.vue'
import UserPopover from 'src/components/user_popover/user_popover.vue' import UserPopover from 'src/components/user_popover/user_popover.vue'

View file

@ -1,5 +1,3 @@
import { useEmojiStore } from 'src/stores/emoji.js'
/** /**
* suggest - generates a suggestor function to be used by emoji-input * suggest - generates a suggestor function to be used by emoji-input
* data: object providing source information for specific types of suggestions: * data: object providing source information for specific types of suggestions:

View file

@ -6,7 +6,6 @@ import Popover from 'src/components/popover/popover.vue'
import { ensureFinalFallback } from '../../i18n/languages.js' import { ensureFinalFallback } from '../../i18n/languages.js'
import { useEmojiStore } from 'src/stores/emoji.js' import { useEmojiStore } from 'src/stores/emoji.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 { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'

View file

@ -4,7 +4,6 @@ import { mapState } from 'vuex'
import { getListEntries } from 'src/components/navigation/filter.js' import { getListEntries } from 'src/components/navigation/filter.js'
import NavigationEntry from 'src/components/navigation/navigation_entry.vue' import NavigationEntry from 'src/components/navigation/navigation_entry.vue'
import { useInstanceStore } from 'src/stores/instance.js'
import { useListsStore } from 'src/stores/lists.js' import { useListsStore } from 'src/stores/lists.js'
export const ListsMenuContent = { export const ListsMenuContent = {

View file

@ -1,4 +1,4 @@
import { mapActions, mapState as mapPiniaState, mapStores } from 'pinia' import { mapActions, mapState as mapPiniaState } from 'pinia'
import { mapState } from 'vuex' import { mapState } from 'vuex'
import { useAuthFlowStore } from 'src/stores/auth_flow.js' import { useAuthFlowStore } from 'src/stores/auth_flow.js'

View file

@ -1,7 +1,6 @@
import { defineAsyncComponent } from 'vue' import { defineAsyncComponent } from 'vue'
import Modal from 'src/components/modal/modal.vue' import Modal from 'src/components/modal/modal.vue'
import StillImage from 'src/components/still-image/still-image.vue'
import GestureService from '../../services/gesture_service/gesture_service' import GestureService from '../../services/gesture_service/gesture_service'
import { useMediaViewerStore } from 'src/stores/media_viewer.js' import { useMediaViewerStore } from 'src/stores/media_viewer.js'

View file

@ -1,6 +1,5 @@
import { mapState as mapPiniaState } from 'pinia' import { mapState as mapPiniaState } from 'pinia'
import { defineAsyncComponent } from 'vue' import { mapState } from 'vuex'
import { mapGetters, mapState } from 'vuex'
import UnicodeDomainIndicator from 'src/components/unicode_domain_indicator/unicode_domain_indicator.vue' import UnicodeDomainIndicator from 'src/components/unicode_domain_indicator/unicode_domain_indicator.vue'
import UserAvatar from 'src/components/user_avatar/user_avatar.vue' import UserAvatar from 'src/components/user_avatar/user_avatar.vue'

View file

@ -4,7 +4,6 @@ import ConfirmModal from 'src/components/confirm_modal/confirm_modal.vue'
import Popover from 'src/components/popover/popover.vue' import Popover from 'src/components/popover/popover.vue'
import { useAdminSettingsStore } from 'src/stores/admin_settings.js' import { useAdminSettingsStore } from 'src/stores/admin_settings.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 { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'

View file

@ -1,7 +1,6 @@
import { debounce, map, reject, uniqBy } from 'lodash' import { debounce, map, reject, uniqBy } from 'lodash'
import { mapActions, mapState } from 'pinia' import { mapActions, mapState } from 'pinia'
import { defineAsyncComponent } from 'vue' import { defineAsyncComponent } from 'vue'
import { mapGetters } from 'vuex'
import Attachment from 'src/components/attachment/attachment.vue' import Attachment from 'src/components/attachment/attachment.vue'
import Checkbox from 'src/components/checkbox/checkbox.vue' import Checkbox from 'src/components/checkbox/checkbox.vue'

View file

@ -1,5 +1,4 @@
import { get } from 'lodash' import { get } from 'lodash'
import { defineAsyncComponent } from 'vue'
import Modal from 'src/components/modal/modal.vue' import Modal from 'src/components/modal/modal.vue'
import PostStatusForm from 'src/components/post_status_form/post_status_form.vue' import PostStatusForm from 'src/components/post_status_form/post_status_form.vue'

View file

@ -1,5 +1,3 @@
import { defineAsyncComponent } from 'vue'
import { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'
import { faCircleNotch } from '@fortawesome/free-solid-svg-icons' import { faCircleNotch } from '@fortawesome/free-solid-svg-icons'

View file

@ -1,5 +1,3 @@
import { defineAsyncComponent } from 'vue'
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 ModerationTools from 'src/components/moderation_tools/moderation_tools.vue' import ModerationTools from 'src/components/moderation_tools/moderation_tools.vue'

View file

@ -2,7 +2,7 @@ import Checkbox from 'components/checkbox/checkbox.vue'
import Popover from 'components/popover/popover.vue' import Popover from 'components/popover/popover.vue'
import Select from 'components/select/select.vue' import Select from 'components/select/select.vue'
import StillImage from 'components/still-image/still-image.vue' import StillImage from 'components/still-image/still-image.vue'
import { assign, clone } from 'lodash' import { clone } from 'lodash'
import { defineAsyncComponent } from 'vue' import { defineAsyncComponent } from 'vue'
import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx' import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx'

View file

@ -1,5 +1,3 @@
import { isEmpty } from 'lodash'
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 Checkbox from 'src/components/checkbox/checkbox.vue' import Checkbox from 'src/components/checkbox/checkbox.vue'
import List from 'src/components/list/list.vue' import List from 'src/components/list/list.vue'

View file

@ -5,7 +5,6 @@ import LocalSettingIndicator from './local_setting_indicator.vue'
import ModifiedIndicator from './modified_indicator.vue' import ModifiedIndicator from './modified_indicator.vue'
import { useAdminSettingsStore } from 'src/stores/admin_settings.js' import { useAdminSettingsStore } from 'src/stores/admin_settings.js'
import { useInstanceStore } from 'src/stores/instance.js'
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'

View file

@ -1,8 +1,7 @@
// eslint-disable-next-line no-unused // eslint-disable-next-line no-unused
import { throttle } from 'lodash' import { mapState as mapPiniaState } from 'pinia'
import { mapState as mapPiniaState, mapState } from 'pinia' import { Fragment } from 'vue'
import { Fragment, h } from 'vue'
import { FontAwesomeIcon as FAIcon } from '@fortawesome/vue-fontawesome' import { FontAwesomeIcon as FAIcon } from '@fortawesome/vue-fontawesome'

View file

@ -1,4 +1,3 @@
import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx'
import AuthTab from './admin_tabs/auth_tab.vue' import AuthTab from './admin_tabs/auth_tab.vue'
import EmojiTab from './admin_tabs/emoji_tab.vue' import EmojiTab from './admin_tabs/emoji_tab.vue'
import FederationTab from './admin_tabs/federation_tab.vue' import FederationTab from './admin_tabs/federation_tab.vue'

View file

@ -8,7 +8,6 @@ import FloatSetting from '../helpers/float_setting.vue'
import SharedComputedObject from '../helpers/shared_computed_object.js' import SharedComputedObject from '../helpers/shared_computed_object.js'
import UnitSetting from '../helpers/unit_setting.vue' import UnitSetting from '../helpers/unit_setting.vue'
import { 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'

View file

@ -1,4 +1,4 @@
import { get, isEmpty, map, reject } from 'lodash' import { get, map, reject } from 'lodash'
import Autosuggest from 'src/components/autosuggest/autosuggest.vue' import Autosuggest from 'src/components/autosuggest/autosuggest.vue'
import BlockCard from 'src/components/block_card/block_card.vue' import BlockCard from 'src/components/block_card/block_card.vue'

View file

@ -6,7 +6,6 @@ import SharedComputedObject from '../helpers/shared_computed_object.js'
import UnitSetting from '../helpers/unit_setting.vue' import UnitSetting from '../helpers/unit_setting.vue'
import { useLocalConfigStore } from 'src/stores/local_config.js' import { useLocalConfigStore } from 'src/stores/local_config.js'
import { useSyncConfigStore } from 'src/stores/sync_config.js'
const PostsTab = { const PostsTab = {
data() { data() {

View file

@ -1,5 +1,4 @@
import VueQrcode from '@chenfengyuan/vue-qrcode' import VueQrcode from '@chenfengyuan/vue-qrcode'
import { mapState } from 'vuex'
import Confirm from './confirm.vue' import Confirm from './confirm.vue'
import RecoveryCodes from './mfa_backup_codes.vue' import RecoveryCodes from './mfa_backup_codes.vue'

View file

@ -1,5 +1,3 @@
import { mapState } from 'vuex'
import Confirm from './confirm.vue' import Confirm from './confirm.vue'
import { useOAuthStore } from 'src/stores/oauth.js' import { useOAuthStore } from 'src/stores/oauth.js'

View file

@ -2,7 +2,6 @@ import Checkbox from 'src/components/checkbox/checkbox.vue'
import ProgressButton from 'src/components/progress_button/progress_button.vue' import ProgressButton from 'src/components/progress_button/progress_button.vue'
import Mfa from './mfa.vue' import Mfa from './mfa.vue'
import { 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 { useOAuthStore } from 'src/stores/oauth.js'
import { useOAuthTokensStore } from 'src/stores/oauth_tokens' import { useOAuthTokensStore } from 'src/stores/oauth_tokens'

View file

@ -1,5 +1,4 @@
import { mapActions, mapState } from 'pinia' import { mapActions, mapState } from 'pinia'
import { defineAsyncComponent } from 'vue'
import { mapGetters } from 'vuex' import { mapGetters } from 'vuex'
import { USERNAME_ROUTES } from 'src/components/navigation/navigation.js' import { USERNAME_ROUTES } from 'src/components/navigation/navigation.js'

View file

@ -1,6 +1,5 @@
import { mapState as mapPiniaState } from 'pinia' import { mapState as mapPiniaState } from 'pinia'
import { defineAsyncComponent } from 'vue' import { mapState } from 'vuex'
import { mapGetters, mapState } from 'vuex'
import Attachment from 'src/components/attachment/attachment.vue' import Attachment from 'src/components/attachment/attachment.vue'
import Gallery from 'src/components/gallery/gallery.vue' import Gallery from 'src/components/gallery/gallery.vue'

View file

@ -1,7 +1,6 @@
import { find } from 'lodash' import { find } from 'lodash'
import Popover from 'src/components/popover/popover.vue' import Popover from 'src/components/popover/popover.vue'
import Status from 'src/components/status/status.vue'
import { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'
import { faCircleNotch } from '@fortawesome/free-solid-svg-icons' import { faCircleNotch } from '@fortawesome/free-solid-svg-icons'

View file

@ -4,7 +4,6 @@ import statusPosterService from '../../services/status_poster/status_poster.serv
import TabSwitcher from '../tab_switcher/tab_switcher.jsx' import TabSwitcher from '../tab_switcher/tab_switcher.jsx'
import { useEmojiStore } from 'src/stores/emoji.js' import { useEmojiStore } from 'src/stores/emoji.js'
import { useInstanceStore } from 'src/stores/instance.js'
const StickerPicker = { const StickerPicker = {
components: { components: {

View file

@ -1,14 +1,11 @@
// eslint-disable-next-line no-unused // eslint-disable-next-line no-unused
import { mapState } from 'pinia' import { Fragment } from 'vue'
import { Fragment, h } from 'vue'
import { FontAwesomeIcon as FAIcon } from '@fortawesome/vue-fontawesome' import { FontAwesomeIcon as FAIcon } from '@fortawesome/vue-fontawesome'
import './tab_switcher.scss' import './tab_switcher.scss'
import { useInterfaceStore } from 'src/stores/interface.js'
const findFirstUsable = (slots) => slots.findIndex((_) => _.props) const findFirstUsable = (slots) => slots.findIndex((_) => _.props)
export default { export default {

View file

@ -22,7 +22,6 @@ 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'

View file

@ -1,5 +1,3 @@
import { defineAsyncComponent } from 'vue'
import Popover from 'src/components/popover/popover.vue' import Popover from 'src/components/popover/popover.vue'
import UnicodeDomainIndicator from 'src/components/unicode_domain_indicator/unicode_domain_indicator.vue' import UnicodeDomainIndicator from 'src/components/unicode_domain_indicator/unicode_domain_indicator.vue'
import UserAvatar from 'src/components/user_avatar/user_avatar.vue' import UserAvatar from 'src/components/user_avatar/user_avatar.vue'

View file

@ -1,5 +1,4 @@
import { mapState } from 'pinia' import { mapState } from 'pinia'
import { defineAsyncComponent } from 'vue'
import Popover from 'src/components/popover/popover.vue' import Popover from 'src/components/popover/popover.vue'
import UserCard from 'src/components/user_card/user_card.vue' import UserCard from 'src/components/user_card/user_card.vue'

View file

@ -1,5 +1,4 @@
import { get } from 'lodash' import { get } from 'lodash'
import { mapState } from 'pinia'
import FollowCard from 'src/components/follow_card/follow_card.vue' import FollowCard from 'src/components/follow_card/follow_card.vue'
import List from 'src/components/list/list.vue' import List from 'src/components/list/list.vue'
@ -7,7 +6,6 @@ import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx'
import Timeline from 'src/components/timeline/timeline.vue' import Timeline from 'src/components/timeline/timeline.vue'
import UserCard from 'src/components/user_card/user_card.vue' import UserCard from 'src/components/user_card/user_card.vue'
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 { useMergedConfigStore } from 'src/stores/merged_config.js' import { useMergedConfigStore } from 'src/stores/merged_config.js'

View file

@ -1,6 +1,3 @@
import { get } from 'lodash'
import { mapState } from 'pinia'
import Checkbox from 'src/components/checkbox/checkbox.vue' import Checkbox from 'src/components/checkbox/checkbox.vue'
import List from 'src/components/list/list.vue' import List from 'src/components/list/list.vue'
import Status from 'src/components/status/status.vue' import Status from 'src/components/status/status.vue'

View file

@ -1,6 +1,5 @@
import FollowCard from 'src/components/follow_card/follow_card.vue' import FollowCard from 'src/components/follow_card/follow_card.vue'
import { useInstanceStore } from 'src/stores/instance.js'
import { useOAuthStore } from 'src/stores/oauth.js' import { useOAuthStore } from 'src/stores/oauth.js'
import { fetchUser, suggestions } from 'src/api/public.js' import { fetchUser, suggestions } from 'src/api/public.js'

View file

@ -1,5 +1,3 @@
import Cookies from 'js-cookie'
import { useEmojiStore } from 'src/stores/emoji.js' import { useEmojiStore } from 'src/stores/emoji.js'
import { useI18nStore } from 'src/stores/i18n.js' import { useI18nStore } from 'src/stores/i18n.js'

View file

@ -2,13 +2,12 @@ import { Socket } from 'phoenix'
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 { 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 { useOAuthStore } from 'src/stores/oauth.js'
import { useShoutStore } from 'src/stores/shout.js' import { useShoutStore } from 'src/stores/shout.js'
import { fetchTimeline } from 'src/api/public.js' import { fetchTimeline } from 'src/api/timelines.js'
import { import {
getMastodonSocketURI, getMastodonSocketURI,
ProcessedWS, ProcessedWS,

View file

@ -1,4 +1,4 @@
import { get, set } from 'lodash' import { get } from 'lodash'
const browserLocale = (navigator.language || 'en').split('-')[0] const browserLocale = (navigator.language || 'en').split('-')[0]

View file

@ -1,11 +1,10 @@
import { promiseInterval } from '../promise_interval/promise_interval.js' import { promiseInterval } from '../promise_interval/promise_interval.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 { useMergedConfigStore } from 'src/stores/merged_config.js' import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { fetchTimeline } from 'src/api/public.js' import { fetchTimeline } from 'src/api/timelines.js'
const update = ({ store, notifications, older }) => { const update = ({ store, notifications, older }) => {
store.dispatch('addNewNotifications', { notifications, older }) store.dispatch('addNewNotifications', { notifications, older })

View file

@ -2,12 +2,11 @@ import { camelCase } from 'lodash'
import { promiseInterval } from '../promise_interval/promise_interval.js' import { promiseInterval } from '../promise_interval/promise_interval.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 { useMergedConfigStore } from 'src/stores/merged_config.js' import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { fetchTimeline } from 'src/api/public.js' import { fetchTimeline } from 'src/api/timelines.js'
const update = ({ const update = ({
store, store,

View file

@ -1,4 +1,4 @@
import { get, set } from 'lodash' import { set } from 'lodash'
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { import {

View file

@ -1,8 +1,5 @@
import { cloneDeep, set } from 'lodash' import { cloneDeep, set } from 'lodash'
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { toRaw } from 'vue'
import { useInstanceStore } from 'src/stores/instance'
import { import {
LOCAL_DEFAULT_CONFIG, LOCAL_DEFAULT_CONFIG,

View file

@ -20,7 +20,6 @@ import { toRaw } from 'vue'
import { CURRENT_UPDATE_COUNTER } from 'src/components/update_notification/update_notification.js' import { CURRENT_UPDATE_COUNTER } from 'src/components/update_notification/update_notification.js'
import { 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 { useOAuthStore } from 'src/stores/oauth.js'

View file

@ -1,15 +1,11 @@
import { import {
merge as _merge, merge as _merge,
clamp,
clone, clone,
cloneDeep, cloneDeep,
findLastIndex,
flatten, flatten,
get,
groupBy, groupBy,
isEqual, isEqual,
takeRight, takeRight,
uniqWith,
} from 'lodash' } from 'lodash'
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { toRaw } from 'vue' import { toRaw } from 'vue'
@ -33,17 +29,6 @@ export const defaultState = {
cache: null, cache: null,
} }
export const _moveItemInArray = (array, value, movement) => {
const oldIndex = array.indexOf(value)
const newIndex = oldIndex + movement
const newArray = [...array]
// remove old
newArray.splice(oldIndex, 1)
// add new
newArray.splice(clamp(newIndex, 0, newArray.length + 1), 0, value)
return newArray
}
const _wrapData = (data, userName) => { const _wrapData = (data, userName) => {
return { return {
...data, ...data,

View file

@ -2,7 +2,6 @@ import mastoapidata from '../../../../fixtures/mastoapi.json'
import { import {
parseLinkHeaderPagination, parseLinkHeaderPagination,
parseNotification,
parseStatus, parseStatus,
parseUser, parseUser,
} from 'src/services/entity_normalizer/entity_normalizer.service.js' } from 'src/services/entity_normalizer/entity_normalizer.service.js'

View file

@ -12,7 +12,7 @@ describe('The lists store', () => {
let store let store
beforeEach(() => { beforeEach(() => {
createTestingPinia({ stubActions: false }) setActivePinia(createTestingPinia({ stubActions: false }))
store = useListsStore() store = useListsStore()
}) })

View file

@ -9,8 +9,6 @@ import { useOAuthStore } from 'src/stores/oauth.js'
import { import {
MASTODON_APP_URL, MASTODON_APP_URL,
MASTODON_APP_VERIFY_URL, MASTODON_APP_VERIFY_URL,
OAUTH_MFA_CHALLENGE_URL,
OAUTH_REVOKE_URL,
OAUTH_TOKEN_URL, OAUTH_TOKEN_URL,
} from 'src/api/oauth.js' } from 'src/api/oauth.js'

View file

@ -1,10 +1,8 @@
import { cloneDeep } from 'lodash'
import { createPinia, setActivePinia } from 'pinia' import { createPinia, setActivePinia } from 'pinia'
import { import {
_getRecentData, _getRecentData,
_mergeHighlights, _mergeHighlights,
_moveItemInArray,
useUserHighlightStore, useUserHighlightStore,
} from 'src/stores/user_highlight.js' } from 'src/stores/user_highlight.js'

View file

@ -1,6 +1,5 @@
import { dirname, resolve } from 'node:path' import { dirname, resolve } from 'node:path'
import { fileURLToPath } from 'node:url' import { fileURLToPath } from 'node:url'
import { DevTools } from '@vitejs/devtools'
import vue from '@vitejs/plugin-vue' import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx' import vueJsx from '@vitejs/plugin-vue-jsx'
import { playwright } from '@vitest/browser-playwright' import { playwright } from '@vitest/browser-playwright'