From dbe0205a9cc63cd3ecb5e1f754ebf55c27bbca3c Mon Sep 17 00:00:00 2001
From: William Pitcock <nenolod@dereferenced.org>
Date: Thu, 24 Jan 2019 10:47:49 +0000
Subject: [PATCH 1/3] api service: add the ability to fetch a media-only
 timeline

---
 src/services/api/api.service.js | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js
index 776d8dae..5b0d8650 100644
--- a/src/services/api/api.service.js
+++ b/src/services/api/api.service.js
@@ -325,6 +325,7 @@ const fetchTimeline = ({timeline, credentials, since = false, until = false, use
     notifications: QVITTER_USER_NOTIFICATIONS_URL,
     'publicAndExternal': PUBLIC_AND_EXTERNAL_TIMELINE_URL,
     user: QVITTER_USER_TIMELINE_URL,
+    media: QVITTER_USER_TIMELINE_URL,
     favorites: MASTODON_USER_FAVORITES_TIMELINE_URL,
     tag: TAG_TIMELINE_URL
   }
@@ -345,6 +346,9 @@ const fetchTimeline = ({timeline, credentials, since = false, until = false, use
   if (tag) {
     url += `/${tag}.json`
   }
+  if (timeline === 'media') {
+    params.push(['only_media', 1])
+  }
 
   params.push(['count', 20])
 

From 7b296696a3cf83b93b1f8246b114e05dcee4e040 Mon Sep 17 00:00:00 2001
From: William Pitcock <nenolod@dereferenced.org>
Date: Thu, 24 Jan 2019 10:48:40 +0000
Subject: [PATCH 2/3] user profile: add media timeline

---
 src/components/user_profile/user_profile.js  | 12 ++++++++++++
 src/components/user_profile/user_profile.vue |  1 +
 src/i18n/en.json                             |  1 +
 src/modules/statuses.js                      |  1 +
 4 files changed, 15 insertions(+)

diff --git a/src/components/user_profile/user_profile.js b/src/components/user_profile/user_profile.js
index c9197a1c..7414e573 100644
--- a/src/components/user_profile/user_profile.js
+++ b/src/components/user_profile/user_profile.js
@@ -6,8 +6,10 @@ const UserProfile = {
   created () {
     this.$store.commit('clearTimeline', { timeline: 'user' })
     this.$store.commit('clearTimeline', { timeline: 'favorites' })
+    this.$store.commit('clearTimeline', { timeline: 'media' })
     this.$store.dispatch('startFetching', ['user', this.fetchBy])
     this.$store.dispatch('startFetching', ['favorites', this.fetchBy])
+    this.$store.dispatch('startFetching', ['media', this.fetchBy])
     if (!this.user.id) {
       this.$store.dispatch('fetchUser', this.fetchBy)
     }
@@ -15,6 +17,7 @@ const UserProfile = {
   destroyed () {
     this.$store.dispatch('stopFetching', 'user')
     this.$store.dispatch('stopFetching', 'favorites')
+    this.$store.dispatch('stopFetching', 'media')
   },
   computed: {
     timeline () {
@@ -23,6 +26,9 @@ const UserProfile = {
     favorites () {
       return this.$store.state.statuses.timelines.favorites
     },
+    media () {
+      return this.$store.state.statuses.timelines.media
+    },
     userId () {
       return this.$route.params.id || this.user.id
     },
@@ -78,10 +84,13 @@ const UserProfile = {
       }
       this.$store.dispatch('stopFetching', 'user')
       this.$store.dispatch('stopFetching', 'favorites')
+      this.$store.dispatch('stopFetching', 'media')
       this.$store.commit('clearTimeline', { timeline: 'user' })
       this.$store.commit('clearTimeline', { timeline: 'favorites' })
+      this.$store.commit('clearTimeline', { timeline: 'media' })
       this.$store.dispatch('startFetching', ['user', this.fetchBy])
       this.$store.dispatch('startFetching', ['favorites', this.fetchBy])
+      this.$store.dispatch('startFetching', ['media', this.fetchBy])
     },
     userId () {
       if (!this.isExternal) {
@@ -89,10 +98,13 @@ const UserProfile = {
       }
       this.$store.dispatch('stopFetching', 'user')
       this.$store.dispatch('stopFetching', 'favorites')
+      this.$store.dispatch('stopFetching', 'media')
       this.$store.commit('clearTimeline', { timeline: 'user' })
       this.$store.commit('clearTimeline', { timeline: 'favorites' })
+      this.$store.commit('clearTimeline', { timeline: 'media' })
       this.$store.dispatch('startFetching', ['user', this.fetchBy])
       this.$store.dispatch('startFetching', ['favorites', this.fetchBy])
+      this.$store.dispatch('startFetching', ['media', this.fetchBy])
     },
     user () {
       if (this.user.id && !this.user.followers) {
diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue
index d64ce277..74cd9c53 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -20,6 +20,7 @@
           <i class="icon-spin3 animate-spin"></i>
         </div>
       </div>
+      <Timeline :label="$t('user_card.media')" :embedded="true" :title="$t('user_profile.media_title')" timeline-name="media" :timeline="media" :user-id="fetchBy" />
       <Timeline v-if="isUs" :label="$t('user_card.favorites')" :embedded="true" :title="$t('user_profile.favorites_title')" timeline-name="favorites" :timeline="favorites"/>
     </tab-switcher>
   </div>
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 3c29a17e..3ff98ab0 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -335,6 +335,7 @@
     "following": "Following!",
     "follows_you": "Follows you!",
     "its_you": "It's you!",
+    "media": "Media",
     "mute": "Mute",
     "muted": "Muted",
     "per_day": "per day",
diff --git a/src/modules/statuses.js b/src/modules/statuses.js
index 20a8d2eb..3d6ea2f7 100644
--- a/src/modules/statuses.js
+++ b/src/modules/statuses.js
@@ -37,6 +37,7 @@ export const defaultState = {
     public: emptyTl(),
     user: emptyTl(),
     favorites: emptyTl(),
+    media: emptyTl(),
     publicAndExternal: emptyTl(),
     friends: emptyTl(),
     tag: emptyTl(),

From efad3ad0a51273e192590761b905d4db7d76bf71 Mon Sep 17 00:00:00 2001
From: William Pitcock <nenolod@dereferenced.org>
Date: Sat, 26 Jan 2019 13:51:07 +0000
Subject: [PATCH 3/3] attempt to fix tests

---
 .../specs/components/user_profile.spec.js     | 32 +++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/test/unit/specs/components/user_profile.spec.js b/test/unit/specs/components/user_profile.spec.js
index cde39245..41fd9cd0 100644
--- a/test/unit/specs/components/user_profile.spec.js
+++ b/test/unit/specs/components/user_profile.spec.js
@@ -66,6 +66,22 @@ const externalProfileStore = new Vuex.Store({
           viewing: 'statuses',
           userId: 100,
           flushMarker: 0
+        },
+        media: {
+          statuses: [],
+          statusesObject: {},
+          faves: [],
+          visibleStatuses: [],
+          visibleStatusesObject: {},
+          newStatusCount: 0,
+          maxId: 0,
+          minVisibleId: 0,
+          loading: false,
+          followers: [],
+          friends: [],
+          viewing: 'statuses',
+          userId: 100,
+          flushMarker: 0
         }
       }
     },
@@ -116,6 +132,22 @@ const localProfileStore = new Vuex.Store({
           viewing: 'statuses',
           userId: 100,
           flushMarker: 0
+        },
+        media: {
+          statuses: [],
+          statusesObject: {},
+          faves: [],
+          visibleStatuses: [],
+          visibleStatusesObject: {},
+          newStatusCount: 0,
+          maxId: 0,
+          minVisibleId: 0,
+          loading: false,
+          followers: [],
+          friends: [],
+          viewing: 'statuses',
+          userId: 100,
+          flushMarker: 0
         }
       }
     },