mirror of
https://github.com/elk-zone/elk.git
synced 2024-11-23 09:55:28 +03:00
feat: upgrade to masto.js v6 (#2530)
This commit is contained in:
parent
d8ea685803
commit
6c5bb83ac3
62 changed files with 262 additions and 263 deletions
|
@ -19,7 +19,7 @@ const { client } = $(useMasto())
|
|||
async function unblock() {
|
||||
relationship!.blocking = false
|
||||
try {
|
||||
const newRel = await client.v1.accounts.unblock(account.id)
|
||||
const newRel = await client.v1.accounts.$select(account.id).unblock()
|
||||
Object.assign(relationship!, newRel)
|
||||
}
|
||||
catch (err) {
|
||||
|
@ -32,7 +32,7 @@ async function unblock() {
|
|||
async function unmute() {
|
||||
relationship!.muting = false
|
||||
try {
|
||||
const newRel = await client.v1.accounts.unmute(account.id)
|
||||
const newRel = await client.v1.accounts.$select(account.id).unmute()
|
||||
Object.assign(relationship!, newRel)
|
||||
}
|
||||
catch (err) {
|
||||
|
|
|
@ -12,7 +12,7 @@ async function authorizeFollowRequest() {
|
|||
relationship!.requestedBy = false
|
||||
relationship!.followedBy = true
|
||||
try {
|
||||
const newRel = await client.v1.followRequests.authorize(account.id)
|
||||
const newRel = await client.v1.followRequests.$select(account.id).authorize()
|
||||
Object.assign(relationship!, newRel)
|
||||
}
|
||||
catch (err) {
|
||||
|
@ -25,7 +25,7 @@ async function authorizeFollowRequest() {
|
|||
async function rejectFollowRequest() {
|
||||
relationship!.requestedBy = false
|
||||
try {
|
||||
const newRel = await client.v1.followRequests.reject(account.id)
|
||||
const newRel = await client.v1.followRequests.$select(account.id).reject()
|
||||
Object.assign(relationship!, newRel)
|
||||
}
|
||||
catch (err) {
|
||||
|
|
|
@ -53,7 +53,7 @@ function previewAvatar() {
|
|||
async function toggleNotifications() {
|
||||
relationship!.notifying = !relationship?.notifying
|
||||
try {
|
||||
const newRel = await client.v1.accounts.follow(account.id, { notify: relationship?.notifying })
|
||||
const newRel = await client.v1.accounts.$select(account.id).follow({ notify: relationship?.notifying })
|
||||
Object.assign(relationship!, newRel)
|
||||
}
|
||||
catch {
|
||||
|
@ -97,7 +97,7 @@ async function editNote(event: Event) {
|
|||
if (relationship.note?.trim() === newNote.trim())
|
||||
return
|
||||
|
||||
const newNoteApiResult = await client.v1.accounts.createNote(account.id, { comment: newNote })
|
||||
const newNoteApiResult = await client.v1.accounts.$select(account.id).note.create({ comment: newNote })
|
||||
relationship.note = newNoteApiResult.note
|
||||
personalNoteDraft.value = relationship.note ?? ''
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ async function toggleReblogs() {
|
|||
return
|
||||
|
||||
const showingReblogs = !relationship?.showingReblogs
|
||||
relationship = await client.v1.accounts.follow(account.id, { reblogs: showingReblogs })
|
||||
relationship = await client.v1.accounts.$select(account.id).follow({ reblogs: showingReblogs })
|
||||
}
|
||||
|
||||
async function addUserNote() {
|
||||
|
@ -44,7 +44,7 @@ async function removeUserNote() {
|
|||
if (!relationship!.note || relationship!.note.length === 0)
|
||||
return
|
||||
|
||||
const newNote = await client.v1.accounts.createNote(account.id, { comment: '' })
|
||||
const newNote = await client.v1.accounts.$select(account.id).note.create({ comment: '' })
|
||||
relationship!.note = newNote.note
|
||||
emit('removeNote')
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<script setup lang="ts">
|
||||
import type { Paginator, mastodon } from 'masto'
|
||||
import type { mastodon } from 'masto'
|
||||
|
||||
const { paginator, account, context } = defineProps<{
|
||||
paginator: Paginator<mastodon.v1.Account[], mastodon.DefaultPaginationParams>
|
||||
paginator: mastodon.Paginator<mastodon.v1.Account[], mastodon.DefaultPaginationParams | undefined>
|
||||
context?: 'following' | 'followers'
|
||||
account?: mastodon.v1.Account
|
||||
relationshipContext?: 'followedBy' | 'following'
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// @ts-expect-error missing types
|
||||
import { DynamicScroller } from 'vue-virtual-scroller'
|
||||
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
|
||||
import type { Paginator, WsEvents } from 'masto'
|
||||
import type { mastodon } from 'masto'
|
||||
import type { UnwrapRef } from 'vue'
|
||||
|
||||
const {
|
||||
|
@ -14,10 +14,10 @@ const {
|
|||
preprocess,
|
||||
endMessage = true,
|
||||
} = defineProps<{
|
||||
paginator: Paginator<T[], O>
|
||||
paginator: mastodon.Paginator<T[], O>
|
||||
keyProp?: keyof T
|
||||
virtualScroller?: boolean
|
||||
stream?: Promise<WsEvents>
|
||||
stream?: mastodon.streaming.Subscription
|
||||
eventType?: 'notification' | 'update'
|
||||
preprocess?: (items: (U | T)[]) => U[]
|
||||
endMessage?: boolean | string
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<script setup lang="ts">
|
||||
import type { Paginator, mastodon } from 'masto'
|
||||
import type { mastodon } from 'masto'
|
||||
|
||||
const { paginator } = defineProps<{
|
||||
paginator: Paginator<mastodon.v1.Conversation[], mastodon.DefaultPaginationParams>
|
||||
paginator: mastodon.Paginator<mastodon.v1.Conversation[], mastodon.DefaultPaginationParams>
|
||||
}>()
|
||||
|
||||
function preprocess(items: mastodon.v1.Conversation[]): mastodon.v1.Conversation[] {
|
||||
|
|
|
@ -16,8 +16,8 @@ const isRemoved = ref(false)
|
|||
async function edit() {
|
||||
try {
|
||||
isRemoved.value
|
||||
? await client.v1.lists.addAccount(list, { accountIds: [account.id] })
|
||||
: await client.v1.lists.removeAccount(list, { accountIds: [account.id] })
|
||||
? await client.v1.lists.$select(list).accounts.create({ accountIds: [account.id] })
|
||||
: await client.v1.lists.$select(list).accounts.remove({ accountIds: [account.id] })
|
||||
isRemoved.value = !isRemoved.value
|
||||
}
|
||||
catch (err) {
|
||||
|
|
|
@ -40,7 +40,7 @@ async function cancelEdit() {
|
|||
|
||||
const { submit, submitting } = submitter(async () => {
|
||||
try {
|
||||
list.value = await client.v1.lists.update(form.id, {
|
||||
list.value = await client.v1.lists.$select(form.id).update({
|
||||
title: form.title,
|
||||
})
|
||||
cancelEdit()
|
||||
|
@ -70,7 +70,7 @@ async function removeList() {
|
|||
if (confirmDelete === 'confirm') {
|
||||
await nextTick()
|
||||
try {
|
||||
await client.v1.lists.remove(list.value.id)
|
||||
await client.v1.lists.$select(list.value.id).remove()
|
||||
emit('listRemoved', list.value.id)
|
||||
}
|
||||
catch (err) {
|
||||
|
|
|
@ -5,7 +5,7 @@ const { userId } = defineProps<{
|
|||
|
||||
const { client } = $(useMasto())
|
||||
const paginator = client.v1.lists.list()
|
||||
const listsWithUser = ref((await client.v1.accounts.listLists(userId)).map(list => list.id))
|
||||
const listsWithUser = ref((await client.v1.accounts.$select(userId).lists.list()).map(list => list.id))
|
||||
|
||||
function indexOfUserInList(listId: string) {
|
||||
return listsWithUser.value.indexOf(listId)
|
||||
|
@ -15,11 +15,11 @@ async function edit(listId: string) {
|
|||
try {
|
||||
const index = indexOfUserInList(listId)
|
||||
if (index === -1) {
|
||||
await client.v1.lists.addAccount(listId, { accountIds: [userId] })
|
||||
await client.v1.lists.$select(listId).accounts.create({ accountIds: [userId] })
|
||||
listsWithUser.value.push(listId)
|
||||
}
|
||||
else {
|
||||
await client.v1.lists.removeAccount(listId, { accountIds: [userId] })
|
||||
await client.v1.lists.$select(listId).accounts.remove({ accountIds: [userId] })
|
||||
listsWithUser.value = listsWithUser.value.filter(id => id !== listId)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ const { notification } = defineProps<{
|
|||
ps-3 pe-4 inset-is-0
|
||||
rounded-ie-be-3
|
||||
py-3 bg-base top-0
|
||||
:lang="notification.status?.language ?? undefined"
|
||||
>
|
||||
<div i-ri-user-3-line text-xl me-3 color-blue />
|
||||
<AccountDisplayName :account="notification.account" text-primary me-1 font-bold line-clamp-1 ws-pre-wrap break-all />
|
||||
|
@ -26,7 +25,6 @@ const { notification } = defineProps<{
|
|||
<AccountBigCard
|
||||
ms10
|
||||
:account="notification.account"
|
||||
:lang="notification.status?.language ?? undefined"
|
||||
/>
|
||||
</NuxtLink>
|
||||
</template>
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<script setup lang="ts">
|
||||
// @ts-expect-error missing types
|
||||
import { DynamicScrollerItem } from 'vue-virtual-scroller'
|
||||
import type { Paginator, WsEvents, mastodon } from 'masto'
|
||||
import type { mastodon } from 'masto'
|
||||
import type { GroupedAccountLike, NotificationSlot } from '~/types'
|
||||
|
||||
const { paginator, stream } = defineProps<{
|
||||
paginator: Paginator<mastodon.v1.Notification[], mastodon.v1.ListNotificationsParams>
|
||||
stream?: Promise<WsEvents>
|
||||
paginator: mastodon.Paginator<mastodon.v1.Notification[], mastodon.rest.v1.ListNotificationsParams>
|
||||
stream?: mastodon.streaming.Subscription
|
||||
}>()
|
||||
|
||||
const virtualScroller = false // TODO: fix flickering issue with virtual scroll
|
||||
|
|
|
@ -75,12 +75,13 @@ function trimPollOptions() {
|
|||
}
|
||||
|
||||
function editPollOptionDraft(event: Event, index: number) {
|
||||
draft.params.poll!.options[index] = (event.target as HTMLInputElement).value
|
||||
draft.params.poll!.options = Object.assign(draft.params.poll!.options.slice(), { [index]: (event.target as HTMLInputElement).value })
|
||||
|
||||
trimPollOptions()
|
||||
}
|
||||
|
||||
function deletePollOption(index: number) {
|
||||
draft.params.poll!.options.splice(index, 1)
|
||||
draft.params.poll!.options = draft.params.poll!.options.slice().splice(index, 1)
|
||||
trimPollOptions()
|
||||
}
|
||||
|
||||
|
|
|
@ -34,11 +34,11 @@ function categoryChosen() {
|
|||
async function loadStatuses() {
|
||||
if (status) {
|
||||
// Load the 5 statuses before and after the reported status
|
||||
const prevStatuses = await client.value.v1.accounts.listStatuses(account.id, {
|
||||
const prevStatuses = await client.value.v1.accounts.$select(account.id).statuses.list({
|
||||
maxId: status.id,
|
||||
limit: 5,
|
||||
})
|
||||
const nextStatuses = await client.value.v1.accounts.listStatuses(account.id, {
|
||||
const nextStatuses = await client.value.v1.accounts.$select(account.id).statuses.list({
|
||||
minId: status.id,
|
||||
limit: 5,
|
||||
})
|
||||
|
@ -48,7 +48,7 @@ async function loadStatuses() {
|
|||
else {
|
||||
// Reporting an account directly
|
||||
// Load the 10 most recent statuses
|
||||
const mostRecentStatuses = await client.value.v1.accounts.listStatuses(account.id, {
|
||||
const mostRecentStatuses = await client.value.v1.accounts.$select(account.id).statuses.list({
|
||||
limit: 10,
|
||||
})
|
||||
availableStatuses.value = mostRecentStatuses
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import type { mastodon } from 'masto'
|
||||
|
||||
const form = defineModel<{
|
||||
fieldsAttributes: NonNullable<mastodon.v1.UpdateCredentialsParams['fieldsAttributes']>
|
||||
fieldsAttributes: NonNullable<mastodon.rest.v1.UpdateCredentialsParams['fieldsAttributes']>
|
||||
}>({ required: true })
|
||||
const dropdown = $ref<any>()
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ async function deleteStatus() {
|
|||
return
|
||||
|
||||
removeCachedStatus(status.id)
|
||||
await client.v1.statuses.remove(status.id)
|
||||
await client.v1.statuses.$select(status.id).remove()
|
||||
|
||||
if (route.name === 'status')
|
||||
router.back()
|
||||
|
@ -96,7 +96,7 @@ async function deleteAndRedraft() {
|
|||
}
|
||||
|
||||
removeCachedStatus(status.id)
|
||||
await client.v1.statuses.remove(status.id)
|
||||
await client.v1.statuses.$select(status.id).remove()
|
||||
await openPublishDialog('dialog', await getDraftFromStatus(status), true)
|
||||
|
||||
// Go to the new status, if the page is the old status
|
||||
|
|
|
@ -6,7 +6,7 @@ const type = ref<'favourited-by' | 'boosted-by'>('favourited-by')
|
|||
const { client } = $(useMasto())
|
||||
|
||||
function load() {
|
||||
return client.v1.statuses[type.value === 'favourited-by' ? 'listFavouritedBy' : 'listRebloggedBy'](favouritedBoostedByStatusId.value!)
|
||||
return client.v1.statuses.$select(favouritedBoostedByStatusId.value!)[type.value === 'favourited-by' ? 'favouritedBy' : 'rebloggedBy'].list()
|
||||
}
|
||||
|
||||
const paginator = $computed(() => load())
|
||||
|
|
|
@ -36,7 +36,7 @@ async function vote(e: Event) {
|
|||
|
||||
cacheStatus({ ...status, poll }, undefined, true)
|
||||
|
||||
await client.v1.polls.vote(poll.id, { choices })
|
||||
await client.v1.polls.$select(poll.id).votes.create({ choices })
|
||||
}
|
||||
|
||||
const votersCount = $computed(() => poll.votersCount ?? poll.votesCount ?? 0)
|
||||
|
|
|
@ -6,7 +6,7 @@ const { status } = defineProps<{
|
|||
status: mastodon.v1.Status
|
||||
}>()
|
||||
|
||||
const paginator = useMastoClient().v1.statuses.listHistory(status.id)
|
||||
const paginator = useMastoClient().v1.statuses.$select(status.id).history.list()
|
||||
|
||||
function showHistory(edit: mastodon.v1.StatusEdit) {
|
||||
openEditHistoryDialog(edit)
|
||||
|
|
|
@ -20,9 +20,9 @@ async function toggleFollowTag() {
|
|||
|
||||
try {
|
||||
if (previousFollowingState)
|
||||
await client.v1.tags.unfollow(tag.name)
|
||||
await client.v1.tags.$select(tag.name).unfollow()
|
||||
else
|
||||
await client.v1.tags.follow(tag.name)
|
||||
await client.v1.tags.$select(tag.name).follow()
|
||||
|
||||
emit('change')
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<script setup lang="ts">
|
||||
import type { Paginator, mastodon } from 'masto'
|
||||
import type { mastodon } from 'masto'
|
||||
|
||||
const { paginator } = defineProps<{
|
||||
paginator: Paginator<mastodon.v1.Tag[], mastodon.DefaultPaginationParams>
|
||||
paginator: mastodon.Paginator<mastodon.v1.Tag[], mastodon.DefaultPaginationParams>
|
||||
}>()
|
||||
</script>
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ const { client } = $(useMasto())
|
|||
const paginator = client.v1.domainBlocks.list()
|
||||
|
||||
async function unblock(domain: string) {
|
||||
await client.v1.domainBlocks.unblock(domain)
|
||||
await client.v1.domainBlocks.remove({ domain })
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<script setup lang="ts">
|
||||
import type { mastodon } from 'masto'
|
||||
|
||||
const paginator = useMastoClient().v1.timelines.listHome({ limit: 30 })
|
||||
const stream = $(useStreaming(client => client.v1.stream.streamUser()))
|
||||
const paginator = useMastoClient().v1.timelines.home.list({ limit: 30 })
|
||||
const stream = useStreaming(client => client.user.subscribe())
|
||||
function reorderAndFilter(items: mastodon.v1.Status[]) {
|
||||
return reorderedTimeline(items, 'home')
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ const options = { limit: 30, types: filter ? [filter] : [] }
|
|||
|
||||
// Default limit is 20 notifications, and servers are normally caped to 30
|
||||
const paginator = useMastoClient().v1.notifications.list(options)
|
||||
const stream = useStreaming(client => client.v1.stream.streamUser())
|
||||
const stream = useStreaming(client => client.user.subscribe())
|
||||
|
||||
const { clearNotifications } = useNotifications()
|
||||
onActivated(clearNotifications)
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
// @ts-expect-error missing types
|
||||
import { DynamicScrollerItem } from 'vue-virtual-scroller'
|
||||
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
|
||||
import type { Paginator, WsEvents, mastodon } from 'masto'
|
||||
import type { mastodon } from 'masto'
|
||||
|
||||
const { paginator, stream, account, buffer = 10, endMessage = true } = defineProps<{
|
||||
paginator: Paginator<mastodon.v1.Status[], mastodon.v1.ListAccountStatusesParams>
|
||||
stream?: Promise<WsEvents>
|
||||
paginator: mastodon.Paginator<mastodon.v1.Status[], mastodon.rest.v1.ListAccountStatusesParams>
|
||||
stream?: mastodon.streaming.Subscription
|
||||
context?: mastodon.v2.FilterContext
|
||||
account?: mastodon.v1.Account
|
||||
preprocess?: (items: mastodon.v1.Status[]) => mastodon.v1.Status[]
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
const paginator = useMastoClient().v1.accounts.listStatuses(currentUser.value!.account.id, { pinned: true })
|
||||
const paginator = useMastoClient().v1.accounts.$select(currentUser.value!.account.id).statuses.list({ pinned: true })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<script setup lang="ts">
|
||||
import type { mastodon } from 'masto'
|
||||
|
||||
const paginator = useMastoClient().v1.timelines.listPublic({ limit: 30 })
|
||||
const stream = useStreaming(client => client.v1.stream.streamPublicTimeline())
|
||||
const paginator = useMastoClient().v1.timelines.public.list({ limit: 30 })
|
||||
const stream = useStreaming(client => client.public.subscribe())
|
||||
function reorderAndFilter(items: mastodon.v1.Status[]) {
|
||||
return reorderedTimeline(items, 'public')
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
const paginator = useMastoClient().v1.timelines.listPublic({ limit: 30, local: true })
|
||||
const stream = useStreaming(client => client.v1.stream.streamCommunityTimeline())
|
||||
const paginator = useMastoClient().v1.timelines.public.list({ limit: 30, local: true })
|
||||
const stream = useStreaming(client => client.direct.subscribe())
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
|
@ -24,7 +24,7 @@ export function fetchStatus(id: string, force = false): Promise<mastodon.v1.Stat
|
|||
const cached = cache.get(key)
|
||||
if (cached && !force)
|
||||
return cached
|
||||
const promise = useMastoClient().v1.statuses.fetch(id)
|
||||
const promise = useMastoClient().v1.statuses.$select(id).fetch()
|
||||
.then((status) => {
|
||||
cacheStatus(status)
|
||||
return status
|
||||
|
@ -44,7 +44,7 @@ export function fetchAccountById(id?: string | null): Promise<mastodon.v1.Accoun
|
|||
if (cached)
|
||||
return cached
|
||||
const domain = getInstanceDomainFromServer(server)
|
||||
const promise = useMastoClient().v1.accounts.fetch(id)
|
||||
const promise = useMastoClient().v1.accounts.$select(id).fetch()
|
||||
.then((r) => {
|
||||
if (r.acct && !r.acct.includes('@') && domain)
|
||||
r.acct = `${r.acct}@${domain}`
|
||||
|
@ -74,7 +74,7 @@ export async function fetchAccountByHandle(acct: string): Promise<mastodon.v1.Ac
|
|||
}
|
||||
else {
|
||||
const userAcctDomain = userAcct.includes('@') ? userAcct : `${userAcct}@${domain}`
|
||||
account = (await client.v1.search({ q: `@${userAcctDomain}`, type: 'accounts' })).accounts[0]
|
||||
account = (await client.v1.search.fetch({ q: `@${userAcctDomain}`, type: 'accounts' })).accounts[0]
|
||||
}
|
||||
|
||||
if (account.acct && !account.acct.includes('@') && domain)
|
||||
|
|
|
@ -1,27 +1,14 @@
|
|||
import type { Pausable } from '@vueuse/core'
|
||||
import type { CreateClientParams, WsEvents, mastodon } from 'masto'
|
||||
import { createClient, fetchV1Instance } from 'masto'
|
||||
import type { mastodon } from 'masto'
|
||||
import { createRestAPIClient, createStreamingAPIClient } from 'masto'
|
||||
import type { Ref } from 'vue'
|
||||
import type { ElkInstance } from '../users'
|
||||
import type { Mutable } from '~/types/utils'
|
||||
import type { UserLogin } from '~/types'
|
||||
|
||||
export function createMasto() {
|
||||
let client = $shallowRef<mastodon.Client>(undefined as never)
|
||||
let params = $ref<Mutable<CreateClientParams>>()
|
||||
const canStreaming = $computed(() => !!params?.streamingApiUrl)
|
||||
|
||||
const setParams = (newParams: Partial<CreateClientParams>) => {
|
||||
const p = { ...params, ...newParams } as CreateClientParams
|
||||
client = createClient(p)
|
||||
params = p
|
||||
}
|
||||
|
||||
return {
|
||||
client: $$(client),
|
||||
params: readonly($$(params)),
|
||||
canStreaming: $$(canStreaming),
|
||||
setParams,
|
||||
client: shallowRef<mastodon.rest.Client>(undefined as never),
|
||||
streamingClient: shallowRef<mastodon.streaming.Client | undefined>(),
|
||||
}
|
||||
}
|
||||
export type ElkMasto = ReturnType<typeof createMasto>
|
||||
|
@ -34,23 +21,25 @@ export function useMastoClient() {
|
|||
}
|
||||
|
||||
export function mastoLogin(masto: ElkMasto, user: Pick<UserLogin, 'server' | 'token'>) {
|
||||
const { setParams } = $(masto)
|
||||
|
||||
const server = user.server
|
||||
const url = `https://${server}`
|
||||
const instance: ElkInstance = reactive(getInstanceCache(server) || { uri: server, accountDomain: server })
|
||||
setParams({
|
||||
url,
|
||||
accessToken: user?.token,
|
||||
disableVersionCheck: true,
|
||||
streamingApiUrl: instance?.urls?.streamingApi,
|
||||
})
|
||||
const accessToken = user.token
|
||||
|
||||
fetchV1Instance({ url }).then((newInstance) => {
|
||||
const createStreamingClient = (streamingApiUrl: string | undefined) => {
|
||||
return streamingApiUrl ? createStreamingAPIClient({ streamingApiUrl, accessToken, implementation: globalThis.WebSocket }) : undefined
|
||||
}
|
||||
|
||||
const streamingApiUrl = instance?.urls?.streamingApi
|
||||
masto.client.value = createRestAPIClient({ url, accessToken })
|
||||
masto.streamingClient.value = createStreamingClient(streamingApiUrl)
|
||||
|
||||
// Refetch instance info in the background on login
|
||||
masto.client.value.v1.instance.fetch().then((newInstance) => {
|
||||
Object.assign(instance, newInstance)
|
||||
setParams({
|
||||
streamingApiUrl: newInstance.urls.streamingApi,
|
||||
})
|
||||
if (newInstance.urls.streamingApi !== streamingApiUrl)
|
||||
masto.streamingClient.value = createStreamingClient(newInstance.urls.streamingApi)
|
||||
|
||||
instanceStorage.value[server] = newInstance
|
||||
})
|
||||
|
||||
|
@ -73,21 +62,21 @@ interface UseStreamingOptions<Controls extends boolean> {
|
|||
}
|
||||
|
||||
export function useStreaming(
|
||||
cb: (client: mastodon.Client) => Promise<WsEvents>,
|
||||
cb: (client: mastodon.streaming.Client) => mastodon.streaming.Subscription,
|
||||
options: UseStreamingOptions<true>,
|
||||
): { stream: Ref<Promise<WsEvents> | undefined> } & Pausable
|
||||
): { stream: Ref<mastodon.streaming.Subscription | undefined> } & Pausable
|
||||
export function useStreaming(
|
||||
cb: (client: mastodon.Client) => Promise<WsEvents>,
|
||||
cb: (client: mastodon.streaming.Client) => mastodon.streaming.Subscription,
|
||||
options?: UseStreamingOptions<false>,
|
||||
): Ref<Promise<WsEvents> | undefined>
|
||||
): Ref<mastodon.streaming.Subscription | undefined>
|
||||
export function useStreaming(
|
||||
cb: (client: mastodon.Client) => Promise<WsEvents>,
|
||||
cb: (client: mastodon.streaming.Client) => mastodon.streaming.Subscription,
|
||||
{ immediate = true, controls }: UseStreamingOptions<boolean> = {},
|
||||
): ({ stream: Ref<Promise<WsEvents> | undefined> } & Pausable) | Ref<Promise<WsEvents> | undefined> {
|
||||
const { canStreaming, client } = useMasto()
|
||||
): ({ stream: Ref<mastodon.streaming.Subscription | undefined> } & Pausable) | Ref<mastodon.streaming.Subscription | undefined> {
|
||||
const { streamingClient } = useMasto()
|
||||
|
||||
const isActive = ref(immediate)
|
||||
const stream = ref<Promise<WsEvents>>()
|
||||
const stream = ref<mastodon.streaming.Subscription>()
|
||||
|
||||
function pause() {
|
||||
isActive.value = false
|
||||
|
@ -99,15 +88,15 @@ export function useStreaming(
|
|||
|
||||
function cleanup() {
|
||||
if (stream.value) {
|
||||
stream.value.then(s => s.disconnect()).catch(() => Promise.resolve())
|
||||
stream.value.unsubscribe()
|
||||
stream.value = undefined
|
||||
}
|
||||
}
|
||||
|
||||
watchEffect(() => {
|
||||
cleanup()
|
||||
if (canStreaming.value && isActive.value)
|
||||
stream.value = cb(client.value)
|
||||
if (streamingClient.value && isActive.value)
|
||||
stream.value = cb(streamingClient.value)
|
||||
})
|
||||
|
||||
if (process.client && !process.test)
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import type { WsEvents } from 'masto'
|
||||
import type { mastodon } from 'masto'
|
||||
|
||||
const notifications = reactive<Record<string, undefined | [Promise<WsEvents>, string[]]>>({})
|
||||
const notifications = reactive<Record<string, undefined | [Promise<mastodon.streaming.Subscription>, string[]]>>({})
|
||||
|
||||
export function useNotifications() {
|
||||
const id = currentUser.value?.account.id
|
||||
|
||||
const { client, canStreaming } = $(useMasto())
|
||||
const { client, streamingClient } = $(useMasto())
|
||||
|
||||
async function clearNotifications() {
|
||||
if (!id || !notifications[id])
|
||||
|
@ -19,21 +19,27 @@ export function useNotifications() {
|
|||
}
|
||||
}
|
||||
|
||||
async function processNotifications(stream: mastodon.streaming.Subscription, id: string) {
|
||||
for await (const entry of stream) {
|
||||
if (entry.event === 'notification' && notifications[id])
|
||||
notifications[id]![1].unshift(entry.payload.id)
|
||||
}
|
||||
}
|
||||
|
||||
async function connect(): Promise<void> {
|
||||
if (!isHydrated.value || !id || notifications[id] || !currentUser.value?.token)
|
||||
if (!isHydrated.value || !id || notifications[id] !== undefined || !currentUser.value?.token)
|
||||
return
|
||||
|
||||
let resolveStream
|
||||
const stream = new Promise<WsEvents>(resolve => resolveStream = resolve)
|
||||
notifications[id] = [stream, []]
|
||||
const streamPromise = new Promise<mastodon.streaming.Subscription>(resolve => resolveStream = resolve)
|
||||
notifications[id] = [streamPromise, []]
|
||||
|
||||
await until($$(canStreaming)).toBe(true)
|
||||
await until($$(streamingClient)).toBe(true)
|
||||
|
||||
client.v1.stream.streamUser().then(resolveStream)
|
||||
stream.then(s => s.on('notification', (n) => {
|
||||
if (notifications[id])
|
||||
notifications[id]![1].unshift(n.id)
|
||||
}))
|
||||
const stream = streamingClient!.user.subscribe()
|
||||
resolveStream!(stream)
|
||||
|
||||
processNotifications(stream, id)
|
||||
|
||||
const position = await client.v1.markers.fetch({ timeline: ['notifications'] })
|
||||
const paginator = client.v1.notifications.list({ limit: 30 })
|
||||
|
@ -55,7 +61,7 @@ export function useNotifications() {
|
|||
function disconnect(): void {
|
||||
if (!id || !notifications[id])
|
||||
return
|
||||
notifications[id]![0].then(stream => stream.disconnect())
|
||||
notifications[id]![0].then(stream => stream.unsubscribe())
|
||||
notifications[id] = undefined
|
||||
}
|
||||
|
||||
|
@ -67,7 +73,6 @@ export function useNotifications() {
|
|||
|
||||
return {
|
||||
notifications: computed(() => id ? notifications[id]?.[1].length ?? 0 : 0),
|
||||
disconnect,
|
||||
clearNotifications,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -93,7 +93,7 @@ export function usePublish(options: {
|
|||
language: draft.params.language || preferredLanguage,
|
||||
poll,
|
||||
...(isGlitchEdition.value ? { 'content-type': 'text/markdown' } : {}),
|
||||
} as mastodon.v1.CreateStatusParams
|
||||
} as mastodon.rest.v1.CreateStatusParams
|
||||
|
||||
if (process.dev) {
|
||||
// eslint-disable-next-line no-console
|
||||
|
@ -116,14 +116,13 @@ export function usePublish(options: {
|
|||
}
|
||||
|
||||
else {
|
||||
const updatePayload = {
|
||||
status = await client.v1.statuses.$select(draft.editingStatus.id).update({
|
||||
...payload,
|
||||
mediaAttributes: draft.attachments.map(media => ({
|
||||
id: media.id,
|
||||
description: media.description,
|
||||
})),
|
||||
} as mastodon.v1.UpdateStatusParams
|
||||
status = await client.v1.statuses.update(draft.editingStatus.id, updatePayload)
|
||||
})
|
||||
}
|
||||
if (draft.params.inReplyToId)
|
||||
navigateToStatus({ status })
|
||||
|
@ -232,7 +231,7 @@ export function useUploadMediaAttachment(draftRef: Ref<Draft>) {
|
|||
if (draft.attachments.length < limit) {
|
||||
isExceedingAttachmentLimit = false
|
||||
try {
|
||||
const attachment = await client.v1.mediaAttachments.create({
|
||||
const attachment = await client.v1.media.create({
|
||||
file: await processFile(file),
|
||||
})
|
||||
draft.attachments.push(attachment)
|
||||
|
@ -266,7 +265,7 @@ export function useUploadMediaAttachment(draftRef: Ref<Draft>) {
|
|||
async function setDescription(att: mastodon.v1.MediaAttachment, description: string) {
|
||||
att.description = description
|
||||
if (!draft.editingStatus)
|
||||
await client.v1.mediaAttachments.update(att.id, { description: att.description })
|
||||
await client.v1.media.$select(att.id).update({ description: att.description })
|
||||
}
|
||||
|
||||
function removeAttachment(index: number) {
|
||||
|
|
|
@ -27,7 +27,7 @@ export function useRelationship(account: mastodon.v1.Account): Ref<mastodon.v1.R
|
|||
|
||||
async function fetchRelationships() {
|
||||
const requested = Array.from(requestedRelationships.entries()).filter(([, r]) => !r.value)
|
||||
const relationships = await useMastoClient().v1.accounts.fetchRelationships(requested.map(([id]) => id))
|
||||
const relationships = await useMastoClient().v1.accounts.relationships.fetch({ id: requested.map(([id]) => id) })
|
||||
for (let i = 0; i < requested.length; i++)
|
||||
requested[i][1].value = relationships[i]
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ export async function toggleFollowAccount(relationship: mastodon.v1.Relationship
|
|||
relationship!.following = true
|
||||
}
|
||||
|
||||
relationship = await client.v1.accounts[unfollow ? 'unfollow' : 'follow'](account.id)
|
||||
relationship = await client.v1.accounts.$select(account.id)[unfollow ? 'unfollow' : 'follow']()
|
||||
}
|
||||
|
||||
export async function toggleMuteAccount(relationship: mastodon.v1.Relationship, account: mastodon.v1.Account) {
|
||||
|
@ -74,10 +74,10 @@ export async function toggleMuteAccount(relationship: mastodon.v1.Relationship,
|
|||
|
||||
relationship!.muting = !relationship!.muting
|
||||
relationship = relationship!.muting
|
||||
? await client.v1.accounts.mute(account.id, {
|
||||
? await client.v1.accounts.$select(account.id).mute({
|
||||
// TODO support more options
|
||||
})
|
||||
: await client.v1.accounts.unmute(account.id)
|
||||
: await client.v1.accounts.$select(account.id).unmute()
|
||||
}
|
||||
|
||||
export async function toggleBlockAccount(relationship: mastodon.v1.Relationship, account: mastodon.v1.Account) {
|
||||
|
@ -92,7 +92,7 @@ export async function toggleBlockAccount(relationship: mastodon.v1.Relationship,
|
|||
return
|
||||
|
||||
relationship!.blocking = !relationship!.blocking
|
||||
relationship = await client.v1.accounts[relationship!.blocking ? 'block' : 'unblock'](account.id)
|
||||
relationship = await client.v1.accounts.$select(account.id)[relationship!.blocking ? 'block' : 'unblock']()
|
||||
}
|
||||
|
||||
export async function toggleBlockDomain(relationship: mastodon.v1.Relationship, account: mastodon.v1.Account) {
|
||||
|
@ -107,5 +107,5 @@ export async function toggleBlockDomain(relationship: mastodon.v1.Relationship,
|
|||
return
|
||||
|
||||
relationship!.domainBlocking = !relationship!.domainBlocking
|
||||
await client.v1.domainBlocks[relationship!.domainBlocking ? 'block' : 'unblock'](getServerName(account))
|
||||
await client.v1.domainBlocks[relationship!.domainBlocking ? 'create' : 'remove']({ domain: getServerName(account) })
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import type { MaybeRefOrGetter } from '@vueuse/core'
|
||||
import type { Paginator, mastodon } from 'masto'
|
||||
import type { mastodon } from 'masto'
|
||||
import type { RouteLocation } from 'vue-router'
|
||||
|
||||
export type UseSearchOptions = MaybeRefOrGetter<
|
||||
Partial<Omit<mastodon.v1.SearchParams, keyof mastodon.DefaultPaginationParams | 'q'>>
|
||||
Partial<Omit<mastodon.rest.v2.SearchParams, keyof mastodon.DefaultPaginationParams | 'q'>>
|
||||
>
|
||||
|
||||
export interface BuildSearchResult<K extends keyof any, T> {
|
||||
|
@ -30,7 +30,7 @@ export function useSearch(query: MaybeRefOrGetter<string>, options: UseSearchOpt
|
|||
|
||||
const q = $computed(() => resolveUnref(query).trim())
|
||||
|
||||
let paginator: Paginator<mastodon.v2.Search, mastodon.v2.SearchParams> | undefined
|
||||
let paginator: mastodon.Paginator<mastodon.v2.Search, mastodon.rest.v2.SearchParams> | undefined
|
||||
|
||||
const appendResults = (results: mastodon.v2.Search, empty = false) => {
|
||||
if (empty) {
|
||||
|
@ -72,7 +72,7 @@ export function useSearch(query: MaybeRefOrGetter<string>, options: UseSearchOpt
|
|||
* Based on the source it seems like modifying the params when calling next would result in a new search,
|
||||
* but that doesn't seem to be the case. So instead we just create a new paginator with the new params.
|
||||
*/
|
||||
paginator = client.v2.search({
|
||||
paginator = client.v2.search.list({
|
||||
q,
|
||||
...resolveUnref(options),
|
||||
resolve: !!currentUser.value,
|
||||
|
|
|
@ -61,7 +61,7 @@ export function useStatusActions(props: StatusActionsProps) {
|
|||
|
||||
const toggleReblog = () => toggleStatusAction(
|
||||
'reblogged',
|
||||
() => client.v1.statuses[status.reblogged ? 'unreblog' : 'reblog'](status.id).then((res) => {
|
||||
() => client.v1.statuses.$select(status.id)[status.reblogged ? 'unreblog' : 'reblog']().then((res) => {
|
||||
if (status.reblogged)
|
||||
// returns the original status
|
||||
return res.reblog!
|
||||
|
@ -72,23 +72,23 @@ export function useStatusActions(props: StatusActionsProps) {
|
|||
|
||||
const toggleFavourite = () => toggleStatusAction(
|
||||
'favourited',
|
||||
() => client.v1.statuses[status.favourited ? 'unfavourite' : 'favourite'](status.id),
|
||||
() => client.v1.statuses.$select(status.id)[status.favourited ? 'unfavourite' : 'favourite'](),
|
||||
'favouritesCount',
|
||||
)
|
||||
|
||||
const toggleBookmark = () => toggleStatusAction(
|
||||
'bookmarked',
|
||||
() => client.v1.statuses[status.bookmarked ? 'unbookmark' : 'bookmark'](status.id),
|
||||
() => client.v1.statuses.$select(status.id)[status.bookmarked ? 'unbookmark' : 'bookmark'](),
|
||||
)
|
||||
|
||||
const togglePin = async () => toggleStatusAction(
|
||||
'pinned',
|
||||
() => client.v1.statuses[status.pinned ? 'unpin' : 'pin'](status.id),
|
||||
() => client.v1.statuses.$select(status.id)[status.pinned ? 'unpin' : 'pin'](),
|
||||
)
|
||||
|
||||
const toggleMute = async () => toggleStatusAction(
|
||||
'muted',
|
||||
() => client.v1.statuses[status.muted ? 'unmute' : 'mute'](status.id),
|
||||
() => client.v1.statuses.$select(status.id)[status.muted ? 'unmute' : 'mute'](),
|
||||
)
|
||||
|
||||
return {
|
||||
|
|
|
@ -25,7 +25,7 @@ function getDefaultVisibility(currentVisibility: mastodon.v1.StatusVisibility) {
|
|||
: preferredVisibility
|
||||
}
|
||||
|
||||
export function getDefaultDraft(options: Partial<Mutable<mastodon.v1.CreateStatusParams> & Omit<Draft, 'params'>> = {}): Draft {
|
||||
export function getDefaultDraft(options: Partial<Mutable<mastodon.rest.v1.CreateStatusParams> & Omit<Draft, 'params'>> = {}): Draft {
|
||||
const {
|
||||
attachments = [],
|
||||
initialText = '',
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import type { Paginator, WsEvents, mastodon } from 'masto'
|
||||
import type { mastodon } from 'masto'
|
||||
import type { Ref } from 'vue'
|
||||
import type { PaginatorState } from '~/types'
|
||||
|
||||
export function usePaginator<T, P, U = T>(
|
||||
_paginator: Paginator<T[], P>,
|
||||
stream: Ref<Promise<WsEvents> | undefined>,
|
||||
_paginator: mastodon.Paginator<T[], P>,
|
||||
stream: Ref<mastodon.streaming.Subscription | undefined>,
|
||||
eventType: 'notification' | 'update' = 'update',
|
||||
preprocess: (items: (T | U)[]) => U[] = items => items as unknown as U[],
|
||||
buffer = 10,
|
||||
|
@ -30,10 +30,15 @@ export function usePaginator<T, P, U = T>(
|
|||
prevItems.value = []
|
||||
}
|
||||
|
||||
watch(stream, (stream) => {
|
||||
stream?.then((s) => {
|
||||
s.on(eventType, (status) => {
|
||||
if ('uri' in status)
|
||||
watch(stream, async (stream) => {
|
||||
if (!stream)
|
||||
return
|
||||
|
||||
for await (const entry of stream) {
|
||||
if (entry.event === 'update') {
|
||||
const status = entry.payload
|
||||
|
||||
if ('uri' in entry)
|
||||
cacheStatus(status, undefined, true)
|
||||
|
||||
const index = prevItems.value.findIndex((i: any) => i.id === status.id)
|
||||
|
@ -41,27 +46,27 @@ export function usePaginator<T, P, U = T>(
|
|||
prevItems.value.splice(index, 1)
|
||||
|
||||
prevItems.value.unshift(status as any)
|
||||
})
|
||||
|
||||
// TODO: update statuses
|
||||
s.on('status.update', (status) => {
|
||||
}
|
||||
else if (entry.event === 'status.update') {
|
||||
const status = entry.payload
|
||||
cacheStatus(status, undefined, true)
|
||||
|
||||
const data = items.value as mastodon.v1.Status[]
|
||||
const index = data.findIndex(s => s.id === status.id)
|
||||
if (index >= 0)
|
||||
data[index] = status
|
||||
})
|
||||
}
|
||||
|
||||
s.on('delete', (id) => {
|
||||
else if (entry.event === 'delete') {
|
||||
const id = entry.payload
|
||||
removeCachedStatus(id)
|
||||
|
||||
const data = items.value as mastodon.v1.Status[]
|
||||
const index = data.findIndex(s => s.id === id)
|
||||
if (index >= 0)
|
||||
data.splice(index, 1)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}, { immediate: true })
|
||||
|
||||
async function loadNext() {
|
||||
|
|
|
@ -8,7 +8,7 @@ import { PushSubscriptionError } from '~/composables/push-notifications/types'
|
|||
|
||||
export async function createPushSubscription(user: RequiredUserLogin,
|
||||
notificationData: CreatePushNotification,
|
||||
policy: mastodon.v1.SubscriptionPolicy = 'all',
|
||||
policy: mastodon.v1.WebPushSubscriptionPolicy = 'all',
|
||||
force = false): Promise<mastodon.v1.WebPushSubscription | undefined> {
|
||||
const { server: serverEndpoint, vapidKey } = user
|
||||
|
||||
|
@ -115,10 +115,10 @@ async function removePushNotificationDataOnError(e: Error) {
|
|||
async function sendSubscriptionToBackend(
|
||||
subscription: PushSubscription,
|
||||
data: CreatePushNotification,
|
||||
policy: mastodon.v1.SubscriptionPolicy,
|
||||
policy: mastodon.v1.WebPushSubscriptionPolicy,
|
||||
): Promise<mastodon.v1.WebPushSubscription> {
|
||||
const { endpoint, keys } = subscription.toJSON()
|
||||
const params: mastodon.v1.CreateWebPushSubscriptionParams = {
|
||||
return await useMastoClient().v1.push.subscription.create({
|
||||
policy,
|
||||
subscription: {
|
||||
endpoint: endpoint!,
|
||||
|
@ -128,7 +128,5 @@ async function sendSubscriptionToBackend(
|
|||
},
|
||||
},
|
||||
data,
|
||||
}
|
||||
|
||||
return await useMastoClient().v1.webPushSubscriptions.create(params)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -14,11 +14,11 @@ export interface RequiredUserLogin extends Required<Omit<UserLogin, 'account' |
|
|||
|
||||
export interface CreatePushNotification {
|
||||
alerts?: Partial<mastodon.v1.WebPushSubscriptionAlerts> | null
|
||||
policy?: mastodon.v1.SubscriptionPolicy
|
||||
policy?: mastodon.v1.WebPushSubscriptionPolicy
|
||||
}
|
||||
|
||||
export type PushNotificationRequest = Record<string, boolean>
|
||||
export type PushNotificationPolicy = Record<string, mastodon.v1.SubscriptionPolicy>
|
||||
export type PushNotificationPolicy = Record<string, mastodon.v1.WebPushSubscriptionPolicy>
|
||||
|
||||
export interface CustomEmojisInfo {
|
||||
lastUpdate: number
|
||||
|
|
|
@ -61,7 +61,7 @@ export function usePushManager() {
|
|||
|
||||
const subscribe = async (
|
||||
notificationData?: CreatePushNotification,
|
||||
policy?: mastodon.v1.SubscriptionPolicy,
|
||||
policy?: mastodon.v1.WebPushSubscriptionPolicy,
|
||||
force?: boolean,
|
||||
): Promise<SubscriptionResult> => {
|
||||
if (!isSupported)
|
||||
|
@ -116,7 +116,7 @@ export function usePushManager() {
|
|||
await removePushNotificationData(currentUser.value)
|
||||
}
|
||||
|
||||
const saveSettings = async (policy?: mastodon.v1.SubscriptionPolicy) => {
|
||||
const saveSettings = async (policy?: mastodon.v1.WebPushSubscriptionPolicy) => {
|
||||
if (policy)
|
||||
pushNotificationData.value.policy = policy
|
||||
|
||||
|
@ -173,7 +173,7 @@ export function usePushManager() {
|
|||
if (policyChanged)
|
||||
await subscribe(data, policy, true)
|
||||
else
|
||||
currentUser.value.pushSubscription = await client.v1.webPushSubscriptions.update({ data })
|
||||
currentUser.value.pushSubscription = await client.v1.push.subscription.update({ data })
|
||||
|
||||
policyChanged && await nextTick()
|
||||
|
||||
|
@ -198,7 +198,7 @@ export function usePushManager() {
|
|||
|
||||
function createRawSettings(
|
||||
pushSubscription?: mastodon.v1.WebPushSubscription,
|
||||
subscriptionPolicy?: mastodon.v1.SubscriptionPolicy,
|
||||
subscriptionPolicy?: mastodon.v1.WebPushSubscriptionPolicy,
|
||||
) {
|
||||
return {
|
||||
follow: pushSubscription?.alerts.follow ?? true,
|
||||
|
|
|
@ -27,8 +27,8 @@ export const TiptapMentionSuggestion: Partial<SuggestionOptions> = process.serve
|
|||
if (query.length === 0)
|
||||
return []
|
||||
|
||||
const results = await useMastoClient().v2.search({ q: query, type: 'accounts', limit: 25, resolve: true })
|
||||
return results.accounts
|
||||
const paginator = useMastoClient().v2.search.list({ q: query, type: 'accounts', limit: 25, resolve: true })
|
||||
return (await paginator.next()).value?.accounts ?? []
|
||||
},
|
||||
render: createSuggestionRenderer(TiptapMentionList),
|
||||
}
|
||||
|
@ -40,14 +40,14 @@ export const TiptapHashtagSuggestion: Partial<SuggestionOptions> = {
|
|||
if (query.length === 0)
|
||||
return []
|
||||
|
||||
const results = await useMastoClient().v2.search({
|
||||
const paginator = useMastoClient().v2.search.list({
|
||||
q: query,
|
||||
type: 'hashtags',
|
||||
limit: 25,
|
||||
resolve: false,
|
||||
excludeUnreviewed: true,
|
||||
})
|
||||
return results.hashtags
|
||||
return (await paginator.next()).value?.hashtags ?? []
|
||||
},
|
||||
render: createSuggestionRenderer(TiptapHashtagList),
|
||||
}
|
||||
|
|
|
@ -149,7 +149,7 @@ export async function loginTo(masto: ElkMasto, user: Overwrite<UserLogin, { acco
|
|||
// if PWA is not enabled, don't get push subscription
|
||||
useAppConfig().pwaEnabled
|
||||
// we get 404 response instead empty data
|
||||
? client.v1.webPushSubscriptions.fetch().catch(() => Promise.resolve(undefined))
|
||||
? client.v1.push.subscription.fetch().catch(() => Promise.resolve(undefined))
|
||||
: Promise.resolve(undefined),
|
||||
])
|
||||
|
||||
|
@ -172,6 +172,7 @@ export async function loginTo(masto: ElkMasto, user: Overwrite<UserLogin, { acco
|
|||
const accountPreferencesMap = new Map<string, Partial<mastodon.v1.Preference>>()
|
||||
|
||||
/**
|
||||
* @param account
|
||||
* @returns `true` when user ticked the preference to always expand posts with content warnings
|
||||
*/
|
||||
export function getExpandSpoilersByDefault(account: mastodon.v1.AccountCredentials) {
|
||||
|
@ -179,6 +180,7 @@ export function getExpandSpoilersByDefault(account: mastodon.v1.AccountCredentia
|
|||
}
|
||||
|
||||
/**
|
||||
* @param account
|
||||
* @returns `true` when user selected "Always show media" as Media Display preference
|
||||
*/
|
||||
export function getExpandMediaByDefault(account: mastodon.v1.AccountCredentials) {
|
||||
|
@ -186,13 +188,14 @@ export function getExpandMediaByDefault(account: mastodon.v1.AccountCredentials)
|
|||
}
|
||||
|
||||
/**
|
||||
* @param account
|
||||
* @returns `true` when user selected "Always hide media" as Media Display preference
|
||||
*/
|
||||
export function getHideMediaByDefault(account: mastodon.v1.AccountCredentials) {
|
||||
return accountPreferencesMap.get(account.acct)?.['reading:expand:media'] === 'hide_all' ?? false
|
||||
}
|
||||
|
||||
export async function fetchAccountInfo(client: mastodon.Client, server: string) {
|
||||
export async function fetchAccountInfo(client: mastodon.rest.Client, server: string) {
|
||||
// Try to fetch user preferences if the backend supports it.
|
||||
const fetchPrefs = async (): Promise<Partial<mastodon.v1.Preference>> => {
|
||||
try {
|
||||
|
@ -267,7 +270,7 @@ export async function removePushNotifications(user: UserLogin) {
|
|||
return
|
||||
|
||||
// unsubscribe push notifications
|
||||
await useMastoClient().v1.webPushSubscriptions.remove().catch(() => Promise.resolve())
|
||||
await useMastoClient().v1.push.subscription.remove().catch(() => Promise.resolve())
|
||||
}
|
||||
|
||||
export async function switchUser(user: UserLogin) {
|
||||
|
@ -336,6 +339,8 @@ interface UseUserLocalStorageCache {
|
|||
|
||||
/**
|
||||
* Create reactive storage for the current user
|
||||
* @param key
|
||||
* @param initial
|
||||
*/
|
||||
export function useUserLocalStorage<T extends object>(key: string, initial: () => T): Ref<T> {
|
||||
if (process.server || process.test)
|
||||
|
@ -382,6 +387,7 @@ export function useUserLocalStorage<T extends object>(key: string, initial: () =
|
|||
|
||||
/**
|
||||
* Clear all storages for the given account
|
||||
* @param account
|
||||
*/
|
||||
export function clearUserLocalStorage(account?: mastodon.v1.Account) {
|
||||
if (!account)
|
||||
|
|
|
@ -43,7 +43,9 @@ export default defineNuxtRouteMiddleware(async (to, from) => {
|
|||
}
|
||||
|
||||
// If we're logged in, search for the local id the account or status corresponds to
|
||||
const { accounts, statuses } = await masto.client.value.v2.search({ q: `https:/${to.fullPath}`, resolve: true, limit: 1 })
|
||||
const paginator = masto.client.value.v2.search.list({ q: `https:/${to.fullPath}`, resolve: true, limit: 1 })
|
||||
const { accounts, statuses } = (await paginator.next()).value ?? { accounts: [], statuses: [] }
|
||||
|
||||
if (statuses[0])
|
||||
return getStatusRoute(statuses[0])
|
||||
|
||||
|
|
|
@ -82,7 +82,7 @@
|
|||
"iso-639-1": "^3.0.0",
|
||||
"js-yaml": "^4.1.0",
|
||||
"lru-cache": "^10.0.0",
|
||||
"masto": "^5.11.3",
|
||||
"masto": "^6.5.2",
|
||||
"node-emoji": "^2.1.3",
|
||||
"nuxt-security": "^0.13.1",
|
||||
"page-lifecycle": "^0.1.2",
|
||||
|
@ -108,7 +108,8 @@
|
|||
"vue-advanced-cropper": "^2.8.8",
|
||||
"vue-virtual-scroller": "2.0.0-beta.8",
|
||||
"workbox-build": "^7.0.0",
|
||||
"workbox-window": "^7.0.0"
|
||||
"workbox-window": "^7.0.0",
|
||||
"ws": "^8.15.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@antfu/eslint-config": "^0.41.3",
|
||||
|
@ -121,6 +122,7 @@
|
|||
"@types/js-yaml": "^4.0.5",
|
||||
"@types/prettier": "^2.7.3",
|
||||
"@types/wicg-file-system-access": "^2020.9.6",
|
||||
"@types/ws": "^8.5.10",
|
||||
"@unlazy/nuxt": "^0.9.3",
|
||||
"@vue/test-utils": "^2.4.3",
|
||||
"bumpp": "^9.2.0",
|
||||
|
|
|
@ -22,7 +22,7 @@ const { data: status, pending, refresh: refreshStatus } = useAsyncData(
|
|||
const { client } = $(useMasto())
|
||||
const { data: context, pending: pendingContext, refresh: refreshContext } = useAsyncData(
|
||||
`context:${id}`,
|
||||
async () => client.v1.statuses.fetchContext(id),
|
||||
async () => client.v1.statuses.$select(id).context.fetch(),
|
||||
{ watch: [isHydrated], immediate: isHydrated.value, lazy: true, default: () => shallowRef() },
|
||||
)
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ const handle = $(computedEager(() => params.account as string))
|
|||
definePageMeta({ name: 'account-followers' })
|
||||
|
||||
const account = await fetchAccountByHandle(handle)
|
||||
const paginator = account ? useMastoClient().v1.accounts.listFollowers(account.id, {}) : null
|
||||
const paginator = account ? useMastoClient().v1.accounts.$select(account.id).followers.list() : null
|
||||
|
||||
const isSelf = useSelfAccount(account)
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ const handle = $(computedEager(() => params.account as string))
|
|||
definePageMeta({ name: 'account-following' })
|
||||
|
||||
const account = await fetchAccountByHandle(handle)
|
||||
const paginator = account ? useMastoClient().v1.accounts.listFollowing(account.id, {}) : null
|
||||
const paginator = account ? useMastoClient().v1.accounts.$select(account.id).following.list() : null
|
||||
|
||||
const isSelf = useSelfAccount(account)
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ function reorderAndFilter(items: mastodon.v1.Status[]) {
|
|||
return reorderedTimeline(items, 'account')
|
||||
}
|
||||
|
||||
const paginator = useMastoClient().v1.accounts.listStatuses(account.id, { limit: 30, excludeReplies: true })
|
||||
const paginator = useMastoClient().v1.accounts.$select(account.id).statuses.list({ limit: 30, excludeReplies: true })
|
||||
|
||||
if (account) {
|
||||
useHydratedHead({
|
||||
|
|
|
@ -7,7 +7,7 @@ const handle = $(computedEager(() => params.account as string))
|
|||
|
||||
const account = await fetchAccountByHandle(handle)
|
||||
|
||||
const paginator = useMastoClient().v1.accounts.listStatuses(account.id, { onlyMedia: true, excludeReplies: false })
|
||||
const paginator = useMastoClient().v1.accounts.$select(account.id).statuses.list({ onlyMedia: true, excludeReplies: false })
|
||||
|
||||
if (account) {
|
||||
useHydratedHead({
|
||||
|
|
|
@ -7,7 +7,7 @@ const handle = $(computedEager(() => params.account as string))
|
|||
|
||||
const account = await fetchAccountByHandle(handle)
|
||||
|
||||
const paginator = useMastoClient().v1.accounts.listStatuses(account.id, { excludeReplies: false })
|
||||
const paginator = useMastoClient().v1.accounts.$select(account.id).statuses.list({ excludeReplies: false })
|
||||
|
||||
if (account) {
|
||||
useHydratedHead({
|
||||
|
|
|
@ -3,7 +3,7 @@ import { STORAGE_KEY_HIDE_EXPLORE_POSTS_TIPS } from '~~/constants'
|
|||
|
||||
const { t } = useI18n()
|
||||
|
||||
const paginator = useMastoClient().v1.trends.listStatuses()
|
||||
const paginator = useMastoClient().v1.trends.statuses.list()
|
||||
|
||||
const hideNewsTips = useLocalStorage(STORAGE_KEY_HIDE_EXPLORE_POSTS_TIPS, false)
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import { STORAGE_KEY_HIDE_EXPLORE_NEWS_TIPS } from '~~/constants'
|
|||
|
||||
const { t } = useI18n()
|
||||
|
||||
const paginator = useMastoClient().v1.trends.listLinks()
|
||||
const paginator = useMastoClient().v1.trends.links.list()
|
||||
|
||||
const hideNewsTips = useLocalStorage(STORAGE_KEY_HIDE_EXPLORE_NEWS_TIPS, false)
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import { STORAGE_KEY_HIDE_EXPLORE_TAGS_TIPS } from '~~/constants'
|
|||
const { t } = useI18n()
|
||||
|
||||
const { client } = $(useMasto())
|
||||
const paginator = client.v1.trends.listTags({
|
||||
const paginator = client.v1.trends.tags.list({
|
||||
limit: 20,
|
||||
})
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ const tabs = $computed<CommonRouteTabOption[]>(() => [
|
|||
)
|
||||
|
||||
const { client } = $(useMasto())
|
||||
const { data: listInfo, refresh } = $(await useAsyncData(() => client.v1.lists.fetch(list), { default: () => shallowRef() }))
|
||||
const { data: listInfo, refresh } = $(await useAsyncData(() => client.v1.lists.$select(list).fetch(), { default: () => shallowRef() }))
|
||||
|
||||
if (listInfo) {
|
||||
useHydratedHead({
|
||||
|
|
|
@ -6,7 +6,7 @@ definePageMeta({
|
|||
const params = useRoute().params
|
||||
const listId = $(computedEager(() => params.list as string))
|
||||
|
||||
const paginator = useMastoClient().v1.lists.listAccounts(listId)
|
||||
const paginator = useMastoClient().v1.lists.$select(listId).accounts.list()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
|
@ -8,8 +8,8 @@ const listId = $(computedEager(() => params.list as string))
|
|||
|
||||
const client = useMastoClient()
|
||||
|
||||
const paginator = client.v1.timelines.listList(listId)
|
||||
const stream = useStreaming(client => client.v1.stream.streamListTimeline(listId))
|
||||
const paginator = client.v1.timelines.list.$select(listId).list()
|
||||
const stream = useStreaming(client => client.list.subscribe({ list: listId }))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
|
@ -7,10 +7,10 @@ const params = useRoute().params
|
|||
const tagName = $(computedEager(() => params.tag as string))
|
||||
|
||||
const { client } = $(useMasto())
|
||||
const { data: tag, refresh } = $(await useAsyncData(() => client.v1.tags.fetch(tagName), { default: () => shallowRef() }))
|
||||
const { data: tag, refresh } = $(await useAsyncData(() => client.v1.tags.$select(tagName).fetch(), { default: () => shallowRef() }))
|
||||
|
||||
const paginator = client.v1.timelines.listHashtag(tagName)
|
||||
const stream = useStreaming(client => client.v1.stream.streamTagTimeline(tagName))
|
||||
const paginator = client.v1.timelines.tag.$select(tagName).list()
|
||||
const stream = useStreaming(client => client.hashtag.subscribe({ tag: tagName }))
|
||||
|
||||
if (tag) {
|
||||
useHydratedHead({
|
||||
|
|
|
@ -60,7 +60,7 @@ const { submit, submitting } = submitter(async ({ dirtyFields }) => {
|
|||
if (!isCanSubmit.value)
|
||||
return
|
||||
|
||||
const res = await client.v1.accounts.updateCredentials(dirtyFields.value as mastodon.v1.UpdateCredentialsParams)
|
||||
const res = await client.v1.accounts.updateCredentials(dirtyFields.value as mastodon.rest.v1.UpdateCredentialsParams)
|
||||
.then(account => ({ account }))
|
||||
.catch((error: Error) => ({ error }))
|
||||
|
||||
|
|
131
pnpm-lock.yaml
131
pnpm-lock.yaml
|
@ -168,8 +168,8 @@ importers:
|
|||
specifier: ^10.0.0
|
||||
version: 10.0.1
|
||||
masto:
|
||||
specifier: ^5.11.3
|
||||
version: 5.11.3
|
||||
specifier: ^6.5.2
|
||||
version: 6.5.2
|
||||
node-emoji:
|
||||
specifier: ^2.1.3
|
||||
version: 2.1.3
|
||||
|
@ -211,10 +211,10 @@ importers:
|
|||
version: 5.0.1
|
||||
tauri-plugin-log-api:
|
||||
specifier: github:tauri-apps/tauri-plugin-log
|
||||
version: github.com/tauri-apps/tauri-plugin-log/91dd3fe9dcaa69bae62706e75702a0ce18ce9885
|
||||
version: github.com/tauri-apps/tauri-plugin-log/19f5dcc0425e9127d2c591780e5047b83e77a7c2
|
||||
tauri-plugin-store-api:
|
||||
specifier: github:tauri-apps/tauri-plugin-store
|
||||
version: github.com/tauri-apps/tauri-plugin-store/3367248b2661abcb73d2a89f30df780c387fb57d
|
||||
version: github.com/tauri-apps/tauri-plugin-store/7d2632996f290b0f18cc5f8a2b2791046400690e
|
||||
theme-vitesse:
|
||||
specifier: ^0.7.2
|
||||
version: 0.7.2
|
||||
|
@ -248,6 +248,9 @@ importers:
|
|||
workbox-window:
|
||||
specifier: ^7.0.0
|
||||
version: 7.0.0
|
||||
ws:
|
||||
specifier: ^8.15.1
|
||||
version: 8.15.1
|
||||
devDependencies:
|
||||
'@antfu/eslint-config':
|
||||
specifier: ^0.41.3
|
||||
|
@ -279,6 +282,9 @@ importers:
|
|||
'@types/wicg-file-system-access':
|
||||
specifier: ^2020.9.6
|
||||
version: 2020.9.6
|
||||
'@types/ws':
|
||||
specifier: ^8.5.10
|
||||
version: 8.5.10
|
||||
'@unlazy/nuxt':
|
||||
specifier: ^0.9.3
|
||||
version: 0.9.3(rollup@2.79.1)
|
||||
|
@ -2699,18 +2705,6 @@ packages:
|
|||
- encoding
|
||||
- supports-color
|
||||
|
||||
/@mastojs/ponyfills@1.0.4:
|
||||
resolution: {integrity: sha512-1NaIGmcU7OmyNzx0fk+cYeGTkdXlOJOSdetaC4pStVWsrhht2cdlYSAfe5NDW3FcUmcEm2vVceB9lcClN1RCxw==}
|
||||
dependencies:
|
||||
'@types/node': 18.16.19
|
||||
'@types/node-fetch': 2.6.4
|
||||
abort-controller: 3.0.0
|
||||
form-data: 4.0.0
|
||||
node-fetch: 2.6.12
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
dev: false
|
||||
|
||||
/@netlify/functions@2.4.0:
|
||||
resolution: {integrity: sha512-dIqhdj5u4Lu/8qbYwtYpn8NfvIyPHbSTV2lAP4ocL+iwC9As06AXT0wa/xOpO2vRWJa0IMxdZaqCPnkyHlHiyg==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
|
@ -4172,8 +4166,8 @@ packages:
|
|||
string.prototype.matchall: 4.0.8
|
||||
dev: false
|
||||
|
||||
/@tauri-apps/api@1.5.1:
|
||||
resolution: {integrity: sha512-6unsZDOdlXTmauU3NhWhn+Cx0rODV+rvNvTdvolE5Kls5ybA6cqndQENDt1+FS0tF7ozCP66jwWoH6a5h90BrA==}
|
||||
/@tauri-apps/api@1.5.3:
|
||||
resolution: {integrity: sha512-zxnDjHHKjOsrIzZm6nO5Xapb/BxqUq1tc7cGkFXsFkGTsSWgCPH1D8mm0XS9weJY2OaR73I3k3S+b7eSzJDfqA==}
|
||||
engines: {node: '>= 14.6.0', npm: '>= 6.6.0', yarn: '>= 1.19.1'}
|
||||
dev: false
|
||||
|
||||
|
@ -4574,17 +4568,6 @@ packages:
|
|||
resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==}
|
||||
dev: true
|
||||
|
||||
/@types/node-fetch@2.6.4:
|
||||
resolution: {integrity: sha512-1ZX9fcN4Rvkvgv4E6PAY5WXUFWFcRWxZa3EW83UjycOB9ljJCedb2CupIP4RZMEwF/M3eTcCihbBRgwtGbg5Rg==}
|
||||
dependencies:
|
||||
'@types/node': 20.8.6
|
||||
form-data: 3.0.1
|
||||
dev: false
|
||||
|
||||
/@types/node@18.16.19:
|
||||
resolution: {integrity: sha512-IXl7o+R9iti9eBW4Wg2hx1xQDig183jj7YLn8F7udNceyfkbn1ZxmzZXuak20gR40D7pIkIY1kYGx5VIGbaHKA==}
|
||||
dev: false
|
||||
|
||||
/@types/node@20.8.6:
|
||||
resolution: {integrity: sha512-eWO4K2Ji70QzKUqRy6oyJWUeB7+g2cRagT3T/nxYibYcT4y2BDL8lqolRXjTHmkZCdJfIPaY73KbJAZmcryxTQ==}
|
||||
dependencies:
|
||||
|
@ -4650,6 +4633,12 @@ packages:
|
|||
resolution: {integrity: sha512-6hogE75Hl2Ov/jgp8ZhDaGmIF/q3J07GtXf8nCJCwKTHq7971po5+DId7grft09zG7plBwpF6ZU0yx9Du4/e1A==}
|
||||
dev: true
|
||||
|
||||
/@types/ws@8.5.10:
|
||||
resolution: {integrity: sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==}
|
||||
dependencies:
|
||||
'@types/node': 20.8.6
|
||||
dev: true
|
||||
|
||||
/@typescript-eslint/eslint-plugin@6.7.0(@typescript-eslint/parser@6.7.0)(eslint@8.49.0)(typescript@5.1.6):
|
||||
resolution: {integrity: sha512-gUqtknHm0TDs1LhY12K2NA3Rmlmp88jK9Tx8vGZMfHeNMLE3GH2e9TRub+y+SOjuYgtOmok+wt1AyDPZqxbNag==}
|
||||
engines: {node: ^16.0.0 || >=18.0.0}
|
||||
|
@ -6220,13 +6209,6 @@ packages:
|
|||
/abbrev@1.1.1:
|
||||
resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==}
|
||||
|
||||
/abort-controller@3.0.0:
|
||||
resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==}
|
||||
engines: {node: '>=6.5'}
|
||||
dependencies:
|
||||
event-target-shim: 5.0.1
|
||||
dev: false
|
||||
|
||||
/acorn-import-assertions@1.9.0(acorn@8.11.2):
|
||||
resolution: {integrity: sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==}
|
||||
peerDependencies:
|
||||
|
@ -8276,13 +8258,13 @@ packages:
|
|||
resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
/event-target-shim@5.0.1:
|
||||
resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==}
|
||||
engines: {node: '>=6'}
|
||||
dev: false
|
||||
|
||||
/eventemitter3@5.0.1:
|
||||
resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==}
|
||||
dev: true
|
||||
|
||||
/events-to-async@2.0.1:
|
||||
resolution: {integrity: sha512-RtnLYrMbXp4JkZIoZu+3VTqV21bNVBlJBZ4NmtwvMNqSE3qouhxv2gvLE4JJDaQc54ioPkrX74V6x+hp/hqjkQ==}
|
||||
dev: false
|
||||
|
||||
/events@3.3.0:
|
||||
resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==}
|
||||
|
@ -8476,15 +8458,6 @@ packages:
|
|||
cross-spawn: 7.0.3
|
||||
signal-exit: 4.1.0
|
||||
|
||||
/form-data@3.0.1:
|
||||
resolution: {integrity: sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==}
|
||||
engines: {node: '>= 6'}
|
||||
dependencies:
|
||||
asynckit: 0.4.0
|
||||
combined-stream: 1.0.8
|
||||
mime-types: 2.1.35
|
||||
dev: false
|
||||
|
||||
/form-data@4.0.0:
|
||||
resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==}
|
||||
engines: {node: '>= 6'}
|
||||
|
@ -9511,12 +9484,12 @@ packages:
|
|||
engines: {node: '>=0.10.0'}
|
||||
dev: false
|
||||
|
||||
/isomorphic-ws@5.0.0(ws@8.14.2):
|
||||
/isomorphic-ws@5.0.0(ws@8.15.1):
|
||||
resolution: {integrity: sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==}
|
||||
peerDependencies:
|
||||
ws: '*'
|
||||
dependencies:
|
||||
ws: 8.14.2
|
||||
ws: 8.15.1
|
||||
dev: false
|
||||
|
||||
/jackspeak@2.2.1:
|
||||
|
@ -10015,19 +9988,16 @@ packages:
|
|||
resolution: {integrity: sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==}
|
||||
dev: true
|
||||
|
||||
/masto@5.11.3:
|
||||
resolution: {integrity: sha512-GtSnrqm5fHPaaU0iwag4LCmvpp82rDng6yOZinmOJHHlUfo6Gnq5QY6x3lJCxCnsPIXpTu1yaX42bWrSQyoQPA==}
|
||||
/masto@6.5.2:
|
||||
resolution: {integrity: sha512-JfnG7MSQmhszWnLsvdBuxXc2tcVUyCvlTxnSH/5S+In4dU1tvc1wGhFR87kO+YW8gfDsDw9CHh+AD/z+DbTTfQ==}
|
||||
dependencies:
|
||||
'@mastojs/ponyfills': 1.0.4
|
||||
change-case: 4.1.2
|
||||
eventemitter3: 5.0.1
|
||||
isomorphic-ws: 5.0.0(ws@8.14.2)
|
||||
qs: 6.11.2
|
||||
semver: 7.5.4
|
||||
ws: 8.14.2
|
||||
events-to-async: 2.0.1
|
||||
isomorphic-ws: 5.0.0(ws@8.15.1)
|
||||
ts-custom-error: 3.3.1
|
||||
ws: 8.15.1
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- encoding
|
||||
- utf-8-validate
|
||||
dev: false
|
||||
|
||||
|
@ -12310,13 +12280,6 @@ packages:
|
|||
resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
/qs@6.11.2:
|
||||
resolution: {integrity: sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==}
|
||||
engines: {node: '>=0.6'}
|
||||
dependencies:
|
||||
side-channel: 1.0.4
|
||||
dev: false
|
||||
|
||||
/queue-microtask@1.2.3:
|
||||
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
|
||||
|
||||
|
@ -13231,7 +13194,7 @@ packages:
|
|||
hasBin: true
|
||||
peerDependencies:
|
||||
'@nuxt/kit': ^3.0.0
|
||||
'@nuxt/schema': 3.8.2
|
||||
'@nuxt/schema': ^3.0.0
|
||||
peerDependenciesMeta:
|
||||
'@nuxt/kit':
|
||||
optional: true
|
||||
|
@ -13681,6 +13644,11 @@ packages:
|
|||
typescript: 5.1.6
|
||||
dev: true
|
||||
|
||||
/ts-custom-error@3.3.1:
|
||||
resolution: {integrity: sha512-5OX1tzOjxWEgsr/YEUWSuPrQ00deKLh6D7OTWcvNHm12/7QPyRh8SYpyWvA4IZv8H/+GQWQEh/kwo95Q9OVW1A==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
dev: false
|
||||
|
||||
/tslib@1.14.1:
|
||||
resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==}
|
||||
dev: true
|
||||
|
@ -15354,6 +15322,19 @@ packages:
|
|||
utf-8-validate:
|
||||
optional: true
|
||||
|
||||
/ws@8.15.1:
|
||||
resolution: {integrity: sha512-W5OZiCjXEmk0yZ66ZN82beM5Sz7l7coYxpRkzS+p9PP+ToQry8szKh+61eNktr7EA9DOwvFGhfC605jDHbP6QQ==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
peerDependencies:
|
||||
bufferutil: ^4.0.1
|
||||
utf-8-validate: '>=5.0.2'
|
||||
peerDependenciesMeta:
|
||||
bufferutil:
|
||||
optional: true
|
||||
utf-8-validate:
|
||||
optional: true
|
||||
dev: false
|
||||
|
||||
/xml-name-validator@4.0.0:
|
||||
resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==}
|
||||
engines: {node: '>=12'}
|
||||
|
@ -15453,18 +15434,18 @@ packages:
|
|||
resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
|
||||
dev: true
|
||||
|
||||
github.com/tauri-apps/tauri-plugin-log/91dd3fe9dcaa69bae62706e75702a0ce18ce9885:
|
||||
resolution: {tarball: https://codeload.github.com/tauri-apps/tauri-plugin-log/tar.gz/91dd3fe9dcaa69bae62706e75702a0ce18ce9885}
|
||||
github.com/tauri-apps/tauri-plugin-log/19f5dcc0425e9127d2c591780e5047b83e77a7c2:
|
||||
resolution: {tarball: https://codeload.github.com/tauri-apps/tauri-plugin-log/tar.gz/19f5dcc0425e9127d2c591780e5047b83e77a7c2}
|
||||
name: tauri-plugin-log-api
|
||||
version: 0.0.0
|
||||
dependencies:
|
||||
'@tauri-apps/api': 1.5.1
|
||||
'@tauri-apps/api': 1.5.3
|
||||
dev: false
|
||||
|
||||
github.com/tauri-apps/tauri-plugin-store/3367248b2661abcb73d2a89f30df780c387fb57d:
|
||||
resolution: {tarball: https://codeload.github.com/tauri-apps/tauri-plugin-store/tar.gz/3367248b2661abcb73d2a89f30df780c387fb57d}
|
||||
github.com/tauri-apps/tauri-plugin-store/7d2632996f290b0f18cc5f8a2b2791046400690e:
|
||||
resolution: {tarball: https://codeload.github.com/tauri-apps/tauri-plugin-store/tar.gz/7d2632996f290b0f18cc5f8a2b2791046400690e}
|
||||
name: tauri-plugin-store-api
|
||||
version: 0.0.0
|
||||
dependencies:
|
||||
'@tauri-apps/api': 1.5.1
|
||||
'@tauri-apps/api': 1.5.3
|
||||
dev: false
|
||||
|
|
8
tests/setup.ts
Normal file
8
tests/setup.ts
Normal file
|
@ -0,0 +1,8 @@
|
|||
// We have TypeError: AbortSignal.timeout is not a function when running tests against masto.js v6
|
||||
if (!AbortSignal.timeout) {
|
||||
AbortSignal.timeout = (ms) => {
|
||||
const controller = new AbortController()
|
||||
setTimeout(() => controller.abort(new DOMException('TimeoutError')), ms)
|
||||
return controller.signal
|
||||
}
|
||||
}
|
|
@ -47,7 +47,7 @@ export type TranslateFn = ReturnType<typeof useI18n>['t']
|
|||
export interface Draft {
|
||||
editingStatus?: mastodon.v1.Status
|
||||
initialText?: string
|
||||
params: MarkNonNullable<Mutable<Omit<mastodon.v1.CreateStatusParams, 'poll'>>, 'status' | 'language' | 'sensitive' | 'spoilerText' | 'visibility'> & { poll: Mutable<mastodon.v1.CreateStatusParams['poll']> }
|
||||
params: MarkNonNullable<Mutable<Omit<mastodon.rest.v1.CreateStatusParams, 'poll'>>, 'status' | 'language' | 'sensitive' | 'spoilerText' | 'visibility'> & { poll: Mutable<mastodon.rest.v1.CreateStatusParams['poll']> }
|
||||
attachments: mastodon.v1.MediaAttachment[]
|
||||
lastUpdated: number
|
||||
mentions?: string[]
|
||||
|
|
|
@ -4,4 +4,9 @@ export default defineVitestConfig({
|
|||
define: {
|
||||
'process.test': 'true',
|
||||
},
|
||||
test: {
|
||||
setupFiles: [
|
||||
'/tests/setup.ts',
|
||||
],
|
||||
},
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue