some initial work to make it possible to use "unregistered" timelines, i.e. not

reserving a timeline by name, instead just passing timeline object itself.
This commit is contained in:
Henry Jameson 2019-01-12 23:33:45 +03:00
parent 1fb9ceb59b
commit 039a407400
7 changed files with 43 additions and 31 deletions

View file

@ -7,7 +7,6 @@ import { throttle } from 'lodash'
const Timeline = { const Timeline = {
props: [ props: [
'timeline', 'timeline',
'timelineName',
'title', 'title',
'userId', 'userId',
'tag', 'tag',
@ -55,7 +54,7 @@ const Timeline = {
timelineFetcher.fetchAndUpdate({ timelineFetcher.fetchAndUpdate({
store, store,
credentials, credentials,
timeline: this.timelineName, timeline: this.timeline,
showImmediately, showImmediately,
userId: this.userId, userId: this.userId,
tag: this.tag tag: this.tag
@ -70,32 +69,32 @@ const Timeline = {
destroyed () { destroyed () {
window.removeEventListener('scroll', this.scrollLoad) window.removeEventListener('scroll', this.scrollLoad)
if (typeof document.hidden !== 'undefined') document.removeEventListener('visibilitychange', this.handleVisibilityChange, false) if (typeof document.hidden !== 'undefined') document.removeEventListener('visibilitychange', this.handleVisibilityChange, false)
this.$store.commit('setLoading', { timeline: this.timelineName, value: false }) this.$store.commit('setLoading', { timeline: this.timeline, value: false })
}, },
methods: { methods: {
showNewStatuses () { showNewStatuses () {
if (this.timeline.flushMarker !== 0) { if (this.timeline.flushMarker !== 0) {
this.$store.commit('clearTimeline', { timeline: this.timelineName }) this.$store.commit('clearTimeline', { timeline: this.timeline })
this.$store.commit('queueFlush', { timeline: this.timelineName, id: 0 }) this.$store.commit('queueFlush', { timeline: this.timeline, id: 0 })
this.fetchOlderStatuses() this.fetchOlderStatuses()
} else { } else {
this.$store.commit('showNewStatuses', { timeline: this.timelineName }) this.$store.commit('showNewStatuses', { timeline: this.timeline })
this.paused = false this.paused = false
} }
}, },
fetchOlderStatuses: throttle(function () { fetchOlderStatuses: throttle(function () {
const store = this.$store const store = this.$store
const credentials = store.state.users.currentUser.credentials const credentials = store.state.users.currentUser.credentials
store.commit('setLoading', { timeline: this.timelineName, value: true }) store.commit('setLoading', { timeline: this.timeline, value: true })
timelineFetcher.fetchAndUpdate({ timelineFetcher.fetchAndUpdate({
store, store,
credentials, credentials,
timeline: this.timelineName, timeline: this.timeline,
older: true, older: true,
showImmediately: true, showImmediately: true,
userId: this.userId, userId: this.userId,
tag: this.tag tag: this.tag
}).then(() => store.commit('setLoading', { timeline: this.timelineName, value: false })) }).then(() => store.commit('setLoading', { timeline: this.timeline, value: false }))
}, 1000, this), }, 1000, this),
scrollLoad (e) { scrollLoad (e) {
const bodyBRect = document.body.getBoundingClientRect() const bodyBRect = document.body.getBoundingClientRect()

View file

@ -1,6 +1,7 @@
import UserCardContent from '../user_card_content/user_card_content.vue' import UserCardContent from '../user_card_content/user_card_content.vue'
import UserCard from '../user_card/user_card.vue' import UserCard from '../user_card/user_card.vue'
import Timeline from '../timeline/timeline.vue' import Timeline from '../timeline/timeline.vue'
import { emptyTl } from '../../modules/statuses.js'
const UserProfile = { const UserProfile = {
created () { created () {
@ -13,6 +14,11 @@ const UserProfile = {
destroyed () { destroyed () {
this.$store.dispatch('stopFetching', 'user') this.$store.dispatch('stopFetching', 'user')
}, },
data () {
return {
favorites: emptyTl({ type: 'favorites', userId: this.userId })
}
},
computed: { computed: {
timeline () { timeline () {
return this.$store.state.statuses.timelines.user return this.$store.state.statuses.timelines.user

View file

@ -20,6 +20,7 @@
<i class="icon-spin3 animate-spin"></i> <i class="icon-spin3 animate-spin"></i>
</div> </div>
</div> </div>
<Timeline :label="$t('user_card.favorites')" :embedded="true" :title="$t('user_profile.favorites_title')" :timeline="favorites"/>
</tab-switcher> </tab-switcher>
</div> </div>
<div v-else class="panel user-profile-placeholder"> <div v-else class="panel user-profile-placeholder">

View file

@ -5,7 +5,7 @@ import { Socket } from 'phoenix'
const api = { const api = {
state: { state: {
backendInteractor: backendInteractorService(), backendInteractor: backendInteractorService(),
fetchers: {}, fetchers: new Map(),
socket: null, socket: null,
chatDisabled: false, chatDisabled: false,
followRequests: [] followRequests: []
@ -15,10 +15,10 @@ const api = {
state.backendInteractor = backendInteractor state.backendInteractor = backendInteractor
}, },
addFetcher (state, {timeline, fetcher}) { addFetcher (state, {timeline, fetcher}) {
state.fetchers[timeline] = fetcher state.fetchers.set(timeline, fetcher)
}, },
removeFetcher (state, {timeline}) { removeFetcher (state, {timeline}) {
delete state.fetchers[timeline] delete state.fetchers.delete(timeline)
}, },
setSocket (state, socket) { setSocket (state, socket) {
state.socket = socket state.socket = socket
@ -41,13 +41,13 @@ const api = {
} }
// Don't start fetching if we already are. // Don't start fetching if we already are.
if (!store.state.fetchers[timeline]) { if (!store.state.fetchers.has(timeline)) {
const fetcher = store.state.backendInteractor.startFetching({timeline, store, userId}) const fetcher = store.state.backendInteractor.startFetching({timeline, store, userId})
store.commit('addFetcher', {timeline, fetcher}) store.commit('addFetcher', {timeline, fetcher})
} }
}, },
stopFetching (store, timeline) { stopFetching (store, timeline) {
const fetcher = store.state.fetchers[timeline] const fetcher = store.state.fetchers.get(timeline)
window.clearInterval(fetcher) window.clearInterval(fetcher)
store.commit('removeFetcher', {timeline}) store.commit('removeFetcher', {timeline})
}, },

View file

@ -2,7 +2,7 @@ import { includes, remove, slice, sortBy, toInteger, each, find, flatten, maxBy,
import apiService from '../services/api/api.service.js' import apiService from '../services/api/api.service.js'
// import parse from '../services/status_parser/status_parser.js' // import parse from '../services/status_parser/status_parser.js'
const emptyTl = () => ({ export const emptyTl = (tl) => (Object.assign(tl, {
statuses: [], statuses: [],
statusesObject: {}, statusesObject: {},
faves: [], faves: [],
@ -16,7 +16,7 @@ const emptyTl = () => ({
friends: [], friends: [],
userId: 0, userId: 0,
flushMarker: 0 flushMarker: 0
}) }))
export const defaultState = { export const defaultState = {
allStatuses: [], allStatuses: [],
@ -33,13 +33,13 @@ export const defaultState = {
favorites: new Set(), favorites: new Set(),
error: false, error: false,
timelines: { timelines: {
mentions: emptyTl(), mentions: emptyTl({ type: 'mentions' }),
public: emptyTl(), public: emptyTl({ type: 'public' }),
user: emptyTl(), user: emptyTl({ type: 'user' }), // TODO: switch to unregistered
publicAndExternal: emptyTl(), publicAndExternal: emptyTl({ type: 'publicAndExternal' }),
friends: emptyTl(), friends: emptyTl({ type: 'friends' }),
tag: emptyTl(), tag: emptyTl({ type: 'tag' }),
dms: emptyTl() dms: emptyTl({ type: 'dms' })
} }
} }
@ -137,7 +137,7 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
const allStatuses = state.allStatuses const allStatuses = state.allStatuses
const allStatusesObject = state.allStatusesObject const allStatusesObject = state.allStatusesObject
const timelineObject = state.timelines[timeline] const timelineObject = typeof timeline === 'object' ? timeline : state.timelines[timeline]
const maxNew = statuses.length > 0 ? maxBy(statuses, 'id').id : 0 const maxNew = statuses.length > 0 ? maxBy(statuses, 'id').id : 0
const older = timeline && maxNew < timelineObject.maxId const older = timeline && maxNew < timelineObject.maxId
@ -337,7 +337,7 @@ export const mutations = {
addNewStatuses, addNewStatuses,
addNewNotifications, addNewNotifications,
showNewStatuses (state, { timeline }) { showNewStatuses (state, { timeline }) {
const oldTimeline = (state.timelines[timeline]) const oldTimeline = (typeof timeline === 'object' ? timeline : state.timelines[timeline])
oldTimeline.newStatusCount = 0 oldTimeline.newStatusCount = 0
oldTimeline.visibleStatuses = slice(oldTimeline.statuses, 0, 50) oldTimeline.visibleStatuses = slice(oldTimeline.statuses, 0, 50)
@ -346,7 +346,8 @@ export const mutations = {
each(oldTimeline.visibleStatuses, (status) => { oldTimeline.visibleStatusesObject[status.id] = status }) each(oldTimeline.visibleStatuses, (status) => { oldTimeline.visibleStatusesObject[status.id] = status })
}, },
clearTimeline (state, { timeline }) { clearTimeline (state, { timeline }) {
state.timelines[timeline] = emptyTl() const timelineObject = typeof timeline === 'object' ? timeline : state.timelines[timeline]
emptyTl(timelineObject)
}, },
setFavorited (state, { status, value }) { setFavorited (state, { status, value }) {
const newStatus = state.allStatusesObject[status.id] const newStatus = state.allStatusesObject[status.id]
@ -366,7 +367,8 @@ export const mutations = {
newStatus.deleted = true newStatus.deleted = true
}, },
setLoading (state, { timeline, value }) { setLoading (state, { timeline, value }) {
state.timelines[timeline].loading = value const timelineObject = typeof timeline === 'object' ? timeline : state.timelines[timeline]
timelineObject.loading = value
}, },
setNsfw (state, { id, nsfw }) { setNsfw (state, { id, nsfw }) {
const newStatus = state.allStatusesObject[id] const newStatus = state.allStatusesObject[id]
@ -387,7 +389,8 @@ export const mutations = {
}) })
}, },
queueFlush (state, { timeline, id }) { queueFlush (state, { timeline, id }) {
state.timelines[timeline].flushMarker = id const timelineObject = typeof timeline === 'object' ? timeline : state.timelines[timeline]
timelineObject.flushMarker = id
} }
} }

View file

@ -41,6 +41,8 @@ const APPROVE_USER_URL = '/api/pleroma/friendships/approve'
const DENY_USER_URL = '/api/pleroma/friendships/deny' const DENY_USER_URL = '/api/pleroma/friendships/deny'
const SUGGESTIONS_URL = '/api/v1/suggestions' const SUGGESTIONS_URL = '/api/v1/suggestions'
const MASTODON_USER_FAVORITES_TIMELINE_URL = '/api/v1/favourites'
import { each, map } from 'lodash' import { each, map } from 'lodash'
import 'whatwg-fetch' import 'whatwg-fetch'
@ -300,10 +302,11 @@ const fetchTimeline = ({timeline, credentials, since = false, until = false, use
notifications: QVITTER_USER_NOTIFICATIONS_URL, notifications: QVITTER_USER_NOTIFICATIONS_URL,
'publicAndExternal': PUBLIC_AND_EXTERNAL_TIMELINE_URL, 'publicAndExternal': PUBLIC_AND_EXTERNAL_TIMELINE_URL,
user: QVITTER_USER_TIMELINE_URL, user: QVITTER_USER_TIMELINE_URL,
favorites: MASTODON_USER_FAVORITES_TIMELINE_URL,
tag: TAG_TIMELINE_URL tag: TAG_TIMELINE_URL
} }
let url = timelineUrls[timeline] let url = timelineUrls[timeline.type || timeline]
let params = [] let params = []

View file

@ -3,7 +3,7 @@ import { camelCase } from 'lodash'
import apiService from '../api/api.service.js' import apiService from '../api/api.service.js'
const update = ({store, statuses, timeline, showImmediately, userId}) => { const update = ({store, statuses, timeline, showImmediately, userId}) => {
const ccTimeline = camelCase(timeline) const ccTimeline = typeof timeline === 'object' ? timeline : camelCase(timeline)
store.dispatch('setError', { value: false }) store.dispatch('setError', { value: false })
@ -18,7 +18,7 @@ const update = ({store, statuses, timeline, showImmediately, userId}) => {
const fetchAndUpdate = ({store, credentials, timeline = 'friends', older = false, showImmediately = false, userId = false, tag = false, until}) => { const fetchAndUpdate = ({store, credentials, timeline = 'friends', older = false, showImmediately = false, userId = false, tag = false, until}) => {
const args = { timeline, credentials } const args = { timeline, credentials }
const rootState = store.rootState || store.state const rootState = store.rootState || store.state
const timelineData = rootState.statuses.timelines[camelCase(timeline)] const timelineData = typeof timeline === 'object' ? timeline : rootState.statuses.timelines[camelCase(timeline)]
if (older) { if (older) {
args['until'] = until || timelineData.minVisibleId args['until'] = until || timelineData.minVisibleId