initial streaming work

This commit is contained in:
Henry Jameson 2019-11-24 18:50:28 +02:00
parent ddb6fb9217
commit 319bb4ac28
4 changed files with 76 additions and 5 deletions

View File

@ -6,6 +6,7 @@ const api = {
backendInteractor: backendInteractorService(), backendInteractor: backendInteractorService(),
fetchers: {}, fetchers: {},
socket: null, socket: null,
mastoSocket: null,
followRequests: [] followRequests: []
}, },
mutations: { mutations: {
@ -29,6 +30,20 @@ const api = {
} }
}, },
actions: { 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 }) { startFetchingTimeline (store, { timeline = 'friends', tag = false, userId = false }) {
// Don't start fetching if we already are. // Don't start fetching if we already are.
if (store.state.fetchers[timeline]) return if (store.state.fetchers[timeline]) return

View File

@ -469,11 +469,14 @@ const users = {
store.dispatch('initializeSocket') store.dispatch('initializeSocket')
} }
// Start getting fresh posts. store.dispatch('startMastoSocket').catch((error) => {
store.dispatch('startFetchingTimeline', { timeline: 'friends' }) console.error(error)
// Start getting fresh posts.
store.dispatch('startFetchingTimeline', { timeline: 'friends' })
// Start fetching notifications // Start fetching notifications
store.dispatch('startFetchingNotifications') store.dispatch('startFetchingNotifications')
})
// Get user mutes // Get user mutes
store.dispatch('fetchMutes') store.dispatch('fetchMutes')

View File

@ -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_UNMUTE_CONVERSATION = id => `/api/v1/statuses/${id}/unmute`
const MASTODON_SEARCH_2 = `/api/v2/search` const MASTODON_SEARCH_2 = `/api/v2/search`
const MASTODON_USER_SEARCH_URL = '/api/v1/accounts/search' const MASTODON_USER_SEARCH_URL = '/api/v1/accounts/search'
const MASTODON_STREAMING = '/api/v1/streaming'
const oldfetch = window.fetch 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 = { const apiService = {
verifyCredentials, verifyCredentials,
fetchTimeline, fetchTimeline,

View File

@ -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 timelineFetcherService from '../timeline_fetcher/timeline_fetcher.service.js'
import notificationsFetcher from '../notifications_fetcher/notifications_fetcher.service.js' import notificationsFetcher from '../notifications_fetcher/notifications_fetcher.service.js'
import followRequestFetcher from '../../services/follow_request_fetcher/follow_request_fetcher.service' import followRequestFetcher from '../../services/follow_request_fetcher/follow_request_fetcher.service'
@ -16,6 +16,19 @@ const backendInteractorService = credentials => ({
return followRequestFetcher.startFetching({ store, 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]) => { ...Object.entries(apiService).reduce((acc, [key, func]) => {
return { return {
...acc, ...acc,