elk/composables/masto/masto.ts

112 lines
3.4 KiB
TypeScript
Raw Normal View History

2023-01-15 11:38:02 +03:00
import type { Pausable } from '@vueuse/core'
2024-01-09 11:56:15 +03:00
import type { mastodon } from 'masto'
2023-01-15 11:38:02 +03:00
import type { Ref } from 'vue'
import type { ElkInstance } from '../users'
import type { UserLogin } from '~/types'
import { createRestAPIClient, createStreamingAPIClient } from 'masto'
2023-01-15 11:38:02 +03:00
export function createMasto() {
2023-01-15 11:38:02 +03:00
return {
2024-01-09 11:56:15 +03:00
client: shallowRef<mastodon.rest.Client>(undefined as never),
streamingClient: shallowRef<mastodon.streaming.Client | undefined>(),
2023-01-15 11:38:02 +03:00
}
}
export type ElkMasto = ReturnType<typeof createMasto>
2023-01-06 21:40:15 +03:00
export function useMasto() {
return useNuxtApp().$masto as ElkMasto
}
export function useMastoClient() {
return useMasto().client.value
}
2023-01-15 11:38:02 +03:00
export function mastoLogin(masto: ElkMasto, user: Pick<UserLogin, 'server' | 'token'>) {
const server = user.server
const url = `https://${server}`
2023-01-15 12:44:36 +03:00
const instance: ElkInstance = reactive(getInstanceCache(server) || { uri: server, accountDomain: server })
2024-01-09 11:56:15 +03:00
const accessToken = user.token
2023-01-15 11:38:02 +03:00
2024-01-09 11:56:15 +03:00
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) => {
2023-01-15 11:38:02 +03:00
Object.assign(instance, newInstance)
2024-01-09 11:56:15 +03:00
if (newInstance.urls.streamingApi !== streamingApiUrl)
masto.streamingClient.value = createStreamingClient(newInstance.urls.streamingApi)
instanceStorage.value[server] = newInstance
2023-01-15 11:38:02 +03:00
})
return instance
}
interface UseStreamingOptions<Controls extends boolean> {
/**
* Expose more controls
*
* @default false
*/
controls?: Controls
/**
* Connect on calling
*
* @default true
*/
immediate?: boolean
}
export function useStreaming(
2024-01-09 11:56:15 +03:00
cb: (client: mastodon.streaming.Client) => mastodon.streaming.Subscription,
2023-01-15 11:38:02 +03:00
options: UseStreamingOptions<true>,
2024-01-09 11:56:15 +03:00
): { stream: Ref<mastodon.streaming.Subscription | undefined> } & Pausable
2023-01-15 11:38:02 +03:00
export function useStreaming(
2024-01-09 11:56:15 +03:00
cb: (client: mastodon.streaming.Client) => mastodon.streaming.Subscription,
2023-01-15 11:38:02 +03:00
options?: UseStreamingOptions<false>,
2024-01-09 11:56:15 +03:00
): Ref<mastodon.streaming.Subscription | undefined>
2023-01-15 11:38:02 +03:00
export function useStreaming(
2024-01-09 11:56:15 +03:00
cb: (client: mastodon.streaming.Client) => mastodon.streaming.Subscription,
2023-01-15 11:38:02 +03:00
{ immediate = true, controls }: UseStreamingOptions<boolean> = {},
2024-01-09 11:56:15 +03:00
): ({ stream: Ref<mastodon.streaming.Subscription | undefined> } & Pausable) | Ref<mastodon.streaming.Subscription | undefined> {
const { streamingClient } = useMasto()
2023-01-15 11:38:02 +03:00
const isActive = ref(immediate)
2024-01-09 11:56:15 +03:00
const stream = ref<mastodon.streaming.Subscription>()
2023-01-15 11:38:02 +03:00
function pause() {
isActive.value = false
}
function resume() {
isActive.value = true
}
function cleanup() {
if (stream.value) {
2024-01-09 11:56:15 +03:00
stream.value.unsubscribe()
2023-01-15 11:38:02 +03:00
stream.value = undefined
}
}
watchEffect(() => {
cleanup()
2024-01-09 11:56:15 +03:00
if (streamingClient.value && isActive.value)
stream.value = cb(streamingClient.value)
2023-01-15 11:38:02 +03:00
})
2023-01-06 21:40:15 +03:00
2024-02-24 19:46:14 +03:00
if (import.meta.client && !process.test)
useNuxtApp().$pageLifecycle.addFrozenListener(cleanup)
2023-01-15 11:38:02 +03:00
tryOnBeforeUnmount(() => isActive.value = false)
2023-01-06 21:40:15 +03:00
2023-01-15 11:38:02 +03:00
if (controls)
return { stream, isActive, pause, resume }
else
return stream
2023-01-06 21:40:15 +03:00
}