aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenry Jameson <me@hjkos.com>2019-11-24 18:50:28 +0200
committerHenry Jameson <me@hjkos.com>2019-11-24 18:50:28 +0200
commit319bb4ac2895b8eb62da42e3f95addc9bb67b1a0 (patch)
treede24974025e9df8ca77b6417df3813e1722beeec
parentddb6fb9217789e90490a4ec1ce7a2dd9ced67631 (diff)
initial streaming work
-rw-r--r--src/modules/api.js15
-rw-r--r--src/modules/users.js13
-rw-r--r--src/services/api/api.service.js40
-rw-r--r--src/services/backend_interactor_service/backend_interactor_service.js15
4 files changed, 77 insertions, 6 deletions
diff --git a/src/modules/api.js b/src/modules/api.js
index 1293e3c8..1bf65db5 100644
--- a/src/modules/api.js
+++ b/src/modules/api.js
@@ -6,6 +6,7 @@ const api = {
backendInteractor: backendInteractorService(),
fetchers: {},
socket: null,
+ mastoSocket: null,
followRequests: []
},
mutations: {
@@ -29,6 +30,20 @@ const api = {
}
},
actions: {
+ startMastoSocket (store) {
+ store.state.mastoSocket = store.state.backendInteractor
+ .startUserSocket({
+ store,
+ onMessage: (message) => {
+ if (!message) return
+ if (message.event === 'notification') {
+ store.dispatch('addNewNotifications', { notifications: [message.notification], older: false })
+ } else if (message.event === 'update') {
+ store.dispatch('addNewStatuses', { statuses: [message.status], userId: false, showImmediately: false, timeline: 'friends' })
+ }
+ }
+ })
+ },
startFetchingTimeline (store, { timeline = 'friends', tag = false, userId = false }) {
// Don't start fetching if we already are.
if (store.state.fetchers[timeline]) return
diff --git a/src/modules/users.js b/src/modules/users.js
index e1373220..861a2f4f 100644
--- a/src/modules/users.js
+++ b/src/modules/users.js
@@ -469,11 +469,14 @@ const users = {
store.dispatch('initializeSocket')
}
- // Start getting fresh posts.
- store.dispatch('startFetchingTimeline', { timeline: 'friends' })
-
- // Start fetching notifications
- store.dispatch('startFetchingNotifications')
+ store.dispatch('startMastoSocket').catch((error) => {
+ console.error(error)
+ // Start getting fresh posts.
+ store.dispatch('startFetchingTimeline', { timeline: 'friends' })
+
+ // Start fetching notifications
+ store.dispatch('startFetchingNotifications')
+ })
// Get user mutes
store.dispatch('fetchMutes')
diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js
index 8f5eb416..7f27564f 100644
--- a/src/services/api/api.service.js
+++ b/src/services/api/api.service.js
@@ -71,6 +71,7 @@ const MASTODON_MUTE_CONVERSATION = id => `/api/v1/statuses/${id}/mute`
const MASTODON_UNMUTE_CONVERSATION = id => `/api/v1/statuses/${id}/unmute`
const MASTODON_SEARCH_2 = `/api/v2/search`
const MASTODON_USER_SEARCH_URL = '/api/v1/accounts/search'
+const MASTODON_STREAMING = '/api/v1/streaming'
const oldfetch = window.fetch
@@ -932,6 +933,45 @@ const search2 = ({ credentials, q, resolve, limit, offset, following }) => {
})
}
+export const getMastodonSocketURI = ({ credentials, stream, args = {} }) => {
+ return Object.entries({
+ ...(credentials
+ ? { access_token: credentials }
+ : {}
+ ),
+ stream,
+ ...args
+ }).reduce((acc, [key, val]) => {
+ return acc + `${key}=${val}&`
+ }, MASTODON_STREAMING + '?')
+}
+
+const MASTODON_STREAMING_EVENTS = new Set([
+ 'update',
+ 'notification',
+ 'delete',
+ 'filters_changed'
+])
+
+export const handleMastoWS = (wsEvent) => {
+ console.debug('Event', wsEvent)
+ const { data } = wsEvent
+ if (!data) return
+ const parsedEvent = JSON.parse(data)
+ const { event, payload } = parsedEvent
+ if (MASTODON_STREAMING_EVENTS.has(event)) {
+ const data = payload ? JSON.parse(payload) : null
+ if (event === 'update') {
+ return { event, status: parseStatus(data) }
+ } else if (event === 'notification') {
+ return { event, notification: parseNotification(data) }
+ }
+ } else {
+ console.warn('Unknown event', wsEvent)
+ return null
+ }
+}
+
const apiService = {
verifyCredentials,
fetchTimeline,
diff --git a/src/services/backend_interactor_service/backend_interactor_service.js b/src/services/backend_interactor_service/backend_interactor_service.js
index 57fdccde..0cef4640 100644
--- a/src/services/backend_interactor_service/backend_interactor_service.js
+++ b/src/services/backend_interactor_service/backend_interactor_service.js
@@ -1,4 +1,4 @@
-import apiService from '../api/api.service.js'
+import apiService, { getMastodonSocketURI, handleMastoWS } from '../api/api.service.js'
import timelineFetcherService from '../timeline_fetcher/timeline_fetcher.service.js'
import notificationsFetcher from '../notifications_fetcher/notifications_fetcher.service.js'
import followRequestFetcher from '../../services/follow_request_fetcher/follow_request_fetcher.service'
@@ -16,6 +16,19 @@ const backendInteractorService = credentials => ({
return followRequestFetcher.startFetching({ store, credentials })
},
+ startUserSocket ({ store, onMessage }) {
+ const serv = store.rootState.instance.server.replace('https', 'wss')
+ // const serb = 'ws://localhost:8080/'
+ const url = serv + getMastodonSocketURI({ credentials, stream: 'user' })
+ const socket = new WebSocket(url)
+ console.log(socket)
+ if (socket) {
+ socket.addEventListener('message', (wsEvent) => onMessage(handleMastoWS(wsEvent)))
+ } else {
+ throw new Error('failed to connect to socket')
+ }
+ },
+
...Object.entries(apiService).reduce((acc, [key, func]) => {
return {
...acc,