From 7a013ac39392ef251c0789f27dd4660dcd30bd6d Mon Sep 17 00:00:00 2001
From: Shpuld Shpludson <shp@cock.li>
Date: Wed, 15 Jan 2020 20:22:54 +0000
Subject: Implement domain mutes v2

---
 .../domain_mute_card/domain_mute_card.vue          | 38 ++++++++++++++++++++++
 1 file changed, 38 insertions(+)
 create mode 100644 src/components/domain_mute_card/domain_mute_card.vue

(limited to 'src/components/domain_mute_card/domain_mute_card.vue')

diff --git a/src/components/domain_mute_card/domain_mute_card.vue b/src/components/domain_mute_card/domain_mute_card.vue
new file mode 100644
index 00000000..567d81c5
--- /dev/null
+++ b/src/components/domain_mute_card/domain_mute_card.vue
@@ -0,0 +1,38 @@
+<template>
+  <div class="domain-mute-card">
+    <div class="domain-mute-card-domain">
+      {{ domain }}
+    </div>
+    <ProgressButton
+      :click="unmuteDomain"
+      class="btn btn-default"
+    >
+      {{ $t('domain_mute_card.unmute') }}
+      <template slot="progress">
+        {{ $t('domain_mute_card.unmute_progress') }}
+      </template>
+    </ProgressButton>
+  </div>
+</template>
+
+<script src="./domain_mute_card.js"></script>
+
+<style lang="scss">
+.domain-mute-card {
+  flex: 1 0;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 0.6em 1em 0.6em 0;
+
+  &-domain {
+    margin-right: 1em;
+    overflow: hidden;
+    text-overflow: ellipsis;
+  }
+
+  button {
+    width: 10em;
+  }
+}
+</style>
-- 
cgit v1.2.3-70-g09d2


From 10070394780ac79e9ee1e8548500586a1f78f65b Mon Sep 17 00:00:00 2001
From: Sergey Suprunenko <suprunenko.s@gmail.com>
Date: Sun, 10 May 2020 12:54:55 +0200
Subject: Autocomplete domain mutes from list of known instances

---
 CHANGELOG.md                                       |  1 +
 .../domain_mute_card/domain_mute_card.js           | 11 +++++++++
 .../domain_mute_card/domain_mute_card.vue          | 15 ++++++++++++
 .../settings_modal/tabs/mutes_and_blocks_tab.js    | 28 +++++++++++++++-------
 .../settings_modal/tabs/mutes_and_blocks_tab.vue   | 21 +++++++---------
 src/i18n/en.json                                   |  2 +-
 src/modules/instance.js                            | 17 +++++++++++++
 src/services/api/api.service.js                    |  6 +++++
 8 files changed, 79 insertions(+), 22 deletions(-)

(limited to 'src/components/domain_mute_card/domain_mute_card.vue')

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3e467bc9..11f539da 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
 ### Add
 - Added private notifications option for push notifications
 - 'Copy link' button for statuses (in the ellipsis menu)
+- Autocomplete domains from list of known instances
 
 ### Changed
 - Registration page no longer requires email if the server is configured not to require it
diff --git a/src/components/domain_mute_card/domain_mute_card.js b/src/components/domain_mute_card/domain_mute_card.js
index c8e838ba..f234dcb0 100644
--- a/src/components/domain_mute_card/domain_mute_card.js
+++ b/src/components/domain_mute_card/domain_mute_card.js
@@ -5,9 +5,20 @@ const DomainMuteCard = {
   components: {
     ProgressButton
   },
+  computed: {
+    user () {
+      return this.$store.state.users.currentUser
+    },
+    muted () {
+      return this.user.domainMutes.includes(this.domain)
+    }
+  },
   methods: {
     unmuteDomain () {
       return this.$store.dispatch('unmuteDomain', this.domain)
+    },
+    muteDomain () {
+      return this.$store.dispatch('muteDomain', this.domain)
     }
   }
 }
diff --git a/src/components/domain_mute_card/domain_mute_card.vue b/src/components/domain_mute_card/domain_mute_card.vue
index 567d81c5..97aee243 100644
--- a/src/components/domain_mute_card/domain_mute_card.vue
+++ b/src/components/domain_mute_card/domain_mute_card.vue
@@ -4,6 +4,7 @@
       {{ domain }}
     </div>
     <ProgressButton
+      v-if="muted"
       :click="unmuteDomain"
       class="btn btn-default"
     >
@@ -12,6 +13,16 @@
         {{ $t('domain_mute_card.unmute_progress') }}
       </template>
     </ProgressButton>
+    <ProgressButton
+      v-else
+      :click="muteDomain"
+      class="btn btn-default"
+    >
+      {{ $t('domain_mute_card.mute') }}
+      <template slot="progress">
+        {{ $t('domain_mute_card.mute_progress') }}
+      </template>
+    </ProgressButton>
   </div>
 </template>
 
@@ -34,5 +45,9 @@
   button {
     width: 10em;
   }
+
+  .autosuggest-results & {
+    padding-left: 1em;
+  }
 }
 </style>
diff --git a/src/components/settings_modal/tabs/mutes_and_blocks_tab.js b/src/components/settings_modal/tabs/mutes_and_blocks_tab.js
index b0043dbb..40a87b81 100644
--- a/src/components/settings_modal/tabs/mutes_and_blocks_tab.js
+++ b/src/components/settings_modal/tabs/mutes_and_blocks_tab.js
@@ -32,12 +32,12 @@ const DomainMuteList = withSubscription({
 const MutesAndBlocks = {
   data () {
     return {
-      activeTab: 'profile',
-      newDomainToMute: ''
+      activeTab: 'profile'
     }
   },
   created () {
     this.$store.dispatch('fetchTokens')
+    this.$store.dispatch('getKnownDomains')
   },
   components: {
     TabSwitcher,
@@ -51,6 +51,14 @@ const MutesAndBlocks = {
     Autosuggest,
     Checkbox
   },
+  computed: {
+    knownDomains () {
+      return this.$store.state.instance.knownDomains
+    },
+    user () {
+      return this.$store.state.users.currentUser
+    }
+  },
   methods: {
     importFollows (file) {
       return this.$store.state.api.backendInteractor.importFollows({ file })
@@ -86,13 +94,13 @@ const MutesAndBlocks = {
     filterUnblockedUsers (userIds) {
       return reject(userIds, (userId) => {
         const relationship = this.$store.getters.relationship(this.userId)
-        return relationship.blocking || userId === this.$store.state.users.currentUser.id
+        return relationship.blocking || userId === this.user.id
       })
     },
     filterUnMutedUsers (userIds) {
       return reject(userIds, (userId) => {
         const relationship = this.$store.getters.relationship(this.userId)
-        return relationship.muting || userId === this.$store.state.users.currentUser.id
+        return relationship.muting || userId === this.user.id
       })
     },
     queryUserIds (query) {
@@ -111,12 +119,16 @@ const MutesAndBlocks = {
     unmuteUsers (ids) {
       return this.$store.dispatch('unmuteUsers', ids)
     },
+    filterUnMutedDomains (urls) {
+      return urls.filter(url => !this.user.domainMutes.includes(url))
+    },
+    queryKnownDomains (query) {
+      return new Promise((resolve, reject) => {
+        resolve(this.knownDomains.filter(url => url.toLowerCase().includes(query)))
+      })
+    },
     unmuteDomains (domains) {
       return this.$store.dispatch('unmuteDomains', domains)
-    },
-    muteDomain () {
-      return this.$store.dispatch('muteDomain', this.newDomainToMute)
-        .then(() => { this.newDomainToMute = '' })
     }
   }
 }
diff --git a/src/components/settings_modal/tabs/mutes_and_blocks_tab.vue b/src/components/settings_modal/tabs/mutes_and_blocks_tab.vue
index 6884b7be..5a1cf2c0 100644
--- a/src/components/settings_modal/tabs/mutes_and_blocks_tab.vue
+++ b/src/components/settings_modal/tabs/mutes_and_blocks_tab.vue
@@ -119,21 +119,16 @@
 
         <div :label="$t('settings.domain_mutes')">
           <div class="domain-mute-form">
-            <input
-              v-model="newDomainToMute"
+            <Autosuggest
+              :filter="filterUnMutedDomains"
+              :query="queryKnownDomains"
               :placeholder="$t('settings.type_domains_to_mute')"
-              type="text"
-              @keyup.enter="muteDomain"
-            >
-            <ProgressButton
-              class="btn btn-default domain-mute-button"
-              :click="muteDomain"
             >
-              {{ $t('domain_mute_card.mute') }}
-              <template slot="progress">
-                {{ $t('domain_mute_card.mute_progress') }}
-              </template>
-            </ProgressButton>
+              <DomainMuteCard
+                slot-scope="row"
+                :domain="row.item"
+              />
+            </Autosuggest>
           </div>
           <DomainMuteList
             :refresh="true"
diff --git a/src/i18n/en.json b/src/i18n/en.json
index c322e538..eefe10e5 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -401,7 +401,7 @@
     "theme_help_v2_1": "You can also override certain component's colors and opacity by toggling the checkbox, use \"Clear all\" button to clear all overrides.",
     "theme_help_v2_2": "Icons underneath some entries are background/text contrast indicators, hover over for detailed info. Please keep in mind that when using transparency contrast indicators show the worst possible case.",
     "tooltipRadius": "Tooltips/alerts",
-    "type_domains_to_mute": "Type in domains to mute",
+    "type_domains_to_mute": "Search domains to mute",
     "upload_a_photo": "Upload a photo",
     "user_settings": "User Settings",
     "values": {
diff --git a/src/modules/instance.js b/src/modules/instance.js
index da82eb01..ec5f4e54 100644
--- a/src/modules/instance.js
+++ b/src/modules/instance.js
@@ -1,6 +1,7 @@
 import { set } from 'vue'
 import { getPreset, applyTheme } from '../services/style_setter/style_setter.js'
 import { CURRENT_VERSION } from '../services/theme_data/theme_data.service.js'
+import apiService from '../services/api/api.service.js'
 import { instanceDefaultProperties } from './config.js'
 
 const defaultState = {
@@ -48,6 +49,7 @@ const defaultState = {
   postFormats: [],
   restrictedNicknames: [],
   safeDM: true,
+  knownDomains: [],
 
   // Feature-set, apparently, not everything here is reported...
   chatAvailable: false,
@@ -80,6 +82,9 @@ const instance = {
       if (typeof value !== 'undefined') {
         set(state, name, value)
       }
+    },
+    setKnownDomains (state, domains) {
+      state.knownDomains = domains
     }
   },
   getters: {
@@ -182,6 +187,18 @@ const instance = {
         state.emojiFetched = true
         dispatch('getStaticEmoji')
       }
+    },
+
+    async getKnownDomains ({ commit, rootState }) {
+      try {
+        const result = await apiService.fetchKnownDomains({
+          credentials: rootState.users.currentUser.credentials
+        })
+        commit('setKnownDomains', result)
+      } catch (e) {
+        console.warn("Can't load known domains")
+        console.warn(e)
+      }
     }
   }
 }
diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js
index 9c7530a2..b3082bc5 100644
--- a/src/services/api/api.service.js
+++ b/src/services/api/api.service.js
@@ -75,6 +75,7 @@ const MASTODON_SEARCH_2 = `/api/v2/search`
 const MASTODON_USER_SEARCH_URL = '/api/v1/accounts/search'
 const MASTODON_DOMAIN_BLOCKS_URL = '/api/v1/domain_blocks'
 const MASTODON_STREAMING = '/api/v1/streaming'
+const MASTODON_KNOWN_DOMAIN_LIST_URL = '/api/v1/instance/peers'
 const PLEROMA_EMOJI_REACTIONS_URL = id => `/api/v1/pleroma/statuses/${id}/reactions`
 const PLEROMA_EMOJI_REACT_URL = (id, emoji) => `/api/v1/pleroma/statuses/${id}/reactions/${emoji}`
 const PLEROMA_EMOJI_UNREACT_URL = (id, emoji) => `/api/v1/pleroma/statuses/${id}/reactions/${emoji}`
@@ -995,6 +996,10 @@ const search2 = ({ credentials, q, resolve, limit, offset, following }) => {
     })
 }
 
+const fetchKnownDomains = ({ credentials }) => {
+  return promisedRequest({ url: MASTODON_KNOWN_DOMAIN_LIST_URL, credentials })
+}
+
 const fetchDomainMutes = ({ credentials }) => {
   return promisedRequest({ url: MASTODON_DOMAIN_BLOCKS_URL, credentials })
 }
@@ -1193,6 +1198,7 @@ const apiService = {
   updateNotificationSettings,
   search2,
   searchUsers,
+  fetchKnownDomains,
   fetchDomainMutes,
   muteDomain,
   unmuteDomain
-- 
cgit v1.2.3-70-g09d2

