Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F85830439
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Authored By
Unknown
Size
10 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/src/components/timeline/timeline.js b/src/components/timeline/timeline.js
index 433bca11a6..113455f410 100644
--- a/src/components/timeline/timeline.js
+++ b/src/components/timeline/timeline.js
@@ -1,18 +1,31 @@
import Status from '../status/status.vue'
+import timelineFetcher from '../../services/timeline_fetcher/timeline_fetcher.service.js'
const Timeline = {
props: [
'timeline',
'timelineName'
],
components: {
Status
},
methods: {
showNewStatuses () {
this.$store.commit('showNewStatuses', { timeline: this.timelineName })
+ },
+ fetchOlderStatuses () {
+ const store = this.$store
+ const credentials = store.state.users.currentUser.credentials
+ store.commit('setLoading', { timeline: this.timelineName, value: true });
+ timelineFetcher.fetchAndUpdate({
+ store,
+ credentials,
+ timeline: this.timelineName,
+ older: true,
+ showImmediately: true
+ }).then(() => store.commit('setLoading', { timeline: this.timelineName, value: false }))
}
}
}
export default Timeline
diff --git a/src/components/timeline/timeline.vue b/src/components/timeline/timeline.vue
index 1e779638b8..2f1b8c287f 100644
--- a/src/components/timeline/timeline.vue
+++ b/src/components/timeline/timeline.vue
@@ -1,19 +1,26 @@
<template>
<div class="timeline">
<a href="#" v-on:click.prevent='showNewStatuses()' v-if="timeline.newStatusCount > 0">
<div class="new-status-notification">
<p class="text-center" >
{{timeline.newStatusCount}} new statuses
</p>
</div>
</a>
<status v-for="status in timeline.visibleStatuses" :key="status.id" v-bind:statusoid="status"></status>
+ <a href="#" v-on:click.prevent='fetchOlderStatuses()' v-if="!timeline.loading">
+ <div class="new-status-notification">
+ <p class="text-center" >
+ Load older statuses.
+ </p>
+ </div>
+ </a>
</div>
</template>
<script src="./timeline.js"></script>
<style>
.timeline.panel {
flex: 1;
}
</style>
diff --git a/src/modules/statuses.js b/src/modules/statuses.js
index c3692ae723..5fb57a4fc9 100644
--- a/src/modules/statuses.js
+++ b/src/modules/statuses.js
@@ -1,154 +1,161 @@
import { map, slice, last, intersectionBy, sortBy, unionBy, toInteger, groupBy, differenceBy, each, find } from 'lodash'
import moment from 'moment'
import apiService from '../services/api/api.service.js'
const defaultState = {
allStatuses: [],
maxId: 0,
timelines: {
public: {
statuses: [],
faves: [],
visibleStatuses: [],
newStatusCount: 0,
maxId: 0,
- minVisibleId: 0
+ minVisibleId: 0,
+ loading: false
},
publicAndExternal: {
statuses: [],
faves: [],
visibleStatuses: [],
newStatusCount: 0,
maxId: 0,
- minVisibleId: 0
+ minVisibleId: 0,
+ loading: false
},
friends: {
statuses: [],
faves: [],
visibleStatuses: [],
newStatusCount: 0,
maxId: 0,
- minVisibleId: 0
+ minVisibleId: 0,
+ loading: false
}
}
}
const statusType = (status) => {
return !status.is_post_verb && status.uri.match(/fave/) ? 'fave' : 'status'
}
-const addStatusesToTimeline = (addedStatuses, showImmediately, { statuses, visibleStatuses, newStatusCount, faves }) => {
+const addStatusesToTimeline = (addedStatuses, showImmediately, { statuses, visibleStatuses, newStatusCount, faves, loading }) => {
const statusesAndFaves = groupBy(addedStatuses, statusType)
const addedFaves = statusesAndFaves['fave'] || []
const unseenFaves = differenceBy(addedFaves, faves, 'id')
// Update fave count
each(unseenFaves, ({in_reply_to_status_id}) => {
const status = find(statuses, { id: toInteger(in_reply_to_status_id) })
if (status) {
status.fave_num += 1
}
})
addedStatuses = statusesAndFaves['status'] || []
// Add some html and nsfw to the statuses.
each(addedStatuses, (status) => {
const statusoid = status.retweeted_status || status
statusoid.created_at_parsed = statusoid.created_at
if (statusoid.parsedText === undefined) {
// statusoid.parsedText = statusParserService.parse(statusoid)
statusoid.parsedText = statusoid.text
}
if (statusoid.nsfw === undefined) {
const nsfwRegex = /#nsfw/i
statusoid.nsfw = statusoid.text.match(nsfwRegex)
}
})
const newStatuses = sortBy(
unionBy(addedStatuses, statuses, 'id'),
({id}) => -id
)
let newNewStatusCount = newStatusCount + (newStatuses.length - statuses.length)
let newVisibleStatuses = visibleStatuses
if (showImmediately) {
newVisibleStatuses = unionBy(addedStatuses, newVisibleStatuses, 'id')
newVisibleStatuses = sortBy(newVisibleStatuses, ({id}) => -id)
newNewStatusCount = newStatusCount
};
newVisibleStatuses = intersectionBy(newStatuses, newVisibleStatuses, 'id')
return {
statuses: newStatuses,
visibleStatuses: newVisibleStatuses,
newStatusCount: newNewStatusCount,
maxId: newStatuses[0].id,
minVisibleId: (last(newVisibleStatuses) || { id: undefined }).id,
- faves: unionBy(faves, addedFaves, 'id')
+ faves: unionBy(faves, addedFaves, 'id'),
+ loading
}
}
const updateTimestampsInStatuses = (statuses) => {
return map(statuses, (statusoid) => {
const status = statusoid.retweeted_status || statusoid
// Parse date
status.created_at_parsed = moment(status.created_at).fromNow()
return status
})
}
const statuses = {
state: defaultState,
actions: {
favorite ({ rootState, commit }, status) {
// Optimistic favoriting...
commit('setFavorited', { status, value: true })
apiService.favorite({ id: status.id, credentials: rootState.users.currentUser.credentials })
},
unfavorite ({ rootState, commit }, status) {
// Optimistic favoriting...
commit('setFavorited', { status, value: false })
apiService.unfavorite({ id: status.id, credentials: rootState.users.currentUser.credentials })
}
},
mutations: {
addNewStatuses (state, { statuses, showImmediately = false, timeline }) {
state.timelines[timeline] = addStatusesToTimeline(statuses, showImmediately, state.timelines[timeline])
state.allStatuses = unionBy(state.timelines[timeline].statuses, state.allStatuses.id)
},
showNewStatuses (state, { timeline }) {
const oldTimeline = (state.timelines[timeline])
oldTimeline.newStatusCount = 0
oldTimeline.visibleStatuses = slice(oldTimeline.statuses, 0, 50)
},
updateTimestamps (state) {
updateTimestampsInStatuses(state.allStatuses)
},
setFavorited (state, { status, value }) {
const newStatus = find(state.allStatuses, status)
newStatus.favorited = value
},
+ setLoading (state, { timeline, value }) {
+ state.timelines[timeline].loading = value
+ },
setNsfw (state, { id, nsfw }) {
// For now, walk through all the statuses because the stuff might be in the replied_to_status
// TODO: Save the replied_tos as references.
each(state.allStatuses, (statusoid) => {
const status = statusoid.retweeted_status || statusoid
if (status.id === id) {
status.nsfw = nsfw
}
})
}
}
}
export default statuses
diff --git a/src/services/timeline_fetcher/timeline_fetcher.service.js b/src/services/timeline_fetcher/timeline_fetcher.service.js
index a3d9b9d10c..8a39eeb50a 100644
--- a/src/services/timeline_fetcher/timeline_fetcher.service.js
+++ b/src/services/timeline_fetcher/timeline_fetcher.service.js
@@ -1,93 +1,95 @@
import { camelCase } from 'lodash'
import apiService from '../api/api.service.js'
const update = ({store, statuses, timeline, showImmediately}) => {
const ccTimeline = camelCase(timeline)
store.commit('addNewStatuses', {
timeline: ccTimeline,
statuses,
showImmediately
})
store.commit('updateTimestamps')
}
const fetchAndUpdate = ({store, credentials, timeline = 'friends', older = false, showImmediately = false}) => {
const args = { timeline, credentials }
- const timelineData = store.rootState.statuses.timelines[camelCase(timeline)]
+ const rootState = store.rootState || store.state
+ const timelineData = rootState.statuses.timelines[camelCase(timeline)]
if (older) {
args['until'] = timelineData.minVisibleId
} else {
args['since'] = timelineData.maxId
}
- apiService.fetchTimeline(args)
+ return apiService.fetchTimeline(args)
.then((statuses) => update({store, statuses, timeline, showImmediately}))
}
const startFetching = ({ timeline = 'friends', credentials, store }) => {
fetchAndUpdate({timeline, credentials, store, showImmediately: true})
const boundFetchAndUpdate = () => fetchAndUpdate({ timeline, credentials, store })
setInterval(boundFetchAndUpdate, 10000)
}
const timelineFetcher = {
+ fetchAndUpdate,
startFetching
}
export default timelineFetcher
// const timelineFetcherServiceFactory = ($ngRedux, apiService, $interval) => {
// let fetcher;
// const update = ({statuses, timeline, showImmediately}) => {
// const ccTimeline = camelCase(timeline);
// const action = {
// type: 'ADD_NEW_STATUSES',
// data: {
// statuses,
// timeline: ccTimeline,
// showImmediately
// }
// };
// $ngRedux.dispatch(action);
// $ngRedux.dispatch({type: 'UPDATE_TIMESTAMPS'});
// };
// const fetchAndUpdate = ({timeline = 'friends', older = false, showImmediately = false}) => {
// const args = { timeline };
// const timelineData = $ngRedux.getState().statuses.timelines[camelCase(timeline)];
// if(older) {
// args['until'] = timelineData.minVisibleId;
// } else {
// args['since'] = timelineData.maxId;
// }
// apiService.fetchTimeline(args).
// then((statuses) => update({statuses, timeline, showImmediately}));
// };
// const startFetching = ({timeline = 'friends'}) => {
// fetchAndUpdate({timeline, showImmediately: true});
// const boundFetchAndUpdate = () => fetchAndUpdate({timeline});
// fetcher = $interval(boundFetchAndUpdate, 10000);
// };
// const timelineFetcherService = {
// startFetching,
// fetchAndUpdate
// };
// return timelineFetcherService;
// };
// timelineFetcherServiceFactory.$inject = ['$ngRedux', 'apiService', '$interval'];
// export default timelineFetcherServiceFactory;
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sun, Nov 1, 4:34 AM (16 h, 57 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1802446
Default Alt Text
(10 KB)
Attached To
Mode
rPUFE pleroma-fe-upstream
Attached
Detach File
Event Timeline