diff --git a/app/components/timeline/TimelineHome.vue b/app/components/timeline/TimelineHome.vue index b9b155ec..a0ed7cdf 100644 --- a/app/components/timeline/TimelineHome.vue +++ b/app/components/timeline/TimelineHome.vue @@ -6,7 +6,12 @@ const isSlow = computed(() => isSupported.value && effectiveType.value && ['slow const limit = computed(() => isSlow.value ? 10 : 30) const paginator = useMastoClient().v1.timelines.home.list({ limit: limit.value }) -const stream = useStreaming(client => client.user.subscribe()) + +// streaming requires user session +let stream: Ref +if (currentUser.value !== undefined) + stream = useStreaming(client => client.user.subscribe()) + function reorderAndFilter(items: mastodon.v1.Status[]) { return reorderedTimeline(items, 'home') } diff --git a/app/components/timeline/TimelineNotifications.vue b/app/components/timeline/TimelineNotifications.vue index 548e7020..035446e9 100644 --- a/app/components/timeline/TimelineNotifications.vue +++ b/app/components/timeline/TimelineNotifications.vue @@ -14,8 +14,11 @@ 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) -// @ts-expect-error Type error should be fixed with the following PR to masto.js: https://github.com/neet/masto.js/pull/1355 -const stream = useStreaming(client => client.user.notification.subscribe()) +// streaming requires user session +let stream: Ref +if (currentUser.value !== undefined) + // @ts-expect-error Type error should be fixed with the following PR to masto.js: https://github.com/neet/masto.js/pull/1355 + stream = useStreaming(client => client.user.notification.subscribe()) lastAccessedNotificationRoute.value = route.path.replace(/\/notifications\/?/, '') diff --git a/app/components/timeline/TimelinePublic.vue b/app/components/timeline/TimelinePublic.vue index 2193f0b2..73da7b74 100644 --- a/app/components/timeline/TimelinePublic.vue +++ b/app/components/timeline/TimelinePublic.vue @@ -2,7 +2,12 @@ import type { mastodon } from 'masto' const paginator = useMastoClient().v1.timelines.public.list({ limit: 30 }) -const stream = useStreaming(client => client.public.subscribe()) + +// streaming requires user session +let stream: Ref +if (currentUser.value !== undefined) + stream = useStreaming(client => client.public.subscribe()) + function reorderAndFilter(items: mastodon.v1.Status[]) { return reorderedTimeline(items, 'public') } diff --git a/app/components/timeline/TimelinePublicLocal.vue b/app/components/timeline/TimelinePublicLocal.vue index f3514bfd..c7de4c64 100644 --- a/app/components/timeline/TimelinePublicLocal.vue +++ b/app/components/timeline/TimelinePublicLocal.vue @@ -2,7 +2,12 @@ import type { mastodon } from 'masto' const paginator = useMastoClient().v1.timelines.public.list({ limit: 30, local: true }) -const stream = useStreaming(client => client.public.local.subscribe()) + +// streaming requires user session +let stream: Ref +if (currentUser.value !== undefined) + stream = useStreaming(client => client.public.local.subscribe()) + function reorderAndFilter(items: mastodon.v1.Status[]) { return reorderedTimeline(items, 'public') } diff --git a/app/composables/masto/masto.ts b/app/composables/masto/masto.ts index 30dfd987..3a217519 100644 --- a/app/composables/masto/masto.ts +++ b/app/composables/masto/masto.ts @@ -26,54 +26,59 @@ export function mastoLogin(masto: ElkMasto, user: Pick { - return streamingApiUrl ? createStreamingAPIClient({ streamingApiUrl, accessToken, implementation: globalThis.WebSocket }) : undefined - } + let createStreamingClient: (streamingApiUrl: string | undefined) => mastodon.streaming.Client | undefined - const streamingApiUrl = instance?.configuration?.urls?.streaming masto.client.value = createRestAPIClient({ url, accessToken }) - masto.streamingClient.value = createStreamingClient(streamingApiUrl) - // Refetch instance info in the background on login - masto.client.value.v2.instance.fetch().catch(error => new Promise((resolve, reject) => { - if (error instanceof MastoHttpError && error.statusCode === 404) { - return masto.client.value.v1.instance.fetch().then((newInstance) => { - console.warn(`Instance ${server} on version ${newInstance.version} does not support "GET /api/v2/instance" API, try converting to v2 instance... expect some errors`) - const v2Instance = { - ...newInstance, - domain: newInstance.uri, - sourceUrl: '', - usage: { - users: { - activeMonth: 0, - }, - }, - icon: [], - apiVersions: { - mastodon: newInstance.version, - }, - contact: { - email: newInstance.email, - }, - configuration: { - ...(newInstance.configuration ?? {}), - urls: { - streaming: newInstance.urls.streamingApi, - }, - }, - } as unknown as mastodon.v2.Instance - return resolve(v2Instance) - }).catch(reject) + if (currentUser.value !== undefined) { + createStreamingClient = (streamingApiUrl: string | undefined) => { + return streamingApiUrl ? createStreamingAPIClient({ streamingApiUrl, accessToken, implementation: globalThis.WebSocket }) : undefined } - return reject(error) - })).then((newInstance) => { - Object.assign(instance, newInstance) - if (newInstance.configuration.urls.streaming !== streamingApiUrl) - masto.streamingClient.value = createStreamingClient(newInstance.configuration.urls.streaming) + const streamingApiUrl = instance?.configuration?.urls?.streaming + masto.streamingClient.value = createStreamingClient(streamingApiUrl) - instanceStorage.value[server] = newInstance - }) + // Refetch instance info in the background on login + masto.client.value.v2.instance.fetch().catch(error => new Promise((resolve, reject) => { + if (error instanceof MastoHttpError && error.statusCode === 404) { + return masto.client.value.v1.instance.fetch().then((newInstance) => { + console.warn(`Instance ${server} on version ${newInstance.version} does not support "GET /api/v2/instance" API, try converting to v2 instance... expect some errors`) + const v2Instance = { + ...newInstance, + domain: newInstance.uri, + sourceUrl: '', + usage: { + users: { + activeMonth: 0, + }, + }, + icon: [], + apiVersions: { + mastodon: newInstance.version, + }, + contact: { + email: newInstance.email, + }, + configuration: { + ...(newInstance.configuration ?? {}), + urls: { + streaming: newInstance.urls.streamingApi, + }, + }, + } as unknown as mastodon.v2.Instance + return resolve(v2Instance) + }).catch(reject) + } + + return reject(error) + })).then((newInstance) => { + Object.assign(instance, newInstance) + if (newInstance.configuration.urls.streaming !== streamingApiUrl) + masto.streamingClient.value = createStreamingClient(newInstance.configuration.urls.streaming) + + instanceStorage.value[server] = newInstance + }) + } return instance } diff --git a/app/pages/[[server]]/list/[list]/index/index.vue b/app/pages/[[server]]/list/[list]/index/index.vue index 8dc5a697..6d991fab 100644 --- a/app/pages/[[server]]/list/[list]/index/index.vue +++ b/app/pages/[[server]]/list/[list]/index/index.vue @@ -1,4 +1,6 @@