Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F85628156
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
26 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/src/App.js b/src/App.js
index b018929d9d..095c5df80c 100644
--- a/src/App.js
+++ b/src/App.js
@@ -1,107 +1,106 @@
import UserPanel from './components/user_panel/user_panel.vue'
import NavPanel from './components/nav_panel/nav_panel.vue'
import Notifications from './components/notifications/notifications.vue'
import UserFinder from './components/user_finder/user_finder.vue'
import InstanceSpecificPanel from './components/instance_specific_panel/instance_specific_panel.vue'
import FeaturesPanel from './components/features_panel/features_panel.vue'
import WhoToFollowPanel from './components/who_to_follow_panel/who_to_follow_panel.vue'
import ChatPanel from './components/chat_panel/chat_panel.vue'
import MediaModal from './components/media_modal/media_modal.vue'
import SideDrawer from './components/side_drawer/side_drawer.vue'
-import { unseenNotificationsFromStore } from './services/notification_utils/notification_utils'
export default {
name: 'app',
components: {
UserPanel,
NavPanel,
Notifications,
UserFinder,
InstanceSpecificPanel,
FeaturesPanel,
WhoToFollowPanel,
ChatPanel,
MediaModal,
SideDrawer
},
data: () => ({
mobileActivePanel: 'timeline',
finderHidden: true,
supportsMask: window.CSS && window.CSS.supports && (
window.CSS.supports('mask-size', 'contain') ||
window.CSS.supports('-webkit-mask-size', 'contain') ||
window.CSS.supports('-moz-mask-size', 'contain') ||
window.CSS.supports('-ms-mask-size', 'contain') ||
window.CSS.supports('-o-mask-size', 'contain')
)
}),
created () {
// Load the locale from the storage
this.$i18n.locale = this.$store.state.config.interfaceLanguage
},
computed: {
currentUser () { return this.$store.state.users.currentUser },
background () {
return this.currentUser.background_image || this.$store.state.instance.background
},
enableMask () { return this.supportsMask && this.$store.state.instance.logoMask },
logoStyle () {
return {
'visibility': this.enableMask ? 'hidden' : 'visible'
}
},
logoMaskStyle () {
return this.enableMask ? {
'mask-image': `url(${this.$store.state.instance.logo})`
} : {
'background-color': this.enableMask ? '' : 'transparent'
}
},
logoBgStyle () {
return Object.assign({
'margin': `${this.$store.state.instance.logoMargin} 0`,
opacity: this.finderHidden ? 1 : 0
}, this.enableMask ? {} : {
'background-color': this.enableMask ? '' : 'transparent'
})
},
logo () { return this.$store.state.instance.logo },
bgStyle () {
return {
'background-image': `url(${this.background})`
}
},
bgAppStyle () {
return {
'--body-background-image': `url(${this.background})`
}
},
sitename () { return this.$store.state.instance.name },
chat () { return this.$store.state.chat.channel.state === 'joined' },
suggestionsEnabled () { return this.$store.state.instance.suggestionsEnabled },
showInstanceSpecificPanel () { return this.$store.state.instance.showInstanceSpecificPanel },
unseenNotifications () {
// TODO: Fix
return []
},
unseenNotificationsCount () {
return this.unseenNotifications.length
},
showFeaturesPanel () { return this.$store.state.instance.showFeaturesPanel }
},
methods: {
scrollToTop () {
window.scrollTo(0, 0)
},
logout () {
this.$router.replace('/main/public')
this.$store.dispatch('logoutUser')
},
onFinderToggled (hidden) {
this.finderHidden = hidden
},
toggleMobileSidebar () {
this.$refs.sideDrawer.toggleDrawer()
}
}
}
diff --git a/src/components/notifications/notifications.js b/src/components/notifications/notifications.js
index c25bf74016..38ef6cb853 100644
--- a/src/components/notifications/notifications.js
+++ b/src/components/notifications/notifications.js
@@ -1,59 +1,62 @@
import Notification from '../notification/notification.vue'
+import { getNotificationVisibleTypes } from '../../services/notification_helper/notification_helper'
-import { map } from 'lodash'
+import values from 'lodash/values'
+import orderBy from 'lodash/orderBy'
const Notifications = {
created () {
this.$store.dispatch('startFetchingNotifications')
},
- data () {
- return {
- bottomedOut: false
- }
- },
computed: {
- error () {
- // TODO: fix
- return false
- },
- unseenNotifications () {
- // TODO: fix
- return []
+ visibleTypes () {
+ return getNotificationVisibleTypes(this.$store.state.config.notificationVisibility)
},
visibleNotifications () {
- const notifications = map(this.$store.state.notifications.visibleNotificationIds, (id) => {
- return this.$store.state.notifications.notifications[id]
- })
- return notifications
+ const notifications = values(this.$store.state.notifications.notifications)
+ const filteredNotifications = notifications.filter(notification => this.visibleTypes.includes(notification.type))
+ const sortedNotifications = orderBy(filteredNotifications, ['seen', 'id'], ['asc', 'desc'])
+ return sortedNotifications
+ },
+ unseenNotifications () {
+ return this.visibleNotifications.filter(notification => !notification.seen)
},
unseenCount () {
return this.unseenNotifications.length
},
loading () {
- // TODO: Fix
- return false
+ return this.$store.state.notifications.loading
+ },
+ error () {
+ return this.$store.state.notifications.error
+ },
+ bottomedOut () {
+ return this.$store.state.notifications.bottomedOut
}
},
components: {
Notification
},
watch: {
unseenCount (count) {
if (count > 0) {
this.$store.dispatch('setPageTitle', `(${count})`)
} else {
this.$store.dispatch('setPageTitle', '')
}
}
},
methods: {
markAsSeen () {
- this.$store.dispatch('markNotificationsAsSeen', this.visibleNotifications)
+ this.$store.dispatch('markNotificationsAsSeen')
},
fetchOlderNotifications () {
- // TODO: Repair
+ this.$store.dispatch('fetchOlderNotifications')
}
+ },
+ destroyed () {
+ this.$store.dispatch('stopFetchingNotifications')
}
}
export default Notifications
diff --git a/src/i18n/i18n.js b/src/i18n/i18n.js
new file mode 100644
index 0000000000..f106259692
--- /dev/null
+++ b/src/i18n/i18n.js
@@ -0,0 +1,14 @@
+import Vue from 'vue'
+import VueI18n from 'vue-i18n'
+import messages from './messages.js'
+
+Vue.use(VueI18n)
+
+const currentLocale = (window.navigator.language || 'en').split('-')[0]
+
+export default new VueI18n({
+ // By default, use the browser locale, we will update it if neccessary
+ locale: currentLocale,
+ fallbackLocale: 'en',
+ messages
+})
diff --git a/src/main.js b/src/main.js
index beab301188..28dd710589 100644
--- a/src/main.js
+++ b/src/main.js
@@ -1,86 +1,76 @@
import Vue from 'vue'
import VueRouter from 'vue-router'
import Vuex from 'vuex'
import interfaceModule from './modules/interface.js'
import instanceModule from './modules/instance.js'
import statusesModule from './modules/statuses.js'
import notificationsModule from './modules/notifications.js'
import usersModule from './modules/users.js'
import apiModule from './modules/api.js'
import configModule from './modules/config.js'
import chatModule from './modules/chat.js'
import oauthModule from './modules/oauth.js'
import mediaViewerModule from './modules/media_viewer.js'
import oauthTokensModule from './modules/oauth_tokens.js'
import VueTimeago from 'vue-timeago'
-import VueI18n from 'vue-i18n'
import createPersistedState from './lib/persisted_state.js'
import pushNotifications from './lib/push_notifications_plugin.js'
-import messages from './i18n/messages.js'
-
import VueChatScroll from 'vue-chat-scroll'
import afterStoreSetup from './boot/after_store.js'
+import i18n from './i18n/i18n.js'
const currentLocale = (window.navigator.language || 'en').split('-')[0]
Vue.use(Vuex)
Vue.use(VueRouter)
Vue.use(VueTimeago, {
locale: currentLocale === 'ja' ? 'ja' : 'en',
locales: {
'en': require('../static/timeago-en.json'),
'ja': require('../static/timeago-ja.json')
}
})
-Vue.use(VueI18n)
Vue.use(VueChatScroll)
-const i18n = new VueI18n({
- // By default, use the browser locale, we will update it if neccessary
- locale: currentLocale,
- fallbackLocale: 'en',
- messages
-})
-
const persistedStateOptions = {
paths: [
'config',
'users.lastLoginName',
'oauth'
]
};
(async function () {
const persistedState = await createPersistedState(persistedStateOptions)
const store = new Vuex.Store({
modules: {
interface: interfaceModule,
instance: instanceModule,
statuses: statusesModule,
notifications: notificationsModule,
users: usersModule,
api: apiModule,
config: configModule,
chat: chatModule,
oauth: oauthModule,
mediaViewer: mediaViewerModule,
oauthTokens: oauthTokensModule
},
plugins: [persistedState, pushNotifications],
strict: false // Socket modifies itself, let's ignore this for now.
// strict: process.env.NODE_ENV !== 'production'
})
afterStoreSetup({ store, i18n })
})()
// These are inlined by webpack's DefinePlugin
/* eslint-disable */
window.___pleromafe_mode = process.env
window.___pleromafe_commit_hash = COMMIT_HASH
window.___pleromafe_dev_overrides = DEV_OVERRIDES
diff --git a/src/modules/api.js b/src/modules/api.js
index 8a0081fc2b..5de5f5aa83 100644
--- a/src/modules/api.js
+++ b/src/modules/api.js
@@ -1,79 +1,71 @@
import TimelineFetcher from '../services/timeline_fetcher/timeline_fetcher.service.js'
-import NotificationsFetcher from '../services/notifications_fetcher/notifications_fetcher.service.js'
import ApiUtils from '../services/new_api/utils.js'
import parseLinkHeader from 'parse-link-header'
const Api = {
state: {
fetchers: {}
},
mutations: {
setFetcher (state, { fetcher, timelineName }) {
state.fetchers[timelineName] = fetcher
}
},
actions: {
- async startFetchingNotifications ({ state, rootState, commit, dispatch }) {
- if (state.fetchers['user_notifications']) {
- return
- }
- const fetcher = await NotificationsFetcher.create({ state: rootState, commit, dispatch })
- commit('setFetcher', { fetcher, timelineName: 'user_notifications' })
- },
async startFetchingTimeline ({ state, rootState, commit, dispatch }, options) {
if (state.fetchers[options.timelineName]) {
return
}
const fetcher = await TimelineFetcher.create({ state: rootState, commit, dispatch }, options)
commit('setFetcher', { fetcher, timelineName: options.timelineName })
},
// TODO: DRY up.
async fetchPrevForTimeline ({ commit, rootState, dispatch }, { timelineName }) {
const store = { commit, state: rootState, dispatch }
const data = await ApiUtils.request({
store,
fullUrl: store.state.statuses.timelines[timelineName].links.prev.url
})
const statuses = await data.json()
const links = parseLinkHeader(data.headers.get('link'))
store.dispatch('addNewStatusesToTimeline', { statuses, timelineName })
// We don't always get new link headers.
if (links && links.prev) {
store.commit('setPrevLinkForTimeline', { link: links.prev, timelineName })
}
},
async fetchNextForTimeline ({ commit, rootState, dispatch }, { timelineName }) {
const store = { commit, state: rootState, dispatch }
// We don't want to fetch next if the previous fetching is still in progress
if (store.state.statuses.timelines[timelineName].loading) {
return
}
store.dispatch('startFetchingNextForTimeline', { timelineName })
const data = await ApiUtils.request({
store,
fullUrl: store.state.statuses.timelines[timelineName].links.next.url
})
const statuses = await data.json()
const links = parseLinkHeader(data.headers.get('link'))
store.dispatch('addNewStatusesToTimeline', { statuses, timelineName })
store.dispatch('showOldStatusesForTimeline', { timelineName, statuses })
// We don't always get new link headers.
if (links && links.next) {
store.commit('setNextLinkForTimeline', { link: links.next, timelineName })
}
store.dispatch('completeFetchingNextForTimeline', { timelineName })
},
stopFetchingTimeline ({ state, commit }, { timelineName }) {
const fetcher = state.fetchers[timelineName]
clearInterval(fetcher)
commit('setFetcher', { fetcher: false, timelineName })
}
}
}
export default Api
diff --git a/src/modules/notifications.js b/src/modules/notifications.js
index 409fb423d6..f4e6e411a3 100644
--- a/src/modules/notifications.js
+++ b/src/modules/notifications.js
@@ -1,31 +1,139 @@
-import { map, each, merge, uniq } from 'lodash'
import Vue from 'vue'
+import map from 'lodash/map'
+import mapValues from 'lodash/mapValues'
+import each from 'lodash/each'
+import merge from 'lodash/merge'
+import filter from 'lodash/filter'
+import keys from 'lodash/keys'
+import Notifications from '../services/new_api/notifications'
+import { getNotificationVisibleTypes, showDesktopPushNotification } from '../services/notification_helper/notification_helper'
+
+async function fetchAndUpdate (store, older = false) {
+ const rootState = store.rootState || store.state
+ const state = rootState.notifications
+ const notificationIds = keys(state.notifications)
+ const params = {}
+
+ if (older) {
+ if (notificationIds.length > 0) {
+ params['max_id'] = Math.min(...notificationIds)
+ }
+ } else {
+ // load unread notifications repeadedly to provide consistency between browser tabs
+ const unreadIds = filter(state.notifications, n => !n.seen).map(n => n.id)
+ if (unreadIds.length === 0) {
+ if (notificationIds.length > 0) {
+ params['since_id'] = Math.max(...notificationIds)
+ }
+ } else {
+ const minId = Math.min(...unreadIds)
+ const maxId = Math.max(...unreadIds)
+ params['min_id'] = minId
+ if (maxId - minId >= 20) {
+ params['max_id'] = maxId + 1
+ }
+ }
+ }
+
+ try {
+ const { notifications } = await Notifications.all({ store, params })
+ store.dispatch('addNewNotifications', { notifications })
+ store.commit('setNotificationsError', false)
+ return notifications
+ } catch (e) {
+ store.commit('setNotificationsError', true)
+ return null
+ }
+}
const notifications = {
state: {
notifications: {},
- visibleNotificationIds: []
+ error: false,
+ loading: false,
+ bottomedOut: false,
+ fetcher: undefined,
+ desktopNotificationSilence: true
},
mutations: {
- addNewNotificationsTwo (state, newNotifications) {
+ addNewNotifications (state, newNotifications) {
each(newNotifications, (notification) => {
Vue.set(state.notifications, notification.id, merge(state.notifications[notification.id] || {}, notification))
})
},
- setVisibleNotifications (state, { notificationIds }) {
- state.visibleNotificationIds = notificationIds
+ markNotificationsAsSeen (state) {
+ state.notifications = mapValues(state.notifications, (notification) => ({ ...notification, seen: true }))
+ },
+ setNotificationsError (state, error) {
+ state.error = error
+ },
+ setNotificationsLoading (state, loading) {
+ state.loading = loading
+ },
+ setNotificationsBottomedOut (state, bottomedOut) {
+ state.bottomedOut = bottomedOut
+ },
+ setNotificationsFetcher (state, fetcher) {
+ state.fetcher = fetcher
+ },
+ setNotificationsSilence (state, silence) {
+ state.desktopNotificationSilence = silence
}
},
actions: {
- async addNewNotificationsTwo ({ commit, state }, { notifications }) {
+ async startFetchingNotifications ({ state, rootState, commit, dispatch }) {
+ if (state.fetcher) {
+ return
+ }
+
+ // Fetch the initial data
+ const store = { state: rootState, commit, dispatch }
+ const { notifications } = await Notifications.all({ store })
+ dispatch('addNewNotifications', { notifications })
+
+ // Continue fetching at specified intervals
+ const fetcher = setInterval(() => fetchAndUpdate(store), 10000)
+ commit('setNotificationsFetcher', fetcher)
+
+ // Initially there's set flag to silence all desktop notifications so
+ // that there won't spam of them when user just opened up the FE.
+ // We reset that flag after a while to show new notifications once again.
+ setTimeout(() => commit('setNotificationsSilence', false), 10000)
+ },
+ async fetchOlderNotifications ({ rootState, commit, dispatch }) {
+ const store = { state: rootState, commit, dispatch }
+ commit('setNotificationsLoading', true)
+ const notifications = await fetchAndUpdate(store, true)
+ if (notifications && notifications.length === 0) {
+ commit('setNotificationsBottomedOut', true)
+ }
+ commit('setNotificationsLoading', false)
+ },
+ addNewNotifications ({ state, rootState, commit }, { notifications }) {
+ if ('Notification' in window && window.Notification.permission === 'granted' && !state.desktopNotificationSilence) {
+ const visibleNotificationTypes = getNotificationVisibleTypes(rootState.config.notificationVisibility)
+ each(notifications, (notification) => {
+ // Only show a new notification
+ if (!state.notifications.hasOwnProperty(notification.id) && !notification.seen && visibleNotificationTypes.includes(notification.type)) {
+ showDesktopPushNotification(notification)
+ }
+ })
+ }
+
const newUsers = map(notifications, 'account')
commit('addNewUsers', newUsers)
- commit('addNewNotificationsTwo', notifications)
- const newNotificationIds = map(notifications, 'id')
- const notificationIds = uniq([...newNotificationIds, ...state.visibleNotificationIds])
- commit('setVisibleNotifications', { notificationIds })
+ commit('addNewNotifications', notifications)
+ },
+ async markNotificationsAsSeen ({ rootState, commit, dispatch }) {
+ const store = { state: rootState, commit, dispatch }
+ await Notifications.markAsSeen({ store })
+ commit('markNotificationsAsSeen')
+ },
+ stopFetchingNotifications ({ state, commit }) {
+ clearInterval(state.fetcher)
+ commit('setNotificationsFetcher', undefined)
}
}
}
export default notifications
diff --git a/src/services/new_api/notifications.js b/src/services/new_api/notifications.js
index 57c4fcb4c0..080c9c7725 100644
--- a/src/services/new_api/notifications.js
+++ b/src/services/new_api/notifications.js
@@ -1,18 +1,21 @@
import utils from './utils.js'
import parseLinkHeader from 'parse-link-header'
const Notifications = {
async all ({ store, params = {} }) {
const data = await utils.request({
store,
url: '/api/v1/notifications',
params
})
const notifications = await data.json()
const links = parseLinkHeader(data.headers.get('link'))
return { notifications, links }
+ },
+ async markAsSeen ({ store }) {
+ // TODO: Implement This
}
}
export default Notifications
diff --git a/src/services/notification_helper/notification_helper.js b/src/services/notification_helper/notification_helper.js
new file mode 100644
index 0000000000..b85c30413a
--- /dev/null
+++ b/src/services/notification_helper/notification_helper.js
@@ -0,0 +1,42 @@
+import identity from 'lodash/identity'
+import i18n from '../../i18n/i18n'
+
+export const getNotificationVisibleTypes = (notificationVisibilitySetting) => {
+ return [
+ notificationVisibilitySetting.likes && 'favourite',
+ notificationVisibilitySetting.mentions && 'mention',
+ notificationVisibilitySetting.repeats && 'reblog',
+ notificationVisibilitySetting.follows && 'follow'
+ ].filter(identity)
+}
+
+export const showDesktopPushNotification = (notificationData) => {
+ const status = notificationData.status
+ const title = notificationData.account['display_name']
+ const notifObj = {
+ icon: notificationData.account.avatar,
+ body: generateNotificationDescription(notificationData)
+ }
+
+ // Shows the first attached non-nsfw image, if any. Should add configuration for this somehow...
+ if (status['media_attachments'] && status['media_attachments'].length > 0 && !status.sensitive && status['media_attachments'][0].type.startsWith('image/')) {
+ notifObj.image = status['media_attachments'][0].url
+ }
+
+ const notification = new window.Notification(title, notifObj)
+ // Chrome is known for not closing notifications automatically according to MDN, anyway.
+ setTimeout(notification.close.bind(notification), 5000)
+}
+
+function generateNotificationDescription (notification) {
+ switch (notification.type) {
+ case 'favourite':
+ return i18n.t('notifications.favorited_you')
+ case 'reblog':
+ return i18n.t('notifications.repeated_you')
+ case 'follow':
+ return i18n.t('notifications.followed_you')
+ default:
+ return notification.status.content && notification.status.content.replace(/(<([^>]+)>)/ig, '')
+ }
+}
diff --git a/src/services/notification_utils/notification_utils.js b/src/services/notification_utils/notification_utils.js
deleted file mode 100644
index cd8f3f9efd..0000000000
--- a/src/services/notification_utils/notification_utils.js
+++ /dev/null
@@ -1,36 +0,0 @@
-import { filter, sortBy } from 'lodash'
-
-export const notificationsFromStore = store => store.state.statuses.notifications.data
-
-export const visibleTypes = store => ([
- store.state.config.notificationVisibility.likes && 'like',
- store.state.config.notificationVisibility.mentions && 'mention',
- store.state.config.notificationVisibility.repeats && 'repeat',
- store.state.config.notificationVisibility.follows && 'follow'
-].filter(_ => _))
-
-const sortById = (a, b) => {
- const seqA = Number(a.action.id)
- const seqB = Number(b.action.id)
- const isSeqA = !Number.isNaN(seqA)
- const isSeqB = !Number.isNaN(seqB)
- if (isSeqA && isSeqB) {
- return seqA > seqB ? -1 : 1
- } else if (isSeqA && !isSeqB) {
- return 1
- } else if (!isSeqA && isSeqB) {
- return -1
- } else {
- return a.action.id > b.action.id ? -1 : 1
- }
-}
-
-export const visibleNotificationsFromStore = store => {
- // map is just to clone the array since sort mutates it and it causes some issues
- let sortedNotifications = notificationsFromStore(store).map(_ => _).sort(sortById)
- sortedNotifications = sortBy(sortedNotifications, 'seen')
- return sortedNotifications.filter((notification) => visibleTypes(store).includes(notification.type))
-}
-
-export const unseenNotificationsFromStore = store =>
- filter(visibleNotificationsFromStore(store), ({seen}) => !seen)
diff --git a/src/services/notifications_fetcher/notifications_fetcher.service.js b/src/services/notifications_fetcher/notifications_fetcher.service.js
deleted file mode 100644
index 42db803577..0000000000
--- a/src/services/notifications_fetcher/notifications_fetcher.service.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import Notifications from '../new_api/notifications.js'
-
-const NotificationsFetcher = {
- async create (store) {
- const { notifications, links } = await Notifications.all({ store })
- console.log(links)
- store.dispatch('addNewNotificationsTwo', { notifications })
- }
-}
-
-export default NotificationsFetcher
diff --git a/src/services/timeline_fetcher/timeline_fetcher.service.js b/src/services/timeline_fetcher/timeline_fetcher.service.js
index 4a664d1e19..9e602e9480 100644
--- a/src/services/timeline_fetcher/timeline_fetcher.service.js
+++ b/src/services/timeline_fetcher/timeline_fetcher.service.js
@@ -1,89 +1,89 @@
import Timelines from '../new_api/timelines.js'
import Users from '../new_api/users.js'
const streamTimeline = ({ timelineName, store }) => {
const rootState = store.rootState || store.state
const timelines = {
publicAndExternal: 'public',
public: 'public:local',
home: 'user'
}
let url = `${rootState.instance.server}/api/v1/streaming?stream=${timelines[timelineName]}`.replace('http', 'ws')
let status = ''
if (rootState.oauth.token) {
url = `${url}&access_token=${rootState.oauth.token}`
}
let socket = null
const stop = () => socket.close()
const connect = () => {
status = ''
socket = new window.WebSocket(url)
socket.addEventListener('message', (event) => {
if (event.data === '') { return }
const data = JSON.parse(event.data)
console.log(data.event)
if (data.event === 'update') {
const status = JSON.parse(data.payload)
store.dispatch('addNewStatusesToTimeline', { statuses: [status], timelineName })
}
if (data.event === 'notification') {
const notification = JSON.parse(data.payload)
- store.dispatch('addNewNotificationsTwo', { notifications: [notification] })
+ store.dispatch('addNewNotifications', { notifications: [notification] })
}
})
socket.onopen = () => {
status = 'connected'
}
socket.onclose = () => {
status = 'closed'
}
}
const getStatus = () => (status)
return {
connect,
stop,
getStatus
}
}
const TimelineFetcher = {
async create (store, { type, params = {}, timelineName }) {
// Initial fetch, directly
let tf
switch (type) {
case 'public':
tf = Timelines.public
break
case 'user':
tf = Users.statuses
break
case 'home':
tf = Timelines.home
break
}
const { statuses, links } = await tf({ store, params })
store.dispatch('addNewStatusesToTimeline', { statuses, timelineName, showImmediately: true })
store.commit('setPrevLinkForTimeline', { link: links.prev, timelineName })
store.commit('setNextLinkForTimeline', { link: links.next, timelineName })
// Streaming, reactivate later
const socket = streamTimeline({ store, timelineName })
console.log(socket)
socket.connect()
// Next fetch uses the link headers
const fetcher = async () => {
store.dispatch('fetchPrevForTimeline', { timelineName })
}
return setInterval(fetcher, 10000)
}
}
export default TimelineFetcher
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Aug 8, 10:40 AM (1 d, 7 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1722118
Default Alt Text
(26 KB)
Attached To
Mode
rPUFE pleroma-fe-upstream
Attached
Detach File
Event Timeline
Log In to Comment