From 1e4e2e38b4b1e80df4cf0e32787d08ce8be438f4 Mon Sep 17 00:00:00 2001 From: Roger Braun Date: Sun, 4 Jun 2017 15:22:41 +0200 Subject: [PATCH] First steps for user timeline. --- src/components/timeline/timeline.js | 33 ++++++++++--------- .../user_card_content/user_card_content.vue | 11 ++++--- src/components/user_profile/user_profile.js | 33 ++++++++++++++++--- src/components/user_profile/user_profile.vue | 7 ++-- src/services/api/api.service.js | 31 +++++++++++++---- .../backend_interactor_service.js | 4 ++- .../timeline_fetcher.service.js | 18 +++++++--- 7 files changed, 100 insertions(+), 37 deletions(-) diff --git a/src/components/timeline/timeline.js b/src/components/timeline/timeline.js index 7aaa81c808..f7657a1324 100644 --- a/src/components/timeline/timeline.js +++ b/src/components/timeline/timeline.js @@ -21,13 +21,14 @@ const Timeline = { const showImmediately = this.timeline.visibleStatuses.length === 0 window.onscroll = this.scrollLoad - - timelineFetcher.fetchAndUpdate({ - store, - credentials, - timeline: this.timelineName, - showImmediately - }) + if (this.timelineName !== 'user') { + timelineFetcher.fetchAndUpdate({ + store, + credentials, + timeline: this.timelineName, + showImmediately + }) + } }, methods: { showNewStatuses () { @@ -36,14 +37,16 @@ const Timeline = { 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 })) + if (this.timelineName !== 'user') { + 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 })) + } }, scrollLoad (e) { let height = Math.max(document.body.offsetHeight, document.body.scrollHeight) diff --git a/src/components/user_card_content/user_card_content.vue b/src/components/user_card_content/user_card_content.vue index bba1658496..ff1b108c57 100644 --- a/src/components/user_card_content/user_card_content.vue +++ b/src/components/user_card_content/user_card_content.vue @@ -61,10 +61,13 @@ props: [ 'user' ], computed: { headingStyle () { - let rgb = this.$store.state.config.colors['base00'].match(/\d+/g) - return { - backgroundColor: `rgb(${Math.floor(rgb[0] * 0.53)}, ${Math.floor(rgb[1] * 0.56)}, ${Math.floor(rgb[2] * 0.59)})`, - backgroundImage: `url(${this.user.cover_photo})` + let color = this.$store.state.config.colors['base00'] + if (color) { + let rgb = this.$store.state.config.colors['base00'].match(/\d+/g) + return { + backgroundColor: `rgb(${Math.floor(rgb[0] * 0.53)}, ${Math.floor(rgb[1] * 0.56)}, ${Math.floor(rgb[2] * 0.59)})`, + backgroundImage: `url(${this.user.cover_photo})` + } } }, bodyStyle () { diff --git a/src/components/user_profile/user_profile.js b/src/components/user_profile/user_profile.js index 4d52bc95fa..3fc4348e09 100644 --- a/src/components/user_profile/user_profile.js +++ b/src/components/user_profile/user_profile.js @@ -1,16 +1,39 @@ import UserCardContent from '../user_card_content/user_card_content.vue' -import { find } from 'lodash' +import Timeline from '../timeline/timeline.vue' +import timelineFetcher from '../../services/timeline_fetcher/timeline_fetcher.service.js' const UserProfile = { + data: () => ({timeline: { visibleStatuses: [] }}), + created () { + this.$store.state.api.backendInteractor.getUser(this.userId) + .then((user) => { + if (!user.error) { + this.$store.commit('addNewUsers', [user]) + } + }) + const store = this.$store + const credentials = store.state.users.currentUser.credentials + const timelineData = this.timeline + timelineFetcher.fetchStatuses({ + timelineData, + credentials, + timeline: 'user', + userId: this.userId + }).then((data) => { + this.timeline.visibleStatuses = data + }) + }, computed: { + userId () { + return parseInt(this.$route.params.id) + }, user () { - const id = this.$route.params.id - const user = find(this.$store.state.users.users, {id}) - return user + return this.$store.state.users.usersObject[this.userId] } }, components: { - UserCardContent + UserCardContent, + Timeline } } diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue index 11a61bfc95..a854cd0d7f 100644 --- a/src/components/user_profile/user_profile.vue +++ b/src/components/user_profile/user_profile.vue @@ -1,6 +1,9 @@ diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js index 1c5e281efe..cef135ae77 100644 --- a/src/services/api/api.service.js +++ b/src/services/api/api.service.js @@ -4,6 +4,7 @@ const FRIENDS_TIMELINE_URL = '/api/statuses/friends_timeline.json' const ALL_FOLLOWING_URL = '/api/qvitter/allfollowing' const PUBLIC_TIMELINE_URL = '/api/statuses/public_timeline.json' const PUBLIC_AND_EXTERNAL_TIMELINE_URL = '/api/statuses/public_and_external_timeline.json' +const USER_TIMELINE_URL = '/api/statuses/user_timeline.json' const FAVORITE_URL = '/api/favorites/create' const UNFAVORITE_URL = '/api/favorites/destroy' const RETWEET_URL = '/api/statuses/retweet' @@ -18,7 +19,7 @@ const FOLLOWING_URL = '/api/friendships/create.json' const UNFOLLOWING_URL = '/api/friendships/destroy.json' const QVITTER_USER_PREF_URL = '/api/qvitter/set_profile_pref.json' const EXTERNAL_PROFILE_URL = '/api/externalprofile/show.json' -// const USER_URL = '/api/users/show.json' +const USER_URL = '/api/users/show.json' const oldfetch = window.fetch @@ -43,6 +44,14 @@ const externalProfile = (profileUrl) => { }).then((data) => data.json()) } +const getUser = ({id, credentials}) => { + let url = `${USER_URL}?user_id=${id}` + return fetch(url, { + headers: authHeaders(credentials), + method: 'GET' + }).then((data) => data.json()) +} + const followUser = ({id, credentials}) => { let url = `${FOLLOWING_URL}?user_id=${id}` return fetch(url, { @@ -98,24 +107,33 @@ const setUserMute = ({id, credentials, muted = true}) => { }) } -const fetchTimeline = ({timeline, credentials, since = false, until = false}) => { +const fetchTimeline = ({timeline, credentials, since = false, until = false, userId = false}) => { const timelineUrls = { public: PUBLIC_TIMELINE_URL, friends: FRIENDS_TIMELINE_URL, mentions: MENTIONS_URL, - 'publicAndExternal': PUBLIC_AND_EXTERNAL_TIMELINE_URL + 'publicAndExternal': PUBLIC_AND_EXTERNAL_TIMELINE_URL, + user: USER_TIMELINE_URL } let url = timelineUrls[timeline] + let params = [] if (since) { - url += `?since_id=${since}` + params.push(['since_id', since]) } if (until) { - url += `?max_id=${until}` + params.push(['max_id', until]) } + if (userId) { + params.push(['user_id', userId]) + } + + const queryString = new URLSearchParams(params).toString() + url += `?${queryString}` + return fetch(url, { headers: authHeaders(credentials) }).then((data) => data.json()) } @@ -207,7 +225,8 @@ const apiService = { fetchAllFollowing, setUserMute, fetchMutes, - externalProfile + externalProfile, + getUser } export default apiService diff --git a/src/services/backend_interactor_service/backend_interactor_service.js b/src/services/backend_interactor_service/backend_interactor_service.js index 74248bc084..aa2219c176 100644 --- a/src/services/backend_interactor_service/backend_interactor_service.js +++ b/src/services/backend_interactor_service/backend_interactor_service.js @@ -37,6 +37,7 @@ const backendInteractorService = (credentials) => { const fetchMutes = () => apiService.fetchMutes({credentials}) const externalProfile = (profileUrl) => apiService.externalProfile(profileUrl) + const getUser = (id) => apiService.getUser({credentials, id}) const backendInteractorServiceInstance = { fetchStatus, @@ -49,7 +50,8 @@ const backendInteractorService = (credentials) => { startFetching, setUserMute, fetchMutes, - externalProfile + externalProfile, + getUser } return backendInteractorServiceInstance diff --git a/src/services/timeline_fetcher/timeline_fetcher.service.js b/src/services/timeline_fetcher/timeline_fetcher.service.js index 24aef06925..76e62de5de 100644 --- a/src/services/timeline_fetcher/timeline_fetcher.service.js +++ b/src/services/timeline_fetcher/timeline_fetcher.service.js @@ -15,19 +15,28 @@ const update = ({store, statuses, timeline, showImmediately}) => { } const fetchAndUpdate = ({store, credentials, timeline = 'friends', older = false, showImmediately = false}) => { - const args = { timeline, credentials } const rootState = store.rootState || store.state const timelineData = rootState.statuses.timelines[camelCase(timeline)] + return fetchStatuses({timelineData, store, credentials, timeline, older}) + .then((statuses) => update({store, statuses, timeline, showImmediately}), + () => store.dispatch('setError', { value: true })) +} + +const fetchStatuses = ({timelineData, credentials, timeline = 'friends', older = false, userId = false}) => { + const args = { timeline, credentials } + if (older) { args['until'] = timelineData.minVisibleId } else { args['since'] = timelineData.maxId } + if (timeline === 'user') { + args['userId'] = userId + } + return apiService.fetchTimeline(args) - .then((statuses) => update({store, statuses, timeline, showImmediately}), - () => store.dispatch('setError', { value: true })) } const startFetching = ({ timeline = 'friends', credentials, store }) => { @@ -37,7 +46,8 @@ const startFetching = ({ timeline = 'friends', credentials, store }) => { } const timelineFetcher = { fetchAndUpdate, - startFetching + startFetching, + fetchStatuses } export default timelineFetcher