diff --git a/CHANGELOG.md b/CHANGELOG.md
index e3387b51..6b209941 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -43,6 +43,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
 - Clicking on non-image/video files no longer opens an empty modal
 - Audio files can now be played back in the frontend with hidden attachments
 - Videos are not cropped awkwardly in the uploads section anymore
+- Reply filtering options in Settings -> Filtering now work again using filtering on server
 
 ## [2.0.3] - 2020-05-02
 ### Fixed
diff --git a/src/components/settings_modal/tabs/filtering_tab.js b/src/components/settings_modal/tabs/filtering_tab.js
index 224a7f47..3b2df556 100644
--- a/src/components/settings_modal/tabs/filtering_tab.js
+++ b/src/components/settings_modal/tabs/filtering_tab.js
@@ -37,6 +37,9 @@ const FilteringTab = {
         })
       },
       deep: true
+    },
+    replyVisibility () {
+      this.$store.dispatch('queueFlushAll')
     }
   }
 }
diff --git a/src/components/status/status.js b/src/components/status/status.js
index 73382521..ad0b72a9 100644
--- a/src/components/status/status.js
+++ b/src/components/status/status.js
@@ -141,7 +141,7 @@ const Status = {
       return this.mergedConfig.hideFilteredStatuses
     },
     hideStatus () {
-      return (this.hideReply || this.deleted) || (this.muted && this.hideFilteredStatuses)
+      return this.deleted || (this.muted && this.hideFilteredStatuses)
     },
     isFocused () {
       // retweet or root of an expanded conversation
@@ -164,37 +164,6 @@ const Status = {
         return user && user.screen_name
       }
     },
-    hideReply () {
-      if (this.mergedConfig.replyVisibility === 'all') {
-        return false
-      }
-      if (this.inConversation || !this.isReply) {
-        return false
-      }
-      if (this.status.user.id === this.currentUser.id) {
-        return false
-      }
-      if (this.status.type === 'retweet') {
-        return false
-      }
-      const checkFollowing = this.mergedConfig.replyVisibility === 'following'
-      for (var i = 0; i < this.status.attentions.length; ++i) {
-        if (this.status.user.id === this.status.attentions[i].id) {
-          continue
-        }
-        // There's zero guarantee of this working. If we happen to have that user and their
-        // relationship in store then it will work, but there's kinda little chance of having
-        // them for people you're not following.
-        const relationship = this.$store.state.users.relationships[this.status.attentions[i].id]
-        if (checkFollowing && relationship && relationship.following) {
-          return false
-        }
-        if (this.status.attentions[i].id === this.currentUser.id) {
-          return false
-        }
-      }
-      return this.status.attentions.length > 0
-    },
     replySubject () {
       if (!this.status.summary) return ''
       const decodedSummary = unescape(this.status.summary)
diff --git a/src/components/timeline/timeline.js b/src/components/timeline/timeline.js
index 9a53acd6..d6519f4a 100644
--- a/src/components/timeline/timeline.js
+++ b/src/components/timeline/timeline.js
@@ -45,11 +45,15 @@ const Timeline = {
     newStatusCount () {
       return this.timeline.newStatusCount
     },
-    newStatusCountStr () {
+    showLoadButton () {
+      if (this.timelineError || this.errorData) return false
+      return this.timeline.newStatusCount > 0 || this.timeline.flushMarker !== 0
+    },
+    loadButtonString () {
       if (this.timeline.flushMarker !== 0) {
-        return ''
+        return this.$t('timeline.reload')
       } else {
-        return ` (${this.newStatusCount})`
+        return `${this.$t('timeline.show_new')} (${this.newStatusCount})`
       }
     },
     classes () {
@@ -112,8 +116,6 @@ const Timeline = {
       if (e.key === '.') this.showNewStatuses()
     },
     showNewStatuses () {
-      if (this.newStatusCount === 0) return
-
       if (this.timeline.flushMarker !== 0) {
         this.$store.commit('clearTimeline', { timeline: this.timelineName, excludeUserId: true })
         this.$store.commit('queueFlush', { timeline: this.timelineName, id: 0 })
diff --git a/src/components/timeline/timeline.vue b/src/components/timeline/timeline.vue
index 9777bd0c..111c0976 100644
--- a/src/components/timeline/timeline.vue
+++ b/src/components/timeline/timeline.vue
@@ -19,14 +19,14 @@
         {{ errorData.statusText }}
       </div>
       <button
-        v-if="timeline.newStatusCount > 0 && !timelineError && !errorData"
+        v-else-if="showLoadButton"
         class="loadmore-button"
         @click.prevent="showNewStatuses"
       >
-        {{ $t('timeline.show_new') }}{{ newStatusCountStr }}
+        {{ loadButtonString }}
       </button>
       <div
-        v-if="!timeline.newStatusCount > 0 && !timelineError && !errorData"
+        v-else
         class="loadmore-text faint"
         @click.prevent
       >
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 277c8739..abdba07f 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -618,6 +618,7 @@
     "no_retweet_hint": "Post is marked as followers-only or direct and cannot be repeated",
     "repeated": "repeated",
     "show_new": "Show new",
+    "reload": "Reload",
     "up_to_date": "Up-to-date",
     "no_more_statuses": "No more statuses",
     "no_statuses": "No statuses"
diff --git a/src/modules/statuses.js b/src/modules/statuses.js
index 073b15f1..4d3f8031 100644
--- a/src/modules/statuses.js
+++ b/src/modules/statuses.js
@@ -515,6 +515,11 @@ export const mutations = {
   queueFlush (state, { timeline, id }) {
     state.timelines[timeline].flushMarker = id
   },
+  queueFlushAll (state) {
+    Object.keys(state.timelines).forEach((timeline) => {
+      state.timelines[timeline].flushMarker = state.timelines[timeline].maxId
+    })
+  },
   addRepeats (state, { id, rebloggedByUsers, currentUser }) {
     const newStatus = state.allStatusesObject[id]
     newStatus.rebloggedBy = rebloggedByUsers.filter(_ => _)
@@ -664,6 +669,9 @@ const statuses = {
     queueFlush ({ rootState, commit }, { timeline, id }) {
       commit('queueFlush', { timeline, id })
     },
+    queueFlushAll ({ rootState, commit }) {
+      commit('queueFlushAll')
+    },
     markNotificationsAsSeen ({ rootState, commit }) {
       commit('markNotificationsAsSeen')
       apiService.markNotificationsAsSeen({
diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js
index cb205e3f..093c2013 100644
--- a/src/services/api/api.service.js
+++ b/src/services/api/api.service.js
@@ -498,7 +498,8 @@ const fetchTimeline = ({
   until = false,
   userId = false,
   tag = false,
-  withMuted = false
+  withMuted = false,
+  replyVisibility = 'all'
 }) => {
   const timelineUrls = {
     public: MASTODON_PUBLIC_TIMELINE,
@@ -541,6 +542,9 @@ const fetchTimeline = ({
   if (timeline !== 'favorites') {
     params.push(['with_muted', withMuted])
   }
+  if (replyVisibility !== 'all') {
+    params.push(['reply_visibility', replyVisibility])
+  }
 
   params.push(['limit', 20])
 
diff --git a/src/services/timeline_fetcher/timeline_fetcher.service.js b/src/services/timeline_fetcher/timeline_fetcher.service.js
index c6b28ad5..30fb26bd 100644
--- a/src/services/timeline_fetcher/timeline_fetcher.service.js
+++ b/src/services/timeline_fetcher/timeline_fetcher.service.js
@@ -30,7 +30,8 @@ const fetchAndUpdate = ({
   const rootState = store.rootState || store.state
   const { getters } = store
   const timelineData = rootState.statuses.timelines[camelCase(timeline)]
-  const hideMutedPosts = getters.mergedConfig.hideMutedPosts
+  const { hideMutedPosts, replyVisibility } = getters.mergedConfig
+  const loggedIn = !!rootState.users.currentUser
 
   if (older) {
     args['until'] = until || timelineData.minId
@@ -41,6 +42,7 @@ const fetchAndUpdate = ({
   args['userId'] = userId
   args['tag'] = tag
   args['withMuted'] = !hideMutedPosts
+  if (loggedIn) args['replyVisibility'] = replyVisibility
 
   const numStatusesBeforeFetch = timelineData.statuses.length