From a4e3cccf1cba238e5bfd96ea8c60f0d12bc6b7aa Mon Sep 17 00:00:00 2001
From: Shpuld Shpuldson <shp@cock.li>
Date: Wed, 6 Jan 2021 18:31:34 +0200
Subject: somewhat workign version still with fixture

---
 src/components/notification/notification.vue | 34 ++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

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

diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue
index f56aa977..39e3bda0 100644
--- a/src/components/notification/notification.vue
+++ b/src/components/notification/notification.vue
@@ -106,6 +106,9 @@
                 </i18n>
               </small>
             </span>
+            <span v-if="notification.type === 'pleroma:report'">
+              <small>{{ $t('notifications.submitted_report') }}</small>
+            </span>
           </div>
           <div
             v-if="isStatusNotification"
@@ -180,6 +183,37 @@
             @{{ notification.target.screen_name }}
           </router-link>
         </div>
+        <div
+          v-else-if="notification.type === 'pleroma:report'"
+        >
+          <small>Reported user:</small>
+          <router-link :to="generateUserProfileLink(notification.report.acct)">
+            @{{ notification.report.acct.screen_name }}
+          </router-link>
+          <!-- eslint-disable vue/no-v-html -->
+          <div
+            class="report-content"
+            v-html="notification.report.content"
+          />
+          <div v-if="notification.report.statuses.length">
+            <small>Reported statuses:</small>
+            <!-- eslint-enable vue/no-v-html -->
+            <router-link
+              v-for="status in notification.report.statuses"
+              :key="status.id"
+              :to="{ name: 'conversation', params: { id: status.id } }"
+              class="reported-status"
+            >
+              <span class="reported-status-name">{{ status.user.name }}</span>
+              <Timeago
+                :time="status.created_at"
+                :auto-update="240"
+                class="reported-status-timeago faint"
+              />
+              <status-content :status="status" />
+            </router-link>
+          </div>
+        </div>
         <template v-else>
           <status-content
             class="faint"
-- 
cgit v1.2.3-70-g09d2


From 8674f2002320aaa6c380488b0eab636a53c76705 Mon Sep 17 00:00:00 2001
From: Shpuld Shpuldson <shp@cock.li>
Date: Mon, 11 Jan 2021 19:32:58 +0200
Subject: separated component

---
 src/components/notification/notification.js   |  4 +-
 src/components/notification/notification.scss | 28 ------------
 src/components/notification/notification.vue  | 33 ++------------
 src/components/report/report.js               | 23 ++++++++++
 src/components/report/report.scss             | 39 +++++++++++++++++
 src/components/report/report.vue              | 63 +++++++++++++++++++++++++++
 src/i18n/en.json                              | 10 +++++
 src/services/api/api.service.js               | 32 +++++++++++++-
 8 files changed, 171 insertions(+), 61 deletions(-)
 create mode 100644 src/components/report/report.js
 create mode 100644 src/components/report/report.scss
 create mode 100644 src/components/report/report.vue

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

diff --git a/src/components/notification/notification.js b/src/components/notification/notification.js
index a920bb3e..38211bb3 100644
--- a/src/components/notification/notification.js
+++ b/src/components/notification/notification.js
@@ -4,6 +4,7 @@ import Status from '../status/status.vue'
 import UserAvatar from '../user_avatar/user_avatar.vue'
 import UserCard from '../user_card/user_card.vue'
 import Timeago from '../timeago/timeago.vue'
+import Report from '../report/report.vue'
 import { isStatusNotification } from '../../services/notification_utils/notification_utils.js'
 import { highlightClass, highlightStyle } from '../../services/user_highlighter/user_highlighter.js'
 import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
@@ -44,7 +45,8 @@ const Notification = {
     UserAvatar,
     UserCard,
     Timeago,
-    Status
+    Status,
+    Report
   },
   methods: {
     toggleUserExpanded () {
diff --git a/src/components/notification/notification.scss b/src/components/notification/notification.scss
index b103db86..f5905560 100644
--- a/src/components/notification/notification.scss
+++ b/src/components/notification/notification.scss
@@ -56,34 +56,6 @@
     margin: 0 0.1em;
   }
 
-  .report-content {
-    margin: 0.5em 0;
-  }
-
-  .reported-status {
-    border: 1px solid $fallback--faint;
-    border-color: var(--faint, $fallback--faint);
-    border-radius: $fallback--inputRadius;
-    border-radius: var(--inputRadius, $fallback--inputRadius);
-    color: $fallback--text;
-    color: var(--text, $fallback--text);
-    display: block;
-    padding: 0.5em;
-    margin: 0.5em 0;
-
-    .status-content {
-      pointer-events: none;
-    }
-
-    .reported-status-name {
-      font-weight: bold;
-    }
-
-    .reported-status-timeago {
-      float: right;
-    }
-  }
-
   &.-type--repeat .type-icon {
     color: $fallback--cGreen;
     color: var(--cGreen, $fallback--cGreen);
diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue
index 39e3bda0..3b74249d 100644
--- a/src/components/notification/notification.vue
+++ b/src/components/notification/notification.vue
@@ -183,37 +183,10 @@
             @{{ notification.target.screen_name }}
           </router-link>
         </div>
-        <div
+        <Report
           v-else-if="notification.type === 'pleroma:report'"
-        >
-          <small>Reported user:</small>
-          <router-link :to="generateUserProfileLink(notification.report.acct)">
-            @{{ notification.report.acct.screen_name }}
-          </router-link>
-          <!-- eslint-disable vue/no-v-html -->
-          <div
-            class="report-content"
-            v-html="notification.report.content"
-          />
-          <div v-if="notification.report.statuses.length">
-            <small>Reported statuses:</small>
-            <!-- eslint-enable vue/no-v-html -->
-            <router-link
-              v-for="status in notification.report.statuses"
-              :key="status.id"
-              :to="{ name: 'conversation', params: { id: status.id } }"
-              class="reported-status"
-            >
-              <span class="reported-status-name">{{ status.user.name }}</span>
-              <Timeago
-                :time="status.created_at"
-                :auto-update="240"
-                class="reported-status-timeago faint"
-              />
-              <status-content :status="status" />
-            </router-link>
-          </div>
-        </div>
+          :report="notification.report"
+        />
         <template v-else>
           <status-content
             class="faint"
diff --git a/src/components/report/report.js b/src/components/report/report.js
new file mode 100644
index 00000000..e81417a8
--- /dev/null
+++ b/src/components/report/report.js
@@ -0,0 +1,23 @@
+import StatusContent from '../status_content/status_content.vue'
+import Timeago from '../timeago/timeago.vue'
+import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
+
+const Report = {
+  props: [
+    'report'
+  ],
+  components: {
+    StatusContent,
+    Timeago
+  },
+  methods: {
+    generateUserProfileLink (user) {
+      return generateProfileLink(user.id, user.screen_name, this.$store.state.instance.restrictedNicknames)
+    },
+    setReportState (id, state) {
+      return this.$store.state.api.backendInteractor.setReportState({ id, state })
+    }
+  }
+}
+
+export default Report
diff --git a/src/components/report/report.scss b/src/components/report/report.scss
new file mode 100644
index 00000000..7e9cc2b6
--- /dev/null
+++ b/src/components/report/report.scss
@@ -0,0 +1,39 @@
+@import '../../_variables.scss';
+
+.Report {
+  .report-content {
+    margin: 0.5em 0;
+  }
+
+  .reported-status {
+    border: 1px solid $fallback--faint;
+    border-color: var(--faint, $fallback--faint);
+    border-radius: $fallback--inputRadius;
+    border-radius: var(--inputRadius, $fallback--inputRadius);
+    color: $fallback--text;
+    color: var(--text, $fallback--text);
+    display: block;
+    padding: 0.5em;
+    margin: 0.5em 0;
+
+    .status-content {
+      pointer-events: none;
+    }
+
+    .reported-status-heading {
+      display: flex;
+      width: 100%;
+      justify-content: space-between;
+      margin-bottom: 0.2em;
+    }
+
+    .reported-status-name {
+      font-weight: bold;
+    }
+  }
+
+  .note {
+    width: 100%;
+    margin-bottom: 0.5em;
+  }
+}
diff --git a/src/components/report/report.vue b/src/components/report/report.vue
new file mode 100644
index 00000000..20fe1bfe
--- /dev/null
+++ b/src/components/report/report.vue
@@ -0,0 +1,63 @@
+<template>
+  <div class="Report">
+    <div class="reported-user">
+      <span>{{ $t('report.reported_user') }}</span>
+      <router-link :to="generateUserProfileLink(report.acct)">
+        @{{ report.acct.screen_name }}
+      </router-link>
+    </div>
+    <div class="reporter">
+      <span>{{ $t('report.reporter') }}</span>
+      <router-link :to="generateUserProfileLink(report.actor)">
+        @{{ report.actor.screen_name }}
+      </router-link>
+    </div>
+    <div class="report-state">
+      <span>{{ $t('report.state') }}</span>
+      <b>{{ $t('report.state_' + report.state) }}</b>
+    </div>
+    <!-- eslint-disable vue/no-v-html -->
+    <div
+      class="report-content"
+      v-html="report.content"
+    />
+    <div v-if="report.statuses.length">
+      <small>{{ $t('report.reported_statuses') }}</small>
+      <!-- eslint-enable vue/no-v-html -->
+      <router-link
+        v-for="status in report.statuses"
+        :key="status.id"
+        :to="{ name: 'conversation', params: { id: status.id } }"
+        class="reported-status"
+      >
+        <div class="reported-status-heading">
+          <span class="reported-status-name">{{ status.user.name }}</span>
+          <Timeago
+            :time="status.created_at"
+            :auto-update="240"
+            class="faint"
+          />
+        </div>
+        <status-content :status="status" />
+      </router-link>
+    </div>
+    <div v-if="report.notes.length">
+      <small>{{ $t('report.notes') }}</small>
+      <div
+        v-for="note in report.notes"
+        :key="note.id"
+        class="note"
+      >
+        <span>{{ note.content }}</span>
+        <Timeago
+          :time="note.created_at"
+          :auto-update="240"
+          class="faint"
+        />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script src="./report.js"></script>
+<style src="./report.scss" lang="scss"></style>
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 5936349a..3251de2a 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -237,6 +237,16 @@
     "searching_for": "Searching for",
     "error": "Not found."
   },
+  "report": {
+    "reporter": "Reporter:",
+    "reported_user": "Reported user:",
+    "reported_statuses": "Reported statuses:",
+    "notes": "Notes:",
+    "state": "State:",
+    "state_open": "Open",
+    "state_closed": "Closed",
+    "state_resolved": "Resolved"
+  },
   "selectable_list": {
     "select_all": "Select all"
   },
diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js
index 9a3494ff..e1e26151 100644
--- a/src/services/api/api.service.js
+++ b/src/services/api/api.service.js
@@ -87,6 +87,7 @@ const PLEROMA_CHAT_URL = id => `/api/v1/pleroma/chats/by-account-id/${id}`
 const PLEROMA_CHAT_MESSAGES_URL = id => `/api/v1/pleroma/chats/${id}/messages`
 const PLEROMA_CHAT_READ_URL = id => `/api/v1/pleroma/chats/${id}/read`
 const PLEROMA_DELETE_CHAT_MESSAGE_URL = (chatId, messageId) => `/api/v1/pleroma/chats/${chatId}/messages/${messageId}`
+const PLEROMA_ADMIN_REPORTS = '/api/pleroma/admin/reports'
 
 const oldfetch = window.fetch
 
@@ -759,7 +760,18 @@ const report = {
     "content": "This is the report created by &quot;reporting_account&quot;. It reports &quot;reported_account&quot;.",
     "created_at": "2020-09-03T14:22:59.000Z",
     "id": "9ymggNcUyfIW8Cq1zM",
-    "notes": [],
+    "notes": [
+      {
+        "content": "Some note left here.",
+        "created_at": "2020-09-03T14:22:59.000Z",
+        "id": "1"
+      },
+      {
+        "content": "Some other note that is much much much longer than the previous note left here.",
+        "created_at": "2020-09-03T14:23:59.000Z",
+        "id": "2"
+      }
+    ],
     "state": "open",
     "statuses": [
       {
@@ -1553,6 +1565,21 @@ const deleteChatMessage = ({ chatId, messageId, credentials }) => {
   })
 }
 
+const setReportState = ({ id, state, credentials }) => {
+  return promisedRequest({
+    url: PLEROMA_ADMIN_REPORTS,
+    method: 'PATCH',
+    payload: {
+      'reports': [
+        {
+          id,
+          state
+        }
+      ]
+    }
+  })
+}
+
 const apiService = {
   verifyCredentials,
   fetchTimeline,
@@ -1638,7 +1665,8 @@ const apiService = {
   chatMessages,
   sendChatMessage,
   readChat,
-  deleteChatMessage
+  deleteChatMessage,
+  setReportState
 }
 
 export default apiService
-- 
cgit v1.2.3-70-g09d2


From e73553dca726703f83e5085560377bfaa202a5f9 Mon Sep 17 00:00:00 2001
From: Shpuld Shpuldson <shp@cock.li>
Date: Mon, 18 Jan 2021 15:26:08 +0200
Subject: wip

---
 src/components/notification/notification.vue |  2 +-
 src/components/report/report.js              |  9 ++++--
 src/components/report/report.vue             | 24 ++++++++++++++++
 src/modules/reports.js                       | 41 ++++++++++++++++++++++------
 src/modules/statuses.js                      |  4 +++
 src/services/api/api.service.js              |  8 +++++-
 6 files changed, 75 insertions(+), 13 deletions(-)

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

diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue
index 3b74249d..40ea0431 100644
--- a/src/components/notification/notification.vue
+++ b/src/components/notification/notification.vue
@@ -185,7 +185,7 @@
         </div>
         <Report
           v-else-if="notification.type === 'pleroma:report'"
-          :report="notification.report"
+          :report-id="notification.report.id"
         />
         <template v-else>
           <status-content
diff --git a/src/components/report/report.js b/src/components/report/report.js
index e81417a8..8131dd89 100644
--- a/src/components/report/report.js
+++ b/src/components/report/report.js
@@ -4,18 +4,23 @@ import generateProfileLink from 'src/services/user_profile_link_generator/user_p
 
 const Report = {
   props: [
-    'report'
+    'reportId'
   ],
   components: {
     StatusContent,
     Timeago
   },
+  computed: {
+    report () {
+      return this.$store.state.reports.reports[this.reportId] || {}
+    }
+  },
   methods: {
     generateUserProfileLink (user) {
       return generateProfileLink(user.id, user.screen_name, this.$store.state.instance.restrictedNicknames)
     },
     setReportState (id, state) {
-      return this.$store.state.api.backendInteractor.setReportState({ id, state })
+      return this.$store.dispatch('setReportState', { id, state })
     }
   }
 }
diff --git a/src/components/report/report.vue b/src/components/report/report.vue
index 20fe1bfe..638a3aa0 100644
--- a/src/components/report/report.vue
+++ b/src/components/report/report.vue
@@ -1,5 +1,29 @@
 <template>
   <div class="Report">
+    <div class="report-state">
+      <label
+        for="report-state"
+        class="select"
+      >
+        <select
+          id="report-state"
+          v-model="report.state"
+          class="form-control"
+        >
+          <option
+            v-for="state in ['open', 'closed', 'resolved']"
+            :key="state"
+            :value="report.state"
+          >
+            {{ $t('report.state_' + state) }}
+          </option>
+        </select>
+        <FAIcon
+          class="select-down-icon"
+          icon="chevron-down"
+        />
+      </label>
+    </div>
     <div class="reported-user">
       <span>{{ $t('report.reported_user') }}</span>
       <router-link :to="generateUserProfileLink(report.acct)">
diff --git a/src/modules/reports.js b/src/modules/reports.js
index fea83e5f..3ede42c6 100644
--- a/src/modules/reports.js
+++ b/src/modules/reports.js
@@ -1,21 +1,31 @@
+import backendInteractorService from '../services/backend_interactor_service/backend_interactor_service.js'
 import filter from 'lodash/filter'
 
 const reports = {
   state: {
-    userId: null,
-    statuses: [],
-    preTickedIds: [],
-    modalActivated: false
+    reportModal: {
+      userId: null,
+      statuses: [],
+      preTickedIds: [],
+      activated: false
+    },
+    reports: {}
   },
   mutations: {
     openUserReportingModal (state, { userId, statuses, preTickedIds }) {
-      state.userId = userId
-      state.statuses = statuses
-      state.preTickedIds = preTickedIds
-      state.modalActivated = true
+      state.reportModal.userId = userId
+      state.reportModal.statuses = statuses
+      state.reportModal.preTickedIds = preTickedIds
+      state.reportModal.activated = true
     },
     closeUserReportingModal (state) {
-      state.modalActivated = false
+      state.reportModal.modalActivated = false
+    },
+    setReportState (reportsState, { id, state }) {
+      reportsState.reports[id].state = state
+    },
+    addReport (state, report) {
+      state.reports[report.id] = report
     }
   },
   actions: {
@@ -31,6 +41,19 @@ const reports = {
     },
     closeUserReportingModal ({ commit }) {
       commit('closeUserReportingModal')
+    },
+    setReportState ({ commit, rootState }, { id, state }) {
+      const oldState = rootState.reports.reports[id].state
+      commit('setReportState', { id, state })
+      backendInteractorService.setReportState({ id, state }).then(report => {
+        console.log(report)
+      }).catch(e => {
+        console.error('Failed to set report state', e)
+        commit('setReportState', { id, oldState })
+      })
+    },
+    addReport ({ commit }, report) {
+      commit('addReport', report)
     }
   }
 }
diff --git a/src/modules/statuses.js b/src/modules/statuses.js
index 33c68c57..d5343cd4 100644
--- a/src/modules/statuses.js
+++ b/src/modules/statuses.js
@@ -317,6 +317,10 @@ const addNewNotifications = (state, { dispatch, notifications, older, visibleNot
       notification.status = notification.status && addStatusToGlobalStorage(state, notification.status).item
     }
 
+    if (notification.type === 'pleroma:report') {
+      dispatch('addReport', notification.report)
+    }
+
     if (notification.type === 'pleroma:emoji_reaction') {
       dispatch('fetchEmojiReactionsBy', notification.status.id)
     }
diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js
index e1e26151..f9a97ba7 100644
--- a/src/services/api/api.service.js
+++ b/src/services/api/api.service.js
@@ -786,6 +786,8 @@ const report = {
   },
   "type": "pleroma:report"
 }
+
+const notifs2 = [{"account":{"acct":"shpuld@shpposter.club","avatar":"https://stereophonic.space/proxy/mCyl0lPWgFshoU9vTcm7vvEOSpM/aHR0cHM6Ly9zaHBwb3N0ZXIuY2x1Yi9tZWRpYS82MmUyYTZiNzM1MzZmODBlZmVjOWJjOWY0MDRkMjdhYjMyOTQ2NzkzMDUyZjFiZmRiYjY1Mzc0ZWZlYzc0NWMyLnBuZz9uYW1lPWhhbmRfZHJhd25fZG9yZW15X2ZpLnBuZw/62e2a6b73536f80efec9bc9f404d27ab32946793052f1bfdbb65374efec745c2.png","avatar_static":"https://stereophonic.space/proxy/mCyl0lPWgFshoU9vTcm7vvEOSpM/aHR0cHM6Ly9zaHBwb3N0ZXIuY2x1Yi9tZWRpYS82MmUyYTZiNzM1MzZmODBlZmVjOWJjOWY0MDRkMjdhYjMyOTQ2NzkzMDUyZjFiZmRiYjY1Mzc0ZWZlYzc0NWMyLnBuZz9uYW1lPWhhbmRfZHJhd25fZG9yZW15X2ZpLnBuZw/62e2a6b73536f80efec9bc9f404d27ab32946793052f1bfdbb65374efec745c2.png","bot":false,"created_at":"2019-04-19T05:37:58.000Z","display_name":"shp :blobshp: ","emojis":[{"shortcode":"blobshp","static_url":"https://stereophonic.space/proxy/99gLk4HErQqqLs-IWocZPiUWKVU/aHR0cHM6Ly9zaHBwb3N0ZXIuY2x1Yi9lbW9qaS9jdXN0b20vYmxvYnNocC5wbmc/blobshp.png","url":"https://stereophonic.space/proxy/99gLk4HErQqqLs-IWocZPiUWKVU/aHR0cHM6Ly9zaHBwb3N0ZXIuY2x1Yi9lbW9qaS9jdXN0b20vYmxvYnNocC5wbmc/blobshp.png","visible_in_picker":false}],"fields":[],"followers_count":825,"following_count":172,"header":"https://stereophonic.space/proxy/wqWHtbwjIXRc2V8EJjkS_vWQvzs/aHR0cHM6Ly9zaHBwb3N0ZXIuY2x1Yi9tZWRpYS9mNWIxNzUyMC03YzcwLTQ2MGQtODcxZi03MGUzNjIxY2RkYzYvMDRhNGUwN2Q3ZDg4MGFjYjA0MmQ3MzNmZGQ5ODk2OGQ5OTE2ZjNiY2EwZWYwYzdhYTMxYWFjYTM1ZjZiMTNhNC5wbmc/04a4e07d7d880acb042d733fdd98968d9916f3bca0ef0c7aa31aaca35f6b13a4.png","header_static":"https://stereophonic.space/proxy/wqWHtbwjIXRc2V8EJjkS_vWQvzs/aHR0cHM6Ly9zaHBwb3N0ZXIuY2x1Yi9tZWRpYS9mNWIxNzUyMC03YzcwLTQ2MGQtODcxZi03MGUzNjIxY2RkYzYvMDRhNGUwN2Q3ZDg4MGFjYjA0MmQ3MzNmZGQ5ODk2OGQ5OTE2ZjNiY2EwZWYwYzdhYTMxYWFjYTM1ZjZiMTNhNC5wbmc/04a4e07d7d880acb042d733fdd98968d9916f3bca0ef0c7aa31aaca35f6b13a4.png","id":"9hxJNZ8sR2bG7zLS3E","locked":false,"note":"","pleroma":{"accepts_chat_messages":true,"ap_id":"https://shpposter.club/users/shpuld","background_image":null,"confirmation_pending":false,"deactivated":false,"favicon":null,"hide_favorites":true,"hide_followers":true,"hide_followers_count":false,"hide_follows":true,"hide_follows_count":false,"is_admin":false,"is_moderator":false,"relationship":{},"skip_thread_containment":false,"tags":[]},"source":{"fields":[],"note":"","pleroma":{"actor_type":"Person","discoverable":false},"sensitive":false},"statuses_count":62787,"url":"https://shpposter.club/users/shpuld","username":"shpuld"},"created_at":"2021-01-16T11:13:48.000Z","id":"326692","pleroma":{"is_muted":false,"is_seen":false},"status":{"account":{"acct":"shpuld@shpposter.club","avatar":"https://stereophonic.space/proxy/mCyl0lPWgFshoU9vTcm7vvEOSpM/aHR0cHM6Ly9zaHBwb3N0ZXIuY2x1Yi9tZWRpYS82MmUyYTZiNzM1MzZmODBlZmVjOWJjOWY0MDRkMjdhYjMyOTQ2NzkzMDUyZjFiZmRiYjY1Mzc0ZWZlYzc0NWMyLnBuZz9uYW1lPWhhbmRfZHJhd25fZG9yZW15X2ZpLnBuZw/62e2a6b73536f80efec9bc9f404d27ab32946793052f1bfdbb65374efec745c2.png","avatar_static":"https://stereophonic.space/proxy/mCyl0lPWgFshoU9vTcm7vvEOSpM/aHR0cHM6Ly9zaHBwb3N0ZXIuY2x1Yi9tZWRpYS82MmUyYTZiNzM1MzZmODBlZmVjOWJjOWY0MDRkMjdhYjMyOTQ2NzkzMDUyZjFiZmRiYjY1Mzc0ZWZlYzc0NWMyLnBuZz9uYW1lPWhhbmRfZHJhd25fZG9yZW15X2ZpLnBuZw/62e2a6b73536f80efec9bc9f404d27ab32946793052f1bfdbb65374efec745c2.png","bot":false,"created_at":"2019-04-19T05:37:58.000Z","display_name":"shp :blobshp: ","emojis":[{"shortcode":"blobshp","static_url":"https://stereophonic.space/proxy/99gLk4HErQqqLs-IWocZPiUWKVU/aHR0cHM6Ly9zaHBwb3N0ZXIuY2x1Yi9lbW9qaS9jdXN0b20vYmxvYnNocC5wbmc/blobshp.png","url":"https://stereophonic.space/proxy/99gLk4HErQqqLs-IWocZPiUWKVU/aHR0cHM6Ly9zaHBwb3N0ZXIuY2x1Yi9lbW9qaS9jdXN0b20vYmxvYnNocC5wbmc/blobshp.png","visible_in_picker":false}],"fields":[],"followers_count":825,"following_count":172,"header":"https://stereophonic.space/proxy/wqWHtbwjIXRc2V8EJjkS_vWQvzs/aHR0cHM6Ly9zaHBwb3N0ZXIuY2x1Yi9tZWRpYS9mNWIxNzUyMC03YzcwLTQ2MGQtODcxZi03MGUzNjIxY2RkYzYvMDRhNGUwN2Q3ZDg4MGFjYjA0MmQ3MzNmZGQ5ODk2OGQ5OTE2ZjNiY2EwZWYwYzdhYTMxYWFjYTM1ZjZiMTNhNC5wbmc/04a4e07d7d880acb042d733fdd98968d9916f3bca0ef0c7aa31aaca35f6b13a4.png","header_static":"https://stereophonic.space/proxy/wqWHtbwjIXRc2V8EJjkS_vWQvzs/aHR0cHM6Ly9zaHBwb3N0ZXIuY2x1Yi9tZWRpYS9mNWIxNzUyMC03YzcwLTQ2MGQtODcxZi03MGUzNjIxY2RkYzYvMDRhNGUwN2Q3ZDg4MGFjYjA0MmQ3MzNmZGQ5ODk2OGQ5OTE2ZjNiY2EwZWYwYzdhYTMxYWFjYTM1ZjZiMTNhNC5wbmc/04a4e07d7d880acb042d733fdd98968d9916f3bca0ef0c7aa31aaca35f6b13a4.png","id":"9hxJNZ8sR2bG7zLS3E","locked":false,"note":"","pleroma":{"accepts_chat_messages":true,"ap_id":"https://shpposter.club/users/shpuld","background_image":null,"confirmation_pending":false,"deactivated":false,"favicon":null,"hide_favorites":true,"hide_followers":true,"hide_followers_count":false,"hide_follows":true,"hide_follows_count":false,"is_admin":false,"is_moderator":false,"relationship":{},"skip_thread_containment":false,"tags":[]},"source":{"fields":[],"note":"","pleroma":{"actor_type":"Person","discoverable":false},"sensitive":false},"statuses_count":62787,"url":"https://shpposter.club/users/shpuld","username":"shpuld"},"application":{"name":"Web","website":null},"bookmarked":false,"card":null,"content":"<span class=\"h-card\"><a class=\"u-url mention\" data-user=\"9rZ3QjHZi07Ty8NV68\" href=\"https://stereophonic.space/users/newt\">@<span>newt</span></a></span> check from network tab what it&#39;s actually returning from BE when it does this","created_at":"2021-01-16T11:13:45.000Z","emojis":[],"favourited":false,"favourites_count":0,"id":"A3IFAFmm75qdDrUcWe","in_reply_to_account_id":"9rZ2STPb7FA7JnMRii","in_reply_to_id":"A3IF5X1AcKGdDeyTmi","language":null,"media_attachments":[],"mentions":[{"acct":"newt","id":"9rZ2STPb7FA7JnMRii","url":"https://stereophonic.space/users/newt","username":"newt"}],"muted":false,"pinned":false,"pleroma":{"content":{"text/plain":"@newt check from network tab what it's actually returning from BE when it does this"},"conversation_id":20796406,"direct_conversation_id":null,"emoji_reactions":[],"expires_at":null,"in_reply_to_account_acct":"newt","local":false,"parent_visible":true,"spoiler_text":{"text/plain":""},"thread_muted":false},"poll":null,"reblog":null,"reblogged":false,"reblogs_count":0,"replies_count":1,"sensitive":false,"spoiler_text":"","tags":[],"text":null,"uri":"https://shpposter.club/objects/2a1d1647-d08a-4fed-81ca-5cdd525fc848","url":"https://shpposter.club/objects/2a1d1647-d08a-4fed-81ca-5cdd525fc848","visibility":"public"},"type":"mention"},{"account":{"acct":"shpuld@shpposter.club","avatar":"https://stereophonic.space/proxy/mCyl0lPWgFshoU9vTcm7vvEOSpM/aHR0cHM6Ly9zaHBwb3N0ZXIuY2x1Yi9tZWRpYS82MmUyYTZiNzM1MzZmODBlZmVjOWJjOWY0MDRkMjdhYjMyOTQ2NzkzMDUyZjFiZmRiYjY1Mzc0ZWZlYzc0NWMyLnBuZz9uYW1lPWhhbmRfZHJhd25fZG9yZW15X2ZpLnBuZw/62e2a6b73536f80efec9bc9f404d27ab32946793052f1bfdbb65374efec745c2.png","avatar_static":"https://stereophonic.space/proxy/mCyl0lPWgFshoU9vTcm7vvEOSpM/aHR0cHM6Ly9zaHBwb3N0ZXIuY2x1Yi9tZWRpYS82MmUyYTZiNzM1MzZmODBlZmVjOWJjOWY0MDRkMjdhYjMyOTQ2NzkzMDUyZjFiZmRiYjY1Mzc0ZWZlYzc0NWMyLnBuZz9uYW1lPWhhbmRfZHJhd25fZG9yZW15X2ZpLnBuZw/62e2a6b73536f80efec9bc9f404d27ab32946793052f1bfdbb65374efec745c2.png","bot":false,"created_at":"2019-04-19T05:37:58.000Z","display_name":"shp :blobshp: ","emojis":[{"shortcode":"blobshp","static_url":"https://stereophonic.space/proxy/99gLk4HErQqqLs-IWocZPiUWKVU/aHR0cHM6Ly9zaHBwb3N0ZXIuY2x1Yi9lbW9qaS9jdXN0b20vYmxvYnNocC5wbmc/blobshp.png","url":"https://stereophonic.space/proxy/99gLk4HErQqqLs-IWocZPiUWKVU/aHR0cHM6Ly9zaHBwb3N0ZXIuY2x1Yi9lbW9qaS9jdXN0b20vYmxvYnNocC5wbmc/blobshp.png","visible_in_picker":false}],"fields":[],"followers_count":825,"following_count":172,"header":"https://stereophonic.space/proxy/wqWHtbwjIXRc2V8EJjkS_vWQvzs/aHR0cHM6Ly9zaHBwb3N0ZXIuY2x1Yi9tZWRpYS9mNWIxNzUyMC03YzcwLTQ2MGQtODcxZi03MGUzNjIxY2RkYzYvMDRhNGUwN2Q3ZDg4MGFjYjA0MmQ3MzNmZGQ5ODk2OGQ5OTE2ZjNiY2EwZWYwYzdhYTMxYWFjYTM1ZjZiMTNhNC5wbmc/04a4e07d7d880acb042d733fdd98968d9916f3bca0ef0c7aa31aaca35f6b13a4.png","header_static":"https://stereophonic.space/proxy/wqWHtbwjIXRc2V8EJjkS_vWQvzs/aHR0cHM6Ly9zaHBwb3N0ZXIuY2x1Yi9tZWRpYS9mNWIxNzUyMC03YzcwLTQ2MGQtODcxZi03MGUzNjIxY2RkYzYvMDRhNGUwN2Q3ZDg4MGFjYjA0MmQ3MzNmZGQ5ODk2OGQ5OTE2ZjNiY2EwZWYwYzdhYTMxYWFjYTM1ZjZiMTNhNC5wbmc/04a4e07d7d880acb042d733fdd98968d9916f3bca0ef0c7aa31aaca35f6b13a4.png","id":"9hxJNZ8sR2bG7zLS3E","locked":false,"note":"","pleroma":{"accepts_chat_messages":true,"ap_id":"https://shpposter.club/users/shpuld","background_image":null,"confirmation_pending":false,"deactivated":false,"favicon":null,"hide_favorites":true,"hide_followers":true,"hide_followers_count":false,"hide_follows":true,"hide_follows_count":false,"is_admin":false,"is_moderator":false,"relationship":{},"skip_thread_containment":false,"tags":[]},"source":{"fields":[],"note":"","pleroma":{"actor_type":"Person","discoverable":false},"sensitive":false},"statuses_count":62787,"url":"https://shpposter.club/users/shpuld","username":"shpuld"},"created_at":"2021-01-16T11:12:32.000Z","id":"326691","pleroma":{"is_muted":false,"is_seen":false},"status":{"account":{"acct":"shpuld@shpposter.club","avatar":"https://stereophonic.space/proxy/mCyl0lPWgFshoU9vTcm7vvEOSpM/aHR0cHM6Ly9zaHBwb3N0ZXIuY2x1Yi9tZWRpYS82MmUyYTZiNzM1MzZmODBlZmVjOWJjOWY0MDRkMjdhYjMyOTQ2NzkzMDUyZjFiZmRiYjY1Mzc0ZWZlYzc0NWMyLnBuZz9uYW1lPWhhbmRfZHJhd25fZG9yZW15X2ZpLnBuZw/62e2a6b73536f80efec9bc9f404d27ab32946793052f1bfdbb65374efec745c2.png","avatar_static":"https://stereophonic.space/proxy/mCyl0lPWgFshoU9vTcm7vvEOSpM/aHR0cHM6Ly9zaHBwb3N0ZXIuY2x1Yi9tZWRpYS82MmUyYTZiNzM1MzZmODBlZmVjOWJjOWY0MDRkMjdhYjMyOTQ2NzkzMDUyZjFiZmRiYjY1Mzc0ZWZlYzc0NWMyLnBuZz9uYW1lPWhhbmRfZHJhd25fZG9yZW15X2ZpLnBuZw/62e2a6b73536f80efec9bc9f404d27ab32946793052f1bfdbb65374efec745c2.png","bot":false,"created_at":"2019-04-19T05:37:58.000Z","display_name":"shp :blobshp: ","emojis":[{"shortcode":"blobshp","static_url":"https://stereophonic.space/proxy/99gLk4HErQqqLs-IWocZPiUWKVU/aHR0cHM6Ly9zaHBwb3N0ZXIuY2x1Yi9lbW9qaS9jdXN0b20vYmxvYnNocC5wbmc/blobshp.png","url":"https://stereophonic.space/proxy/99gLk4HErQqqLs-IWocZPiUWKVU/aHR0cHM6Ly9zaHBwb3N0ZXIuY2x1Yi9lbW9qaS9jdXN0b20vYmxvYnNocC5wbmc/blobshp.png","visible_in_picker":false}],"fields":[],"followers_count":825,"following_count":172,"header":"https://stereophonic.space/proxy/wqWHtbwjIXRc2V8EJjkS_vWQvzs/aHR0cHM6Ly9zaHBwb3N0ZXIuY2x1Yi9tZWRpYS9mNWIxNzUyMC03YzcwLTQ2MGQtODcxZi03MGUzNjIxY2RkYzYvMDRhNGUwN2Q3ZDg4MGFjYjA0MmQ3MzNmZGQ5ODk2OGQ5OTE2ZjNiY2EwZWYwYzdhYTMxYWFjYTM1ZjZiMTNhNC5wbmc/04a4e07d7d880acb042d733fdd98968d9916f3bca0ef0c7aa31aaca35f6b13a4.png","header_static":"https://stereophonic.space/proxy/wqWHtbwjIXRc2V8EJjkS_vWQvzs/aHR0cHM6Ly9zaHBwb3N0ZXIuY2x1Yi9tZWRpYS9mNWIxNzUyMC03YzcwLTQ2MGQtODcxZi03MGUzNjIxY2RkYzYvMDRhNGUwN2Q3ZDg4MGFjYjA0MmQ3MzNmZGQ5ODk2OGQ5OTE2ZjNiY2EwZWYwYzdhYTMxYWFjYTM1ZjZiMTNhNC5wbmc/04a4e07d7d880acb042d733fdd98968d9916f3bca0ef0c7aa31aaca35f6b13a4.png","id":"9hxJNZ8sR2bG7zLS3E","locked":false,"note":"","pleroma":{"accepts_chat_messages":true,"ap_id":"https://shpposter.club/users/shpuld","background_image":null,"confirmation_pending":false,"deactivated":false,"favicon":null,"hide_favorites":true,"hide_followers":true,"hide_followers_count":false,"hide_follows":true,"hide_follows_count":false,"is_admin":false,"is_moderator":false,"relationship":{},"skip_thread_containment":false,"tags":[]},"source":{"fields":[],"note":"","pleroma":{"actor_type":"Person","discoverable":false},"sensitive":false},"statuses_count":62787,"url":"https://shpposter.club/users/shpuld","username":"shpuld"},"application":{"name":"Web","website":null},"bookmarked":false,"card":null,"content":"<span class=\"h-card\"><a class=\"u-url mention\" data-user=\"9rZ3QjHZi07Ty8NV68\" href=\"https://stereophonic.space/users/newt\">@<span>newt</span></a></span> it&#39;s probably just lacking error handling for some unusual response","created_at":"2021-01-16T11:12:28.000Z","emojis":[],"favourited":false,"favourites_count":0,"id":"A3IF3EhljWNFqMnypU","in_reply_to_account_id":"9rZ2STPb7FA7JnMRii","in_reply_to_id":"A3IEyJ71v2lE46Gpii","language":null,"media_attachments":[],"mentions":[{"acct":"newt","id":"9rZ2STPb7FA7JnMRii","url":"https://stereophonic.space/users/newt","username":"newt"}],"muted":false,"pinned":false,"pleroma":{"content":{"text/plain":"@newt it's probably just lacking error handling for some unusual response"},"conversation_id":20796406,"direct_conversation_id":null,"emoji_reactions":[],"expires_at":null,"in_reply_to_account_acct":"newt","local":false,"parent_visible":true,"spoiler_text":{"text/plain":""},"thread_muted":false},"poll":null,"reblog":null,"reblogged":false,"reblogs_count":0,"replies_count":1,"sensitive":false,"spoiler_text":"","tags":[],"text":null,"uri":"https://shpposter.club/objects/c70f92c2-3d11-4a35-8998-f86ca4eb3da7","url":"https://shpposter.club/objects/c70f92c2-3d11-4a35-8998-f86ca4eb3da7","visibility":"public"},"type":"mention"},{"account":{"acct":"shpuld@shpposter.club","avatar":"https://stereophonic.space/proxy/mCyl0lPWgFshoU9vTcm7vvEOSpM/aHR0cHM6Ly9zaHBwb3N0ZXIuY2x1Yi9tZWRpYS82MmUyYTZiNzM1MzZmODBlZmVjOWJjOWY0MDRkMjdhYjMyOTQ2NzkzMDUyZjFiZmRiYjY1Mzc0ZWZlYzc0NWMyLnBuZz9uYW1lPWhhbmRfZHJhd25fZG9yZW15X2ZpLnBuZw/62e2a6b73536f80efec9bc9f404d27ab32946793052f1bfdbb65374efec745c2.png","avatar_static":"https://stereophonic.space/proxy/mCyl0lPWgFshoU9vTcm7vvEOSpM/aHR0cHM6Ly9zaHBwb3N0ZXIuY2x1Yi9tZWRpYS82MmUyYTZiNzM1MzZmODBlZmVjOWJjOWY0MDRkMjdhYjMyOTQ2NzkzMDUyZjFiZmRiYjY1Mzc0ZWZlYzc0NWMyLnBuZz9uYW1lPWhhbmRfZHJhd25fZG9yZW15X2ZpLnBuZw/62e2a6b73536f80efec9bc9f404d27ab32946793052f1bfdbb65374efec745c2.png","bot":false,"created_at":"2019-04-19T05:37:58.000Z","display_name":"shp :blobshp: ","emojis":[{"shortcode":"blobshp","static_url":"https://stereophonic.space/proxy/99gLk4HErQqqLs-IWocZPiUWKVU/aHR0cHM6Ly9zaHBwb3N0ZXIuY2x1Yi9lbW9qaS9jdXN0b20vYmxvYnNocC5wbmc/blobshp.png","url":"https://stereophonic.space/proxy/99gLk4HErQqqLs-IWocZPiUWKVU/aHR0cHM6Ly9zaHBwb3N0ZXIuY2x1Yi9lbW9qaS9jdXN0b20vYmxvYnNocC5wbmc/blobshp.png","visible_in_picker":false}],"fields":[],"followers_count":825,"following_count":172,"header":"https://stereophonic.space/proxy/wqWHtbwjIXRc2V8EJjkS_vWQvzs/aHR0cHM6Ly9zaHBwb3N0ZXIuY2x1Yi9tZWRpYS9mNWIxNzUyMC03YzcwLTQ2MGQtODcxZi03MGUzNjIxY2RkYzYvMDRhNGUwN2Q3ZDg4MGFjYjA0MmQ3MzNmZGQ5ODk2OGQ5OTE2ZjNiY2EwZWYwYzdhYTMxYWFjYTM1ZjZiMTNhNC5wbmc/04a4e07d7d880acb042d733fdd98968d9916f3bca0ef0c7aa31aaca35f6b13a4.png","header_static":"https://stereophonic.space/proxy/wqWHtbwjIXRc2V8EJjkS_vWQvzs/aHR0cHM6Ly9zaHBwb3N0ZXIuY2x1Yi9tZWRpYS9mNWIxNzUyMC03YzcwLTQ2MGQtODcxZi03MGUzNjIxY2RkYzYvMDRhNGUwN2Q3ZDg4MGFjYjA0MmQ3MzNmZGQ5ODk2OGQ5OTE2ZjNiY2EwZWYwYzdhYTMxYWFjYTM1ZjZiMTNhNC5wbmc/04a4e07d7d880acb042d733fdd98968d9916f3bca0ef0c7aa31aaca35f6b13a4.png","id":"9hxJNZ8sR2bG7zLS3E","locked":false,"note":"","pleroma":{"accepts_chat_messages":true,"ap_id":"https://shpposter.club/users/shpuld","background_image":null,"confirmation_pending":false,"deactivated":false,"favicon":null,"hide_favorites":true,"hide_followers":true,"hide_followers_count":false,"hide_follows":true,"hide_follows_count":false,"is_admin":false,"is_moderator":false,"relationship":{},"skip_thread_containment":false,"tags":[]},"source":{"fields":[],"note":"","pleroma":{"actor_type":"Person","discoverable":false},"sensitive":false},"statuses_count":62787,"url":"https://shpposter.club/users/shpuld","username":"shpuld"},"created_at":"2021-01-16T11:11:10.000Z","id":"326690","pleroma":{"is_muted":false,"is_seen":false},"status":{"account":{"acct":"shpuld@shpposter.club","avatar":"https://stereophonic.space/proxy/mCyl0lPWgFshoU9vTcm7vvEOSpM/aHR0cHM6Ly9zaHBwb3N0ZXIuY2x1Yi9tZWRpYS82MmUyYTZiNzM1MzZmODBlZmVjOWJjOWY0MDRkMjdhYjMyOTQ2NzkzMDUyZjFiZmRiYjY1Mzc0ZWZlYzc0NWMyLnBuZz9uYW1lPWhhbmRfZHJhd25fZG9yZW15X2ZpLnBuZw/62e2a6b73536f80efec9bc9f404d27ab32946793052f1bfdbb65374efec745c2.png","avatar_static":"https://stereophonic.space/proxy/mCyl0lPWgFshoU9vTcm7vvEOSpM/aHR0cHM6Ly9zaHBwb3N0ZXIuY2x1Yi9tZWRpYS82MmUyYTZiNzM1MzZmODBlZmVjOWJjOWY0MDRkMjdhYjMyOTQ2NzkzMDUyZjFiZmRiYjY1Mzc0ZWZlYzc0NWMyLnBuZz9uYW1lPWhhbmRfZHJhd25fZG9yZW15X2ZpLnBuZw/62e2a6b73536f80efec9bc9f404d27ab32946793052f1bfdbb65374efec745c2.png","bot":false,"created_at":"2019-04-19T05:37:58.000Z","display_name":"shp :blobshp: ","emojis":[{"shortcode":"blobshp","static_url":"https://stereophonic.space/proxy/99gLk4HErQqqLs-IWocZPiUWKVU/aHR0cHM6Ly9zaHBwb3N0ZXIuY2x1Yi9lbW9qaS9jdXN0b20vYmxvYnNocC5wbmc/blobshp.png","url":"https://stereophonic.space/proxy/99gLk4HErQqqLs-IWocZPiUWKVU/aHR0cHM6Ly9zaHBwb3N0ZXIuY2x1Yi9lbW9qaS9jdXN0b20vYmxvYnNocC5wbmc/blobshp.png","visible_in_picker":false}],"fields":[],"followers_count":825,"following_count":172,"header":"https://stereophonic.space/proxy/wqWHtbwjIXRc2V8EJjkS_vWQvzs/aHR0cHM6Ly9zaHBwb3N0ZXIuY2x1Yi9tZWRpYS9mNWIxNzUyMC03YzcwLTQ2MGQtODcxZi03MGUzNjIxY2RkYzYvMDRhNGUwN2Q3ZDg4MGFjYjA0MmQ3MzNmZGQ5ODk2OGQ5OTE2ZjNiY2EwZWYwYzdhYTMxYWFjYTM1ZjZiMTNhNC5wbmc/04a4e07d7d880acb042d733fdd98968d9916f3bca0ef0c7aa31aaca35f6b13a4.png","header_static":"https://stereophonic.space/proxy/wqWHtbwjIXRc2V8EJjkS_vWQvzs/aHR0cHM6Ly9zaHBwb3N0ZXIuY2x1Yi9tZWRpYS9mNWIxNzUyMC03YzcwLTQ2MGQtODcxZi03MGUzNjIxY2RkYzYvMDRhNGUwN2Q3ZDg4MGFjYjA0MmQ3MzNmZGQ5ODk2OGQ5OTE2ZjNiY2EwZWYwYzdhYTMxYWFjYTM1ZjZiMTNhNC5wbmc/04a4e07d7d880acb042d733fdd98968d9916f3bca0ef0c7aa31aaca35f6b13a4.png","id":"9hxJNZ8sR2bG7zLS3E","locked":false,"note":"","pleroma":{"accepts_chat_messages":true,"ap_id":"https://shpposter.club/users/shpuld","background_image":null,"confirmation_pending":false,"deactivated":false,"favicon":null,"hide_favorites":true,"hide_followers":true,"hide_followers_count":false,"hide_follows":true,"hide_follows_count":false,"is_admin":false,"is_moderator":false,"relationship":{},"skip_thread_containment":false,"tags":[]},"source":{"fields":[],"note":"","pleroma":{"actor_type":"Person","discoverable":false},"sensitive":false},"statuses_count":62787,"url":"https://shpposter.club/users/shpuld","username":"shpuld"},"application":{"name":"Web","website":null},"bookmarked":false,"card":null,"content":"<span class=\"h-card\"><a class=\"u-url mention\" data-user=\"9rZ3QjHZi07Ty8NV68\" href=\"https://stereophonic.space/users/newt\">@<span>newt</span></a></span> wonder how it ends up like that, must be a bug happening earlier on","created_at":"2021-01-16T11:11:07.000Z","emojis":[],"favourited":false,"favourites_count":0,"id":"A3IEvgoJLzWuh8Gb3I","in_reply_to_account_id":"9rZ2STPb7FA7JnMRii","in_reply_to_id":"A3IEMMxp9Psb0RsGpc","language":null,"media_attachments":[],"mentions":[{"acct":"newt","id":"9rZ2STPb7FA7JnMRii","url":"https://stereophonic.space/users/newt","username":"newt"}],"muted":false,"pinned":false,"pleroma":{"content":{"text/plain":"@newt wonder how it ends up like that, must be a bug happening earlier on"},"conversation_id":20796406,"direct_conversation_id":null,"emoji_reactions":[],"expires_at":null,"in_reply_to_account_acct":"newt","local":false,"parent_visible":true,"spoiler_text":{"text/plain":""},"thread_muted":false},"poll":null,"reblog":null,"reblogged":false,"reblogs_count":0,"replies_count":1,"sensitive":false,"spoiler_text":"","tags":[],"text":null,"uri":"https://shpposter.club/objects/0039c5b9-38be-4285-8feb-b1c6a28d6089","url":"https://shpposter.club/objects/0039c5b9-38be-4285-8feb-b1c6a28d6089","visibility":"public"},"type":"mention"},{"account":{"acct":"Waroorc@shitposter.club","avatar":"https://stereophonic.space/images/avi.png","avatar_static":"https://stereophonic.space/images/avi.png","bot":false,"created_at":"2021-01-16T06:34:18.000Z","display_name":"Plain","emojis":[],"fields":[],"followers_count":0,"following_count":16,"header":"https://stereophonic.space/images/banner.png","header_static":"https://stereophonic.space/images/banner.png","id":"A3HqDk7iTRcpNhW4xM","locked":false,"note":"","pleroma":{"accepts_chat_messages":true,"ap_id":"https://shitposter.club/users/Waroorc","background_image":null,"confirmation_pending":false,"deactivated":false,"favicon":null,"hide_favorites":true,"hide_followers":false,"hide_followers_count":false,"hide_follows":false,"hide_follows_count":false,"is_admin":false,"is_moderator":false,"relationship":{},"skip_thread_containment":false,"tags":[]},"source":{"fields":[],"note":"","pleroma":{"actor_type":"Person","discoverable":false},"sensitive":false},"statuses_count":0,"url":"https://shitposter.club/users/Waroorc","username":"Waroorc"},"created_at":"2021-01-16T06:34:20.000Z","id":"326657","pleroma":{"is_muted":false,"is_seen":false},"type":"follow"},{"account":{"acct":"vaartis@pl.kotobank.ch","avatar":"https://stereophonic.space/proxy/0HXNgAwa0SJSeUQxMYOlw8LuVDs/aHR0cHM6Ly9wbC5rb3RvYmFuay5jaC9tZWRpYS8wMDQyYjQ5OTVkMTc5NTUyNmI3MTkxODY5ZjE3YWM4YmZlOTY2ZGFkOThmMDAxMTc0ZGQzMTNlYWU4N2Q2MzgwLnBuZz9uYW1lPWJsb2IucG5n/0042b4995d1795526b7191869f17ac8bfe966dad98f001174dd313eae87d6380.png","avatar_static":"https://stereophonic.space/proxy/0HXNgAwa0SJSeUQxMYOlw8LuVDs/aHR0cHM6Ly9wbC5rb3RvYmFuay5jaC9tZWRpYS8wMDQyYjQ5OTVkMTc5NTUyNmI3MTkxODY5ZjE3YWM4YmZlOTY2ZGFkOThmMDAxMTc0ZGQzMTNlYWU4N2Q2MzgwLnBuZz9uYW1lPWJsb2IucG5n/0042b4995d1795526b7191869f17ac8bfe966dad98f001174dd313eae87d6380.png","bot":false,"created_at":"2019-04-19T14:13:04.000Z","display_name":"vaartis von BSD-2-Clause","emojis":[],"fields":[],"followers_count":460,"following_count":25,"header":"https://stereophonic.space/proxy/is3uELq2dc3rQ97kqPSdi-uNmq4/aHR0cHM6Ly9wbC5rb3RvYmFuay5jaC9tZWRpYS81Yzk0ODAwM2E2MTk3ODYxZTg5ZmJmY2M4N2JiNDhhOGU1YzA0ZDllYzkxZTc0NjcwOGVmMzIzYzhmMDg2NTI5LnBuZw/5c948003a6197861e89fbfcc87bb48a8e5c04d9ec91e746708ef323c8f086529.png","header_static":"https://stereophonic.space/proxy/is3uELq2dc3rQ97kqPSdi-uNmq4/aHR0cHM6Ly9wbC5rb3RvYmFuay5jaC9tZWRpYS81Yzk0ODAwM2E2MTk3ODYxZTg5ZmJmY2M4N2JiNDhhOGU1YzA0ZDllYzkxZTc0NjcwOGVmMzIzYzhmMDg2NTI5LnBuZw/5c948003a6197861e89fbfcc87bb48a8e5c04d9ec91e746708ef323c8f086529.png","id":"9hy3LjY2BgKJGdssNM","locked":false,"note":"A programmer interested in functional things. Carrot mistress. No stopping till scalies are topping. Just having fun here. Let&#39;s be friends!<br/><br/>profile picture by <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"29\" href=\"https://niu.moe/@rye\">@<span>rye@niu.moe</span></a></span><br/><br/>Github: <a href=\"https://github.com/vaartis\">https://github.com/vaartis</a><br/>Thing I&#39;m working on right now:  <a href=\"https://vaartis.itch.io/someone\">https://vaartis.itch.io/someone</a><br/>liberapay apparently <a href=\"https://liberapay.com/vaartis/\">https://liberapay.com/vaartis/</a><br/>Also a &quot;blog&quot;: <a href=\"https://kotobank.ch/~vaartis/\">https://kotobank.ch/~vaartis/</a><br/><a class=\"hashtag\" data-tag=\"nobot\" href=\"https://pl.kotobank.ch/tag/nobot\">#nobot</a>","pleroma":{"accepts_chat_messages":true,"ap_id":"https://pl.kotobank.ch/users/vaartis","background_image":null,"confirmation_pending":false,"deactivated":false,"favicon":null,"hide_favorites":true,"hide_followers":false,"hide_followers_count":false,"hide_follows":false,"hide_follows_count":false,"is_admin":false,"is_moderator":false,"relationship":{},"skip_thread_containment":false,"tags":[]},"source":{"fields":[],"note":"","pleroma":{"actor_type":"Person","discoverable":false},"sensitive":false},"statuses_count":24597,"url":"https://pl.kotobank.ch/users/vaartis","username":"vaartis"},"created_at":"2021-01-16T05:41:26.000Z","id":"326645","pleroma":{"is_muted":false,"is_seen":false},"status":{"account":{"acct":"vaartis@pl.kotobank.ch","avatar":"https://stereophonic.space/proxy/0HXNgAwa0SJSeUQxMYOlw8LuVDs/aHR0cHM6Ly9wbC5rb3RvYmFuay5jaC9tZWRpYS8wMDQyYjQ5OTVkMTc5NTUyNmI3MTkxODY5ZjE3YWM4YmZlOTY2ZGFkOThmMDAxMTc0ZGQzMTNlYWU4N2Q2MzgwLnBuZz9uYW1lPWJsb2IucG5n/0042b4995d1795526b7191869f17ac8bfe966dad98f001174dd313eae87d6380.png","avatar_static":"https://stereophonic.space/proxy/0HXNgAwa0SJSeUQxMYOlw8LuVDs/aHR0cHM6Ly9wbC5rb3RvYmFuay5jaC9tZWRpYS8wMDQyYjQ5OTVkMTc5NTUyNmI3MTkxODY5ZjE3YWM4YmZlOTY2ZGFkOThmMDAxMTc0ZGQzMTNlYWU4N2Q2MzgwLnBuZz9uYW1lPWJsb2IucG5n/0042b4995d1795526b7191869f17ac8bfe966dad98f001174dd313eae87d6380.png","bot":false,"created_at":"2019-04-19T14:13:04.000Z","display_name":"vaartis von BSD-2-Clause","emojis":[],"fields":[],"followers_count":460,"following_count":25,"header":"https://stereophonic.space/proxy/is3uELq2dc3rQ97kqPSdi-uNmq4/aHR0cHM6Ly9wbC5rb3RvYmFuay5jaC9tZWRpYS81Yzk0ODAwM2E2MTk3ODYxZTg5ZmJmY2M4N2JiNDhhOGU1YzA0ZDllYzkxZTc0NjcwOGVmMzIzYzhmMDg2NTI5LnBuZw/5c948003a6197861e89fbfcc87bb48a8e5c04d9ec91e746708ef323c8f086529.png","header_static":"https://stereophonic.space/proxy/is3uELq2dc3rQ97kqPSdi-uNmq4/aHR0cHM6Ly9wbC5rb3RvYmFuay5jaC9tZWRpYS81Yzk0ODAwM2E2MTk3ODYxZTg5ZmJmY2M4N2JiNDhhOGU1YzA0ZDllYzkxZTc0NjcwOGVmMzIzYzhmMDg2NTI5LnBuZw/5c948003a6197861e89fbfcc87bb48a8e5c04d9ec91e746708ef323c8f086529.png","id":"9hy3LjY2BgKJGdssNM","locked":false,"note":"A programmer interested in functional things. Carrot mistress. No stopping till scalies are topping. Just having fun here. Let&#39;s be friends!<br/><br/>profile picture by <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"29\" href=\"https://niu.moe/@rye\">@<span>rye@niu.moe</span></a></span><br/><br/>Github: <a href=\"https://github.com/vaartis\">https://github.com/vaartis</a><br/>Thing I&#39;m working on right now:  <a href=\"https://vaartis.itch.io/someone\">https://vaartis.itch.io/someone</a><br/>liberapay apparently <a href=\"https://liberapay.com/vaartis/\">https://liberapay.com/vaartis/</a><br/>Also a &quot;blog&quot;: <a href=\"https://kotobank.ch/~vaartis/\">https://kotobank.ch/~vaartis/</a><br/><a class=\"hashtag\" data-tag=\"nobot\" href=\"https://pl.kotobank.ch/tag/nobot\">#nobot</a>","pleroma":{"accepts_chat_messages":true,"ap_id":"https://pl.kotobank.ch/users/vaartis","background_image":null,"confirmation_pending":false,"deactivated":false,"favicon":null,"hide_favorites":true,"hide_followers":false,"hide_followers_count":false,"hide_follows":false,"hide_follows_count":false,"is_admin":false,"is_moderator":false,"relationship":{},"skip_thread_containment":false,"tags":[]},"source":{"fields":[],"note":"","pleroma":{"actor_type":"Person","discoverable":false},"sensitive":false},"statuses_count":24597,"url":"https://pl.kotobank.ch/users/vaartis","username":"vaartis"},"application":{"name":"Web","website":null},"bookmarked":false,"card":null,"content":"<span class=\"h-card\"><a class=\"u-url mention\" data-user=\"9qrXalMYDhWHvvVp20\" href=\"https://lain.com/users/lain\">@<span>lain</span></a></span> <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"9rZ3M7j3axae1l5XFo\" href=\"https://stereophonic.space/users/newt\">@<span>newt</span></a></span> not durov that&#39;s for sure, probably not others too. he moved from russia a while ago and probably took the team with him.","created_at":"2021-01-16T05:40:00.000Z","emojis":[],"favourited":false,"favourites_count":0,"id":"A3HlVARLNor49XBc5Q","in_reply_to_account_id":"9qrXewWxfr80iavPVY","in_reply_to_id":"A3HHdH3JgWNoLvtgXY","language":null,"media_attachments":[],"mentions":[{"acct":"lain@lain.com","id":"9qrXewWxfr80iavPVY","url":"https://lain.com/users/lain","username":"lain"},{"acct":"newt","id":"9rZ2STPb7FA7JnMRii","url":"https://stereophonic.space/users/newt","username":"newt"}],"muted":false,"pinned":false,"pleroma":{"content":{"text/plain":"@lain @newt not durov that's for sure, probably not others too. he moved from russia a while ago and probably took the team with him."},"conversation_id":20784105,"direct_conversation_id":null,"emoji_reactions":[],"expires_at":null,"in_reply_to_account_acct":"lain@lain.com","local":false,"parent_visible":true,"spoiler_text":{"text/plain":""},"thread_muted":false},"poll":null,"reblog":null,"reblogged":false,"reblogs_count":0,"replies_count":0,"sensitive":false,"spoiler_text":"","tags":[],"text":null,"uri":"https://pl.kotobank.ch/objects/bc8f0ce9-978d-4834-860e-c828a66d2074","url":"https://pl.kotobank.ch/objects/bc8f0ce9-978d-4834-860e-c828a66d2074","visibility":"public"},"type":"mention"},{"account":{"acct":"luka@neue.city","avatar":"https://stereophonic.space/proxy/hyI6Cu5NNjQu62uAngvPZuDkbdc/aHR0cHM6Ly9uZXVlLmNpdHkvbWVkaWEvM2Q4NWU3NjA4YmIxOWVjZTE0ZDJhNmE4ZWM2YzdiNDc0OTAxN2YwMjA0MTQ4YWZmZTMxMmU1NDhkZGE0ZDQ0Zi5ibG9iP25hbWU9YmxvYg/3d85e7608bb19ece14d2a6a8ec6c7b4749017f0204148affe312e548dda4d44f.blob","avatar_static":"https://stereophonic.space/proxy/hyI6Cu5NNjQu62uAngvPZuDkbdc/aHR0cHM6Ly9uZXVlLmNpdHkvbWVkaWEvM2Q4NWU3NjA4YmIxOWVjZTE0ZDJhNmE4ZWM2YzdiNDc0OTAxN2YwMjA0MTQ4YWZmZTMxMmU1NDhkZGE0ZDQ0Zi5ibG9iP25hbWU9YmxvYg/3d85e7608bb19ece14d2a6a8ec6c7b4749017f0204148affe312e548dda4d44f.blob","bot":false,"created_at":"2021-01-13T18:23:51.000Z","display_name":"Luke N. Arnold","emojis":[],"fields":[{"name":"Website","value":"<a href=\"http://lukalot.github.io\">lukalot.github.io</a>"},{"name":"Discord","value":"Lukalot#9396 [DM before friend rq please]"}],"followers_count":0,"following_count":0,"header":"https://stereophonic.space/proxy/yaeK5HPDQ4_HiD-Omhma3mz3DkQ/aHR0cHM6Ly9uZXVlLmNpdHkvbWVkaWEvZWUxMjgwMjc4M2FlYjFlYTY2ODA1Y2JiYmI1NDg5Nzg1OWRkYmVhNTk5NjZkN2I5YzhmZDIyNmUxNWNhYzgwYy5wbmc_bmFtZT1nYWxsZXJ5SW1hZ2UucG5n/ee12802783aeb1ea66805cbbbb54897859ddbea59966d7b9c8fd226e15cac80c.png","header_static":"https://stereophonic.space/proxy/yaeK5HPDQ4_HiD-Omhma3mz3DkQ/aHR0cHM6Ly9uZXVlLmNpdHkvbWVkaWEvZWUxMjgwMjc4M2FlYjFlYTY2ODA1Y2JiYmI1NDg5Nzg1OWRkYmVhNTk5NjZkN2I5YzhmZDIyNmUxNWNhYzgwYy5wbmc_bmFtZT1nYWxsZXJ5SW1hZ2UucG5n/ee12802783aeb1ea66805cbbbb54897859ddbea59966d7b9c8fd226e15cac80c.png","id":"A3Ce0HWnJGSPgmGHLc","locked":false,"note":"An artist and programmer. Besides those, I also love games, 1960&#39;s music, and reading (especially science fiction and horror). Feel free to message me here or on Discord.","pleroma":{"accepts_chat_messages":true,"ap_id":"https://neue.city/users/luka","background_image":null,"confirmation_pending":false,"deactivated":false,"favicon":null,"hide_favorites":true,"hide_followers":false,"hide_followers_count":false,"hide_follows":false,"hide_follows_count":false,"is_admin":false,"is_moderator":false,"relationship":{},"skip_thread_containment":false,"tags":[]},"source":{"fields":[],"note":"","pleroma":{"actor_type":"Person","discoverable":true},"sensitive":false},"statuses_count":18,"url":"https://neue.city/users/luka","username":"luka"},"created_at":"2021-01-16T03:44:02.000Z","id":"326632","pleroma":{"is_muted":false,"is_seen":false},"status":null,"type":"favourite"},{"account":{"acct":"partridge@elves.forsale","avatar":"https://stereophonic.space/proxy/VWcL6_S5CE_pg4cMux08AcHUyeo/aHR0cHM6Ly9lbHZlcy5mb3JzYWxlL21lZGlhL2Y5OTQ3MGE4ZmExOTM2ZGY0YTMzZWIxZTgwYjg2NDFmMjNiMmYxM2Y1MjdjN2RkNjUzMTczNWMwYzRmZDhmNDEuanBnP25hbWU9YmxvYi5qcGc/f99470a8fa1936df4a33eb1e80b8641f23b2f13f527c7dd6531735c0c4fd8f41.jpg","avatar_static":"https://stereophonic.space/proxy/VWcL6_S5CE_pg4cMux08AcHUyeo/aHR0cHM6Ly9lbHZlcy5mb3JzYWxlL21lZGlhL2Y5OTQ3MGE4ZmExOTM2ZGY0YTMzZWIxZTgwYjg2NDFmMjNiMmYxM2Y1MjdjN2RkNjUzMTczNWMwYzRmZDhmNDEuanBnP25hbWU9YmxvYi5qcGc/f99470a8fa1936df4a33eb1e80b8641f23b2f13f527c7dd6531735c0c4fd8f41.jpg","bot":false,"created_at":"2019-09-18T01:59:25.000Z","display_name":"parts","emojis":[],"fields":[{"name":"xmpp","value":"this username at xmpp dot co"},{"name":"o meme finger print","value":"69711de9 177a7aa0 54b117ce b2e3a9e7 1cb043cd 14120454 6f32102f c35fbb13"}],"followers_count":186,"following_count":224,"header":"https://stereophonic.space/proxy/6U6F7vWd-KNewAY6XXa-5JbpIdM/aHR0cHM6Ly9lbHZlcy5mb3JzYWxlL21lZGlhLzNmZWMxOTJiMWJjMWEzOGFlYTcwZmM2YzAyNGVlZGYxZDQyOGVkNWRkNGFiNTZhYTI3MWJhNjRmZDBiNTY0NmMuZ2lmP25hbWU9aGlnaF9lbGZfZHJpbmsuZ2lm/3fec192b1bc1a38aea70fc6c024eedf1d428ed5dd4ab56aa271ba64fd0b5646c.gif","header_static":"https://stereophonic.space/proxy/6U6F7vWd-KNewAY6XXa-5JbpIdM/aHR0cHM6Ly9lbHZlcy5mb3JzYWxlL21lZGlhLzNmZWMxOTJiMWJjMWEzOGFlYTcwZmM2YzAyNGVlZGYxZDQyOGVkNWRkNGFiNTZhYTI3MWJhNjRmZDBiNTY0NmMuZ2lmP25hbWU9aGlnaF9lbGZfZHJpbmsuZ2lm/3fec192b1bc1a38aea70fc6c024eedf1d428ed5dd4ab56aa271ba64fd0b5646c.gif","id":"9n23ySvRj1DdWtVq64","locked":false,"note":"vibing and imbibing<br/>unapologetic meltyblood player<br/>admin of this bastard fucking instance<br/><br/>he/him 22 years mtl<br/>i post lewds but i always click the little checkbox so it&#39;s fine<br/>","pleroma":{"accepts_chat_messages":true,"ap_id":"https://elves.forsale/users/partridge","background_image":null,"confirmation_pending":false,"deactivated":false,"favicon":null,"hide_favorites":true,"hide_followers":true,"hide_followers_count":false,"hide_follows":true,"hide_follows_count":false,"is_admin":false,"is_moderator":false,"relationship":{},"skip_thread_containment":false,"tags":[]},"source":{"fields":[],"note":"","pleroma":{"actor_type":"Person","discoverable":false},"sensitive":false},"statuses_count":3299,"url":"https://elves.forsale/users/partridge","username":"partridge"},"created_at":"2021-01-16T03:35:05.000Z","id":"326631","pleroma":{"is_muted":false,"is_seen":false},"status":{"account":{"acct":"partridge@elves.forsale","avatar":"https://stereophonic.space/proxy/VWcL6_S5CE_pg4cMux08AcHUyeo/aHR0cHM6Ly9lbHZlcy5mb3JzYWxlL21lZGlhL2Y5OTQ3MGE4ZmExOTM2ZGY0YTMzZWIxZTgwYjg2NDFmMjNiMmYxM2Y1MjdjN2RkNjUzMTczNWMwYzRmZDhmNDEuanBnP25hbWU9YmxvYi5qcGc/f99470a8fa1936df4a33eb1e80b8641f23b2f13f527c7dd6531735c0c4fd8f41.jpg","avatar_static":"https://stereophonic.space/proxy/VWcL6_S5CE_pg4cMux08AcHUyeo/aHR0cHM6Ly9lbHZlcy5mb3JzYWxlL21lZGlhL2Y5OTQ3MGE4ZmExOTM2ZGY0YTMzZWIxZTgwYjg2NDFmMjNiMmYxM2Y1MjdjN2RkNjUzMTczNWMwYzRmZDhmNDEuanBnP25hbWU9YmxvYi5qcGc/f99470a8fa1936df4a33eb1e80b8641f23b2f13f527c7dd6531735c0c4fd8f41.jpg","bot":false,"created_at":"2019-09-18T01:59:25.000Z","display_name":"parts","emojis":[],"fields":[{"name":"xmpp","value":"this username at xmpp dot co"},{"name":"o meme finger print","value":"69711de9 177a7aa0 54b117ce b2e3a9e7 1cb043cd 14120454 6f32102f c35fbb13"}],"followers_count":186,"following_count":224,"header":"https://stereophonic.space/proxy/6U6F7vWd-KNewAY6XXa-5JbpIdM/aHR0cHM6Ly9lbHZlcy5mb3JzYWxlL21lZGlhLzNmZWMxOTJiMWJjMWEzOGFlYTcwZmM2YzAyNGVlZGYxZDQyOGVkNWRkNGFiNTZhYTI3MWJhNjRmZDBiNTY0NmMuZ2lmP25hbWU9aGlnaF9lbGZfZHJpbmsuZ2lm/3fec192b1bc1a38aea70fc6c024eedf1d428ed5dd4ab56aa271ba64fd0b5646c.gif","header_static":"https://stereophonic.space/proxy/6U6F7vWd-KNewAY6XXa-5JbpIdM/aHR0cHM6Ly9lbHZlcy5mb3JzYWxlL21lZGlhLzNmZWMxOTJiMWJjMWEzOGFlYTcwZmM2YzAyNGVlZGYxZDQyOGVkNWRkNGFiNTZhYTI3MWJhNjRmZDBiNTY0NmMuZ2lmP25hbWU9aGlnaF9lbGZfZHJpbmsuZ2lm/3fec192b1bc1a38aea70fc6c024eedf1d428ed5dd4ab56aa271ba64fd0b5646c.gif","id":"9n23ySvRj1DdWtVq64","locked":false,"note":"vibing and imbibing<br/>unapologetic meltyblood player<br/>admin of this bastard fucking instance<br/><br/>he/him 22 years mtl<br/>i post lewds but i always click the little checkbox so it&#39;s fine<br/>","pleroma":{"accepts_chat_messages":true,"ap_id":"https://elves.forsale/users/partridge","background_image":null,"confirmation_pending":false,"deactivated":false,"favicon":null,"hide_favorites":true,"hide_followers":true,"hide_followers_count":false,"hide_follows":true,"hide_follows_count":false,"is_admin":false,"is_moderator":false,"relationship":{},"skip_thread_containment":false,"tags":[]},"source":{"fields":[],"note":"","pleroma":{"actor_type":"Person","discoverable":false},"sensitive":false},"statuses_count":3299,"url":"https://elves.forsale/users/partridge","username":"partridge"},"application":{"name":"Web","website":null},"bookmarked":false,"card":null,"content":"<span class=\"h-card\"><a class=\"u-url mention\" data-user=\"9rZ7rGwYdtPCJPWDCq\" href=\"https://stereophonic.space/users/newt\">@<span>newt</span></a></span> my favorite hn post was someone complaining about people who are always down on big companies like amazon, only to have someone point out that their previous comment said &quot;i own 500k in amazon stock&quot;","created_at":"2021-01-16T03:35:02.000Z","emojis":[],"favourited":true,"favourites_count":3,"id":"A3HaE2iHl6yJlnk5Ym","in_reply_to_account_id":null,"in_reply_to_id":null,"language":null,"media_attachments":[],"mentions":[{"acct":"newt","id":"9rZ2STPb7FA7JnMRii","url":"https://stereophonic.space/users/newt","username":"newt"}],"muted":false,"pinned":false,"pleroma":{"content":{"text/plain":"@newt my favorite hn post was someone complaining about people who are always down on big companies like amazon, only to have someone point out that their previous comment said \"i own 500k in amazon stock\""},"conversation_id":17495909,"direct_conversation_id":null,"emoji_reactions":[],"expires_at":null,"in_reply_to_account_acct":null,"local":false,"parent_visible":false,"spoiler_text":{"text/plain":""},"thread_muted":false},"poll":null,"reblog":null,"reblogged":false,"reblogs_count":0,"replies_count":0,"sensitive":false,"spoiler_text":"","tags":[],"text":null,"uri":"https://elves.forsale/objects/289e8337-a4f4-40ca-813d-4d8913292bfb","url":"https://elves.forsale/objects/289e8337-a4f4-40ca-813d-4d8913292bfb","visibility":"public"},"type":"mention"},{"account":{"acct":"gaige@neue.city","avatar":"https://stereophonic.space/proxy/yFMKYiPRb7HqOOqoBvIlE48pOQ4/aHR0cHM6Ly9uZXVlLmNpdHkvbWVkaWEvMDIyZTEyZmFlNTI4NjdlMDA5NDQ2Yjc5YWI5ZjIwZWM4ZjhiOTRhNGEyZGZhNjAzODE0NThiMDFiNjBjZGIxMy5ibG9iP25hbWU9YmxvYg/022e12fae52867e009446b79ab9f20ec8f8b94a4a2dfa60381458b01b60cdb13.blob","avatar_static":"https://stereophonic.space/proxy/yFMKYiPRb7HqOOqoBvIlE48pOQ4/aHR0cHM6Ly9uZXVlLmNpdHkvbWVkaWEvMDIyZTEyZmFlNTI4NjdlMDA5NDQ2Yjc5YWI5ZjIwZWM4ZjhiOTRhNGEyZGZhNjAzODE0NThiMDFiNjBjZGIxMy5ibG9iP25hbWU9YmxvYg/022e12fae52867e009446b79ab9f20ec8f8b94a4a2dfa60381458b01b60cdb13.blob","bot":false,"created_at":"2020-03-25T21:35:16.000Z","display_name":"working vala :verifiedsabakan: ","emojis":[{"shortcode":"asukaPout","static_url":"https://stereophonic.space/proxy/zyFns5kHTDRfUxyv8bmFKpz1wko/aHR0cHM6Ly9uZXVlLmNpdHkvZW1vamkvYXN1a2EvYXN1a2FQb3V0LnBuZw/asukaPout.png","url":"https://stereophonic.space/proxy/zyFns5kHTDRfUxyv8bmFKpz1wko/aHR0cHM6Ly9uZXVlLmNpdHkvZW1vamkvYXN1a2EvYXN1a2FQb3V0LnBuZw/asukaPout.png","visible_in_picker":false},{"shortcode":"cirno_comfy","static_url":"https://stereophonic.space/proxy/WfKLe9y4M6QFIOiHG-ulR8RDuSs/aHR0cHM6Ly9uZXVlLmNpdHkvZW1vamkvdG91aG91L2Npcm5vX2NvbWZ5LnBuZw/cirno_comfy.png","url":"https://stereophonic.space/proxy/WfKLe9y4M6QFIOiHG-ulR8RDuSs/aHR0cHM6Ly9uZXVlLmNpdHkvZW1vamkvdG91aG91L2Npcm5vX2NvbWZ5LnBuZw/cirno_comfy.png","visible_in_picker":false},{"shortcode":"corndog","static_url":"https://stereophonic.space/proxy/2zCawCx7ox2BRrf3MqaSqGIpngo/aHR0cHM6Ly9uZXVlLmNpdHkvZW1vamkvdG91aG91L2Nvcm5kb2cucG5n/corndog.png","url":"https://stereophonic.space/proxy/2zCawCx7ox2BRrf3MqaSqGIpngo/aHR0cHM6Ly9uZXVlLmNpdHkvZW1vamkvdG91aG91L2Nvcm5kb2cucG5n/corndog.png","visible_in_picker":false},{"shortcode":"debian","static_url":"https://stereophonic.space/proxy/w_tO63_AjzH9E7fIZci-GhWInfY/aHR0cHM6Ly9uZXVlLmNpdHkvZW1vamkvZGlzdHJvcy9kZWJpYW4ucG5n/debian.png","url":"https://stereophonic.space/proxy/w_tO63_AjzH9E7fIZci-GhWInfY/aHR0cHM6Ly9uZXVlLmNpdHkvZW1vamkvZGlzdHJvcy9kZWJpYW4ucG5n/debian.png","visible_in_picker":false},{"shortcode":"lain","static_url":"https://stereophonic.space/proxy/d8hdGpQW9LYFeFRNhH8qAnNhzLs/aHR0cHM6Ly9uZXVlLmNpdHkvZW1vamkvbGFpbi9sYWluLnBuZw/lain.png","url":"https://stereophonic.space/proxy/d8hdGpQW9LYFeFRNhH8qAnNhzLs/aHR0cHM6Ly9uZXVlLmNpdHkvZW1vamkvbGFpbi9sYWluLnBuZw/lain.png","visible_in_picker":false},{"shortcode":"pleroma_seal","static_url":"https://stereophonic.space/proxy/CQNil1-oQ_V48yrp1rwIgUhnhpY/aHR0cHM6Ly9uZXVlLmNpdHkvZW1vamkvbWVtZXMvcGxlcm9tYV9zZWFsLnBuZw/pleroma_seal.png","url":"https://stereophonic.space/proxy/CQNil1-oQ_V48yrp1rwIgUhnhpY/aHR0cHM6Ly9uZXVlLmNpdHkvZW1vamkvbWVtZXMvcGxlcm9tYV9zZWFsLnBuZw/pleroma_seal.png","visible_in_picker":false},{"shortcode":"raveSmug","static_url":"https://stereophonic.space/proxy/bQ4W7oLEiYgF7z0_lsW2WLeCfeQ/aHR0cHM6Ly9uZXVlLmNpdHkvZW1vamkvY3VzdG9tL3JhdmVTbXVnLnBuZw/raveSmug.png","url":"https://stereophonic.space/proxy/bQ4W7oLEiYgF7z0_lsW2WLeCfeQ/aHR0cHM6Ly9uZXVlLmNpdHkvZW1vamkvY3VzdG9tL3JhdmVTbXVnLnBuZw/raveSmug.png","visible_in_picker":false},{"shortcode":"sataniaNoBulli","static_url":"https://stereophonic.space/proxy/b0DL-MeIUvqdPN0zJwkCT8KIaSc/aHR0cHM6Ly9uZXVlLmNpdHkvZW1vamkvYW5pbWUvc2F0YW5pYU5vQnVsbGkucG5n/sataniaNoBulli.png","url":"https://stereophonic.space/proxy/b0DL-MeIUvqdPN0zJwkCT8KIaSc/aHR0cHM6Ly9uZXVlLmNpdHkvZW1vamkvYW5pbWUvc2F0YW5pYU5vQnVsbGkucG5n/sataniaNoBulli.png","visible_in_picker":false},{"shortcode":"verifiedsabakan","static_url":"https://stereophonic.space/proxy/MbUaXLpXh3ZK7ehIKZqDoyZaCqU/aHR0cHM6Ly9uZXVlLmNpdHkvZW1vamkvbGFiZWxzL3ZlcmlmaWVkc2FiYWthbi5wbmc/verifiedsabakan.png","url":"https://stereophonic.space/proxy/MbUaXLpXh3ZK7ehIKZqDoyZaCqU/aHR0cHM6Ly9uZXVlLmNpdHkvZW1vamkvbGFiZWxzL3ZlcmlmaWVkc2FiYWthbi5wbmc/verifiedsabakan.png","visible_in_picker":false},{"shortcode":"welovelain","static_url":"https://stereophonic.space/proxy/hAlsiSzic1IqFo-G9w3ZWerAg6Q/aHR0cHM6Ly9uZXVlLmNpdHkvZW1vamkvY3VzdG9tL3dlbG92ZWxhaW4ucG5n/welovelain.png","url":"https://stereophonic.space/proxy/hAlsiSzic1IqFo-G9w3ZWerAg6Q/aHR0cHM6Ly9uZXVlLmNpdHkvZW1vamkvY3VzdG9tL3dlbG92ZWxhaW4ucG5n/welovelain.png","visible_in_picker":false}],"fields":[{"name":"cofe?","value":"hell yeah."},{"name":"blÃ¥haj?","value":"everyday."},{"name":"urbit","value":"~difreg-dasrys"},{"name":"alt. account","value":"<a href=\"https://lets.bemoe.online/users/vala\" rel=\"ugc\">@vala@lets.bemoe.online</a>"},{"name":"xmpp","value":"<a href=\"xmpp://vala@neue.city\">xmpp://vala@neue.city</a>"},{"name":"gacha","value":"sucker"}],"followers_count":147,"following_count":78,"header":"https://stereophonic.space/proxy/algbU9JR1QK-UVTeekBSp30CDLQ/aHR0cHM6Ly9uZXVlLmNpdHkvbWVkaWEvM2Q2YzA5MDZmZDg2ZjgyZTY3YTY1OGQ2MDAxOTc1N2EyNjIwOWIyNGNkZjkwZTgxNzBlMWI5Njg2MWQ1ZjkxOC5qcGc_bmFtZT1CMDA1NTQ4LVIxLTE1LTE0QS5qcGc/3d6c0906fd86f82e67a658d60019757a26209b24cdf90e8170e1b96861d5f918.jpg","header_static":"https://stereophonic.space/proxy/algbU9JR1QK-UVTeekBSp30CDLQ/aHR0cHM6Ly9uZXVlLmNpdHkvbWVkaWEvM2Q2YzA5MDZmZDg2ZjgyZTY3YTY1OGQ2MDAxOTc1N2EyNjIwOWIyNGNkZjkwZTgxNzBlMWI5Njg2MWQ1ZjkxOC5qcGc_bmFtZT1CMDA1NTQ4LVIxLTE1LTE0QS5qcGc/3d6c0906fd86f82e67a658d60019757a26209b24cdf90e8170e1b96861d5f918.jpg","id":"9tO7DH9HqBbxkWv3gG","locked":false,"note":"â•±â•³â•²â•±â•³â•²â•±â•³â•²â•±â•³â•²â•±â•³â•²â•±â•³â•²â•±â•³â•²<br/>gaige or vala<br/>comes from a land of ice and snow :cirno_comfy:<br/><br/>just imagine every word i ever say, in cursive comic sans<br/>i generally float around here while being a â‘¨<br/><br/>:corndog: the official server-maid in this pleroma neighbourhood of the fediverse :pleroma_seal:<br/>i cant program in anything<br/><br/>used to post at <a href=\"http://ilovela.in\">ilovela.in</a> and <a href=\"http://welovela.in\">welovela.in</a> :welovelain:<br/><br/>will judge you for your taste in cars<br/>â•±â•³â•²â•±â•³â•²â•±â•³â•²â•±â•³â•²â•±â•³â•²â•±â•³â•²â•±â•³â•²<br/>:debian: :lain: :raveSmug: :sataniaNoBulli:  :asukaPout:","pleroma":{"accepts_chat_messages":true,"ap_id":"https://neue.city/users/gaige","background_image":null,"confirmation_pending":false,"deactivated":false,"favicon":null,"hide_favorites":true,"hide_followers":false,"hide_followers_count":false,"hide_follows":false,"hide_follows_count":false,"is_admin":false,"is_moderator":false,"relationship":{},"skip_thread_containment":false,"tags":[]},"source":{"fields":[],"note":"","pleroma":{"actor_type":"Person","discoverable":true},"sensitive":false},"statuses_count":5946,"url":"https://neue.city/users/gaige","username":"gaige"},"created_at":"2021-01-16T03:33:28.000Z","id":"326630","pleroma":{"is_muted":false,"is_seen":false},"status":null,"type":"favourite"},{"account":{"acct":"gaige@neue.city","avatar":"https://stereophonic.space/proxy/yFMKYiPRb7HqOOqoBvIlE48pOQ4/aHR0cHM6Ly9uZXVlLmNpdHkvbWVkaWEvMDIyZTEyZmFlNTI4NjdlMDA5NDQ2Yjc5YWI5ZjIwZWM4ZjhiOTRhNGEyZGZhNjAzODE0NThiMDFiNjBjZGIxMy5ibG9iP25hbWU9YmxvYg/022e12fae52867e009446b79ab9f20ec8f8b94a4a2dfa60381458b01b60cdb13.blob","avatar_static":"https://stereophonic.space/proxy/yFMKYiPRb7HqOOqoBvIlE48pOQ4/aHR0cHM6Ly9uZXVlLmNpdHkvbWVkaWEvMDIyZTEyZmFlNTI4NjdlMDA5NDQ2Yjc5YWI5ZjIwZWM4ZjhiOTRhNGEyZGZhNjAzODE0NThiMDFiNjBjZGIxMy5ibG9iP25hbWU9YmxvYg/022e12fae52867e009446b79ab9f20ec8f8b94a4a2dfa60381458b01b60cdb13.blob","bot":false,"created_at":"2020-03-25T21:35:16.000Z","display_name":"working vala :verifiedsabakan: ","emojis":[{"shortcode":"asukaPout","static_url":"https://stereophonic.space/proxy/zyFns5kHTDRfUxyv8bmFKpz1wko/aHR0cHM6Ly9uZXVlLmNpdHkvZW1vamkvYXN1a2EvYXN1a2FQb3V0LnBuZw/asukaPout.png","url":"https://stereophonic.space/proxy/zyFns5kHTDRfUxyv8bmFKpz1wko/aHR0cHM6Ly9uZXVlLmNpdHkvZW1vamkvYXN1a2EvYXN1a2FQb3V0LnBuZw/asukaPout.png","visible_in_picker":false},{"shortcode":"cirno_comfy","static_url":"https://stereophonic.space/proxy/WfKLe9y4M6QFIOiHG-ulR8RDuSs/aHR0cHM6Ly9uZXVlLmNpdHkvZW1vamkvdG91aG91L2Npcm5vX2NvbWZ5LnBuZw/cirno_comfy.png","url":"https://stereophonic.space/proxy/WfKLe9y4M6QFIOiHG-ulR8RDuSs/aHR0cHM6Ly9uZXVlLmNpdHkvZW1vamkvdG91aG91L2Npcm5vX2NvbWZ5LnBuZw/cirno_comfy.png","visible_in_picker":false},{"shortcode":"corndog","static_url":"https://stereophonic.space/proxy/2zCawCx7ox2BRrf3MqaSqGIpngo/aHR0cHM6Ly9uZXVlLmNpdHkvZW1vamkvdG91aG91L2Nvcm5kb2cucG5n/corndog.png","url":"https://stereophonic.space/proxy/2zCawCx7ox2BRrf3MqaSqGIpngo/aHR0cHM6Ly9uZXVlLmNpdHkvZW1vamkvdG91aG91L2Nvcm5kb2cucG5n/corndog.png","visible_in_picker":false},{"shortcode":"debian","static_url":"https://stereophonic.space/proxy/w_tO63_AjzH9E7fIZci-GhWInfY/aHR0cHM6Ly9uZXVlLmNpdHkvZW1vamkvZGlzdHJvcy9kZWJpYW4ucG5n/debian.png","url":"https://stereophonic.space/proxy/w_tO63_AjzH9E7fIZci-GhWInfY/aHR0cHM6Ly9uZXVlLmNpdHkvZW1vamkvZGlzdHJvcy9kZWJpYW4ucG5n/debian.png","visible_in_picker":false},{"shortcode":"lain","static_url":"https://stereophonic.space/proxy/d8hdGpQW9LYFeFRNhH8qAnNhzLs/aHR0cHM6Ly9uZXVlLmNpdHkvZW1vamkvbGFpbi9sYWluLnBuZw/lain.png","url":"https://stereophonic.space/proxy/d8hdGpQW9LYFeFRNhH8qAnNhzLs/aHR0cHM6Ly9uZXVlLmNpdHkvZW1vamkvbGFpbi9sYWluLnBuZw/lain.png","visible_in_picker":false},{"shortcode":"pleroma_seal","static_url":"https://stereophonic.space/proxy/CQNil1-oQ_V48yrp1rwIgUhnhpY/aHR0cHM6Ly9uZXVlLmNpdHkvZW1vamkvbWVtZXMvcGxlcm9tYV9zZWFsLnBuZw/pleroma_seal.png","url":"https://stereophonic.space/proxy/CQNil1-oQ_V48yrp1rwIgUhnhpY/aHR0cHM6Ly9uZXVlLmNpdHkvZW1vamkvbWVtZXMvcGxlcm9tYV9zZWFsLnBuZw/pleroma_seal.png","visible_in_picker":false},{"shortcode":"raveSmug","static_url":"https://stereophonic.space/proxy/bQ4W7oLEiYgF7z0_lsW2WLeCfeQ/aHR0cHM6Ly9uZXVlLmNpdHkvZW1vamkvY3VzdG9tL3JhdmVTbXVnLnBuZw/raveSmug.png","url":"https://stereophonic.space/proxy/bQ4W7oLEiYgF7z0_lsW2WLeCfeQ/aHR0cHM6Ly9uZXVlLmNpdHkvZW1vamkvY3VzdG9tL3JhdmVTbXVnLnBuZw/raveSmug.png","visible_in_picker":false},{"shortcode":"sataniaNoBulli","static_url":"https://stereophonic.space/proxy/b0DL-MeIUvqdPN0zJwkCT8KIaSc/aHR0cHM6Ly9uZXVlLmNpdHkvZW1vamkvYW5pbWUvc2F0YW5pYU5vQnVsbGkucG5n/sataniaNoBulli.png","url":"https://stereophonic.space/proxy/b0DL-MeIUvqdPN0zJwkCT8KIaSc/aHR0cHM6Ly9uZXVlLmNpdHkvZW1vamkvYW5pbWUvc2F0YW5pYU5vQnVsbGkucG5n/sataniaNoBulli.png","visible_in_picker":false},{"shortcode":"verifiedsabakan","static_url":"https://stereophonic.space/proxy/MbUaXLpXh3ZK7ehIKZqDoyZaCqU/aHR0cHM6Ly9uZXVlLmNpdHkvZW1vamkvbGFiZWxzL3ZlcmlmaWVkc2FiYWthbi5wbmc/verifiedsabakan.png","url":"https://stereophonic.space/proxy/MbUaXLpXh3ZK7ehIKZqDoyZaCqU/aHR0cHM6Ly9uZXVlLmNpdHkvZW1vamkvbGFiZWxzL3ZlcmlmaWVkc2FiYWthbi5wbmc/verifiedsabakan.png","visible_in_picker":false},{"shortcode":"welovelain","static_url":"https://stereophonic.space/proxy/hAlsiSzic1IqFo-G9w3ZWerAg6Q/aHR0cHM6Ly9uZXVlLmNpdHkvZW1vamkvY3VzdG9tL3dlbG92ZWxhaW4ucG5n/welovelain.png","url":"https://stereophonic.space/proxy/hAlsiSzic1IqFo-G9w3ZWerAg6Q/aHR0cHM6Ly9uZXVlLmNpdHkvZW1vamkvY3VzdG9tL3dlbG92ZWxhaW4ucG5n/welovelain.png","visible_in_picker":false}],"fields":[{"name":"cofe?","value":"hell yeah."},{"name":"blÃ¥haj?","value":"everyday."},{"name":"urbit","value":"~difreg-dasrys"},{"name":"alt. account","value":"<a href=\"https://lets.bemoe.online/users/vala\" rel=\"ugc\">@vala@lets.bemoe.online</a>"},{"name":"xmpp","value":"<a href=\"xmpp://vala@neue.city\">xmpp://vala@neue.city</a>"},{"name":"gacha","value":"sucker"}],"followers_count":147,"following_count":78,"header":"https://stereophonic.space/proxy/algbU9JR1QK-UVTeekBSp30CDLQ/aHR0cHM6Ly9uZXVlLmNpdHkvbWVkaWEvM2Q2YzA5MDZmZDg2ZjgyZTY3YTY1OGQ2MDAxOTc1N2EyNjIwOWIyNGNkZjkwZTgxNzBlMWI5Njg2MWQ1ZjkxOC5qcGc_bmFtZT1CMDA1NTQ4LVIxLTE1LTE0QS5qcGc/3d6c0906fd86f82e67a658d60019757a26209b24cdf90e8170e1b96861d5f918.jpg","header_static":"https://stereophonic.space/proxy/algbU9JR1QK-UVTeekBSp30CDLQ/aHR0cHM6Ly9uZXVlLmNpdHkvbWVkaWEvM2Q2YzA5MDZmZDg2ZjgyZTY3YTY1OGQ2MDAxOTc1N2EyNjIwOWIyNGNkZjkwZTgxNzBlMWI5Njg2MWQ1ZjkxOC5qcGc_bmFtZT1CMDA1NTQ4LVIxLTE1LTE0QS5qcGc/3d6c0906fd86f82e67a658d60019757a26209b24cdf90e8170e1b96861d5f918.jpg","id":"9tO7DH9HqBbxkWv3gG","locked":false,"note":"â•±â•³â•²â•±â•³â•²â•±â•³â•²â•±â•³â•²â•±â•³â•²â•±â•³â•²â•±â•³â•²<br/>gaige or vala<br/>comes from a land of ice and snow :cirno_comfy:<br/><br/>just imagine every word i ever say, in cursive comic sans<br/>i generally float around here while being a â‘¨<br/><br/>:corndog: the official server-maid in this pleroma neighbourhood of the fediverse :pleroma_seal:<br/>i cant program in anything<br/><br/>used to post at <a href=\"http://ilovela.in\">ilovela.in</a> and <a href=\"http://welovela.in\">welovela.in</a> :welovelain:<br/><br/>will judge you for your taste in cars<br/>â•±â•³â•²â•±â•³â•²â•±â•³â•²â•±â•³â•²â•±â•³â•²â•±â•³â•²â•±â•³â•²<br/>:debian: :lain: :raveSmug: :sataniaNoBulli:  :asukaPout:","pleroma":{"accepts_chat_messages":true,"ap_id":"https://neue.city/users/gaige","background_image":null,"confirmation_pending":false,"deactivated":false,"favicon":null,"hide_favorites":true,"hide_followers":false,"hide_followers_count":false,"hide_follows":false,"hide_follows_count":false,"is_admin":false,"is_moderator":false,"relationship":{},"skip_thread_containment":false,"tags":[]},"source":{"fields":[],"note":"","pleroma":{"actor_type":"Person","discoverable":true},"sensitive":false},"statuses_count":5946,"url":"https://neue.city/users/gaige","username":"gaige"},"created_at":"2021-01-16T03:33:28.000Z","id":"326629","pleroma":{"is_muted":false,"is_seen":false},"status":null,"type":"reblog"},{"account":{"acct":"rt@bbs.kawa-kun.com","avatar":"https://stereophonic.space/proxy/oyOufzPwKzGS3HlkB5UGWyM38TI/aHR0cHM6Ly9iYnMua2F3YS1rdW4uY29tL21lZGlhL2MwY2ZkOTFmNDJmNzFhOGM3ZWM1ZTQ1NTU4NGMxYmE1ZWI1NTNkNzcyZWE0ZmM0ZWZhNDVjYjllZTY0NzU4OTQucG5n/c0cfd91f42f71a8c7ec5e455584c1ba5eb553d772ea4fc4efa45cb9ee6475894.png","avatar_static":"https://stereophonic.space/proxy/oyOufzPwKzGS3HlkB5UGWyM38TI/aHR0cHM6Ly9iYnMua2F3YS1rdW4uY29tL21lZGlhL2MwY2ZkOTFmNDJmNzFhOGM3ZWM1ZTQ1NTU4NGMxYmE1ZWI1NTNkNzcyZWE0ZmM0ZWZhNDVjYjllZTY0NzU4OTQucG5n/c0cfd91f42f71a8c7ec5e455584c1ba5eb553d772ea4fc4efa45cb9ee6475894.png","bot":false,"created_at":"2020-05-04T15:46:30.000Z","display_name":"RT All!","emojis":[],"fields":[],"followers_count":0,"following_count":0,"header":"https://stereophonic.space/images/banner.png","header_static":"https://stereophonic.space/images/banner.png","id":"9uhvS4FjH48PRMhy4m","locked":false,"note":"RTing all public posts!<br/><br/>Only public posts with significant interaction will be RT&#39;d.  Unlisted and private posts of any sort will be ignored.<br/><br/>If you don&#39;t want me to RT your posts, just mention me with the text &quot;stop&quot; in a post.","pleroma":{"accepts_chat_messages":true,"ap_id":"https://bbs.kawa-kun.com/users/rt","background_image":null,"confirmation_pending":false,"deactivated":false,"favicon":null,"hide_favorites":true,"hide_followers":false,"hide_followers_count":false,"hide_follows":false,"hide_follows_count":false,"is_admin":false,"is_moderator":false,"relationship":{},"skip_thread_containment":false,"tags":[]},"source":{"fields":[],"note":"","pleroma":{"actor_type":"Person","discoverable":true},"sensitive":false},"statuses_count":2,"url":"https://bbs.kawa-kun.com/users/rt","username":"rt"},"created_at":"2021-01-16T03:30:02.000Z","id":"326628","pleroma":{"is_muted":false,"is_seen":false},"status":null,"type":"reblog"},{"account":{"acct":"emilis@cdrom.tokyo","avatar":"https://stereophonic.space/proxy/8V0mOwZFa_B-_CynqAMBTct_6gY/aHR0cHM6Ly9jZHJvbS50b2t5by9tZWRpYS9lODIxMzc0MWJjZWE5MmIzN2JhNWFmM2EzZmE5NjZjNTU2NzFkZDMxZTUyZjZiNWRmNzJmYTM0ZDk1YTI0NTdmLmpwZw/e8213741bcea92b37ba5af3a3fa966c55671dd31e52f6b5df72fa34d95a2457f.jpg","avatar_static":"https://stereophonic.space/proxy/8V0mOwZFa_B-_CynqAMBTct_6gY/aHR0cHM6Ly9jZHJvbS50b2t5by9tZWRpYS9lODIxMzc0MWJjZWE5MmIzN2JhNWFmM2EzZmE5NjZjNTU2NzFkZDMxZTUyZjZiNWRmNzJmYTM0ZDk1YTI0NTdmLmpwZw/e8213741bcea92b37ba5af3a3fa966c55671dd31e52f6b5df72fa34d95a2457f.jpg","bot":false,"created_at":"2020-10-09T20:14:01.000Z","display_name":"romaboo :jigglypuff:","emojis":[{"shortcode":"jigglypuff","static_url":"https://stereophonic.space/proxy/bnKBn39yPRzUVLRRsLrf-6g4u04/aHR0cHM6Ly9jZHJvbS50b2t5by9lbW9qaS9jZHJvbS9qaWdnbHlwdWZmLnBuZw/jigglypuff.png","url":"https://stereophonic.space/proxy/bnKBn39yPRzUVLRRsLrf-6g4u04/aHR0cHM6Ly9jZHJvbS50b2t5by9lbW9qaS9jZHJvbS9qaWdnbHlwdWZmLnBuZw/jigglypuff.png","visible_in_picker":false}],"fields":[],"followers_count":6,"following_count":12,"header":"https://stereophonic.space/proxy/oeQXvgFN5DnvG8xvOo-NU7BBbO0/aHR0cHM6Ly9jZHJvbS50b2t5by9tZWRpYS81NTE1MThhYzRlNGQ0YTJiZWI1M2ExNTgxOTIwYzJkNDNmYjUzMDA1ZWI2MTU4MjBiMDE2NGYxMDczMTRmMjk4LmpwZw/551518ac4e4d4a2beb53a1581920c2d43fb53005eb615820b0164f107314f298.jpg","header_static":"https://stereophonic.space/proxy/oeQXvgFN5DnvG8xvOo-NU7BBbO0/aHR0cHM6Ly9jZHJvbS50b2t5by9tZWRpYS81NTE1MThhYzRlNGQ0YTJiZWI1M2ExNTgxOTIwYzJkNDNmYjUzMDA1ZWI2MTU4MjBiMDE2NGYxMDczMTRmMjk4LmpwZw/551518ac4e4d4a2beb53a1581920c2d43fb53005eb615820b0164f107314f298.jpg","id":"9zzoVd0oJZMuqGNzLk","locked":false,"note":"lego is based on nipples<br/><br/>In lingua latina: <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"9vqY7exhRY86vqnH6m\" href=\"https://cdrom.tokyo/users/aemilivs\">@<span>aemilivs</span></a></span>","pleroma":{"accepts_chat_messages":true,"ap_id":"https://cdrom.tokyo/users/emilis","background_image":null,"confirmation_pending":false,"deactivated":false,"favicon":null,"hide_favorites":true,"hide_followers":false,"hide_followers_count":false,"hide_follows":false,"hide_follows_count":false,"is_admin":false,"is_moderator":false,"relationship":{},"skip_thread_containment":false,"tags":[]},"source":{"fields":[],"note":"","pleroma":{"actor_type":"Person","discoverable":true},"sensitive":false},"statuses_count":4721,"url":"https://cdrom.tokyo/users/emilis","username":"emilis"},"created_at":"2021-01-16T00:21:23.000Z","id":"326567","pleroma":{"is_muted":false,"is_seen":true},"status":{"account":{"acct":"emilis@cdrom.tokyo","avatar":"https://stereophonic.space/proxy/8V0mOwZFa_B-_CynqAMBTct_6gY/aHR0cHM6Ly9jZHJvbS50b2t5by9tZWRpYS9lODIxMzc0MWJjZWE5MmIzN2JhNWFmM2EzZmE5NjZjNTU2NzFkZDMxZTUyZjZiNWRmNzJmYTM0ZDk1YTI0NTdmLmpwZw/e8213741bcea92b37ba5af3a3fa966c55671dd31e52f6b5df72fa34d95a2457f.jpg","avatar_static":"https://stereophonic.space/proxy/8V0mOwZFa_B-_CynqAMBTct_6gY/aHR0cHM6Ly9jZHJvbS50b2t5by9tZWRpYS9lODIxMzc0MWJjZWE5MmIzN2JhNWFmM2EzZmE5NjZjNTU2NzFkZDMxZTUyZjZiNWRmNzJmYTM0ZDk1YTI0NTdmLmpwZw/e8213741bcea92b37ba5af3a3fa966c55671dd31e52f6b5df72fa34d95a2457f.jpg","bot":false,"created_at":"2020-10-09T20:14:01.000Z","display_name":"romaboo :jigglypuff:","emojis":[{"shortcode":"jigglypuff","static_url":"https://stereophonic.space/proxy/bnKBn39yPRzUVLRRsLrf-6g4u04/aHR0cHM6Ly9jZHJvbS50b2t5by9lbW9qaS9jZHJvbS9qaWdnbHlwdWZmLnBuZw/jigglypuff.png","url":"https://stereophonic.space/proxy/bnKBn39yPRzUVLRRsLrf-6g4u04/aHR0cHM6Ly9jZHJvbS50b2t5by9lbW9qaS9jZHJvbS9qaWdnbHlwdWZmLnBuZw/jigglypuff.png","visible_in_picker":false}],"fields":[],"followers_count":6,"following_count":12,"header":"https://stereophonic.space/proxy/oeQXvgFN5DnvG8xvOo-NU7BBbO0/aHR0cHM6Ly9jZHJvbS50b2t5by9tZWRpYS81NTE1MThhYzRlNGQ0YTJiZWI1M2ExNTgxOTIwYzJkNDNmYjUzMDA1ZWI2MTU4MjBiMDE2NGYxMDczMTRmMjk4LmpwZw/551518ac4e4d4a2beb53a1581920c2d43fb53005eb615820b0164f107314f298.jpg","header_static":"https://stereophonic.space/proxy/oeQXvgFN5DnvG8xvOo-NU7BBbO0/aHR0cHM6Ly9jZHJvbS50b2t5by9tZWRpYS81NTE1MThhYzRlNGQ0YTJiZWI1M2ExNTgxOTIwYzJkNDNmYjUzMDA1ZWI2MTU4MjBiMDE2NGYxMDczMTRmMjk4LmpwZw/551518ac4e4d4a2beb53a1581920c2d43fb53005eb615820b0164f107314f298.jpg","id":"9zzoVd0oJZMuqGNzLk","locked":false,"note":"lego is based on nipples<br/><br/>In lingua latina: <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"9vqY7exhRY86vqnH6m\" href=\"https://cdrom.tokyo/users/aemilivs\">@<span>aemilivs</span></a></span>","pleroma":{"accepts_chat_messages":true,"ap_id":"https://cdrom.tokyo/users/emilis","background_image":null,"confirmation_pending":false,"deactivated":false,"favicon":null,"hide_favorites":true,"hide_followers":false,"hide_followers_count":false,"hide_follows":false,"hide_follows_count":false,"is_admin":false,"is_moderator":false,"relationship":{},"skip_thread_containment":false,"tags":[]},"source":{"fields":[],"note":"","pleroma":{"actor_type":"Person","discoverable":true},"sensitive":false},"statuses_count":4721,"url":"https://cdrom.tokyo/users/emilis","username":"emilis"},"application":{"name":"Web","website":null},"bookmarked":false,"card":null,"content":"<p><span class=\"h-card\"><a class=\"u-url mention\" data-user=\"9vLK6FwkZYqQAO4wIS\" href=\"https://stereophonic.space/users/newt\">@<span>newt</span></a></span> <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"9vJXUEhXxCI7PRhqwi\" href=\"https://lain.com/users/lain\">@<span>lain</span></a></span> funded by russian rich dude :blobthumbsup:</p>","created_at":"2021-01-16T00:21:22.000Z","emojis":[{"shortcode":"blobthumbsup","static_url":"https://stereophonic.space/proxy/TaMFl_7FPDPZrGrrADI_rUyktEo/aHR0cHM6Ly9jZHJvbS50b2t5by9lbW9qaS9zdG9sZW4vYmxvYnRodW1ic3VwLnBuZw/blobthumbsup.png","url":"https://stereophonic.space/proxy/TaMFl_7FPDPZrGrrADI_rUyktEo/aHR0cHM6Ly9jZHJvbS50b2t5by9lbW9qaS9zdG9sZW4vYmxvYnRodW1ic3VwLnBuZw/blobthumbsup.png","visible_in_picker":false}],"favourited":false,"favourites_count":0,"id":"A3HIwFvoB2leKe05QW","in_reply_to_account_id":"9rZ2STPb7FA7JnMRii","in_reply_to_id":"A3HHYP1mbbiHdirCDo","language":null,"media_attachments":[],"mentions":[{"acct":"newt","id":"9rZ2STPb7FA7JnMRii","url":"https://stereophonic.space/users/newt","username":"newt"},{"acct":"lain@lain.com","id":"9qrXewWxfr80iavPVY","url":"https://lain.com/users/lain","username":"lain"}],"muted":false,"pinned":false,"pleroma":{"content":{"text/plain":"@newt @lain funded by russian rich dude :blobthumbsup:"},"conversation_id":20784105,"direct_conversation_id":null,"emoji_reactions":[],"expires_at":null,"in_reply_to_account_acct":"newt","local":false,"parent_visible":true,"spoiler_text":{"text/plain":""},"thread_muted":false},"poll":null,"reblog":null,"reblogged":false,"reblogs_count":0,"replies_count":1,"sensitive":false,"spoiler_text":"","tags":[],"text":null,"uri":"https://cdrom.tokyo/objects/9ee6edee-b483-433c-89b6-ca0a610b3e09","url":"https://cdrom.tokyo/objects/9ee6edee-b483-433c-89b6-ca0a610b3e09","visibility":"public"},"type":"mention"},{"account":{"acct":"emilis@cdrom.tokyo","avatar":"https://stereophonic.space/proxy/8V0mOwZFa_B-_CynqAMBTct_6gY/aHR0cHM6Ly9jZHJvbS50b2t5by9tZWRpYS9lODIxMzc0MWJjZWE5MmIzN2JhNWFmM2EzZmE5NjZjNTU2NzFkZDMxZTUyZjZiNWRmNzJmYTM0ZDk1YTI0NTdmLmpwZw/e8213741bcea92b37ba5af3a3fa966c55671dd31e52f6b5df72fa34d95a2457f.jpg","avatar_static":"https://stereophonic.space/proxy/8V0mOwZFa_B-_CynqAMBTct_6gY/aHR0cHM6Ly9jZHJvbS50b2t5by9tZWRpYS9lODIxMzc0MWJjZWE5MmIzN2JhNWFmM2EzZmE5NjZjNTU2NzFkZDMxZTUyZjZiNWRmNzJmYTM0ZDk1YTI0NTdmLmpwZw/e8213741bcea92b37ba5af3a3fa966c55671dd31e52f6b5df72fa34d95a2457f.jpg","bot":false,"created_at":"2020-10-09T20:14:01.000Z","display_name":"romaboo :jigglypuff:","emojis":[{"shortcode":"jigglypuff","static_url":"https://stereophonic.space/proxy/bnKBn39yPRzUVLRRsLrf-6g4u04/aHR0cHM6Ly9jZHJvbS50b2t5by9lbW9qaS9jZHJvbS9qaWdnbHlwdWZmLnBuZw/jigglypuff.png","url":"https://stereophonic.space/proxy/bnKBn39yPRzUVLRRsLrf-6g4u04/aHR0cHM6Ly9jZHJvbS50b2t5by9lbW9qaS9jZHJvbS9qaWdnbHlwdWZmLnBuZw/jigglypuff.png","visible_in_picker":false}],"fields":[],"followers_count":6,"following_count":12,"header":"https://stereophonic.space/proxy/oeQXvgFN5DnvG8xvOo-NU7BBbO0/aHR0cHM6Ly9jZHJvbS50b2t5by9tZWRpYS81NTE1MThhYzRlNGQ0YTJiZWI1M2ExNTgxOTIwYzJkNDNmYjUzMDA1ZWI2MTU4MjBiMDE2NGYxMDczMTRmMjk4LmpwZw/551518ac4e4d4a2beb53a1581920c2d43fb53005eb615820b0164f107314f298.jpg","header_static":"https://stereophonic.space/proxy/oeQXvgFN5DnvG8xvOo-NU7BBbO0/aHR0cHM6Ly9jZHJvbS50b2t5by9tZWRpYS81NTE1MThhYzRlNGQ0YTJiZWI1M2ExNTgxOTIwYzJkNDNmYjUzMDA1ZWI2MTU4MjBiMDE2NGYxMDczMTRmMjk4LmpwZw/551518ac4e4d4a2beb53a1581920c2d43fb53005eb615820b0164f107314f298.jpg","id":"9zzoVd0oJZMuqGNzLk","locked":false,"note":"lego is based on nipples<br/><br/>In lingua latina: <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"9vqY7exhRY86vqnH6m\" href=\"https://cdrom.tokyo/users/aemilivs\">@<span>aemilivs</span></a></span>","pleroma":{"accepts_chat_messages":true,"ap_id":"https://cdrom.tokyo/users/emilis","background_image":null,"confirmation_pending":false,"deactivated":false,"favicon":null,"hide_favorites":true,"hide_followers":false,"hide_followers_count":false,"hide_follows":false,"hide_follows_count":false,"is_admin":false,"is_moderator":false,"relationship":{},"skip_thread_containment":false,"tags":[]},"source":{"fields":[],"note":"","pleroma":{"actor_type":"Person","discoverable":true},"sensitive":false},"statuses_count":4721,"url":"https://cdrom.tokyo/users/emilis","username":"emilis"},"created_at":"2021-01-16T00:21:06.000Z","id":"326566","pleroma":{"is_muted":false,"is_seen":true},"status":{"account":{"acct":"newt","avatar":"https://stereophonic.space/media/badfe007441b8daa3da9c1dfcd56a71378e3a2c0022745030cfe017057129582.blob","avatar_static":"https://stereophonic.space/media/badfe007441b8daa3da9c1dfcd56a71378e3a2c0022745030cfe017057129582.blob","bot":false,"created_at":"2020-01-31T15:16:18.000Z","display_name":"NÌ¸Ì¢Ì¡Ì¢Ì¤Ì®Ì¥Ì²ÍÍ‹Í†Î£ÌµÌ›ÌžÌ€ÌˆÌÌ†Ì“ÌÍ›Ì‹áº‚ÌµÌ¢Ì«Ì£Ì¦Ì»Ì©Í‘Ì€ÍTÌµÍ™Ì¯Ì”ÌˆÌÍÍ…","emojis":[{"shortcode":"8b_a","static_url":"https://stereophonic.space/emoji/custom/8b_a.png","url":"https://stereophonic.space/emoji/custom/8b_a.png","visible_in_picker":false},{"shortcode":"8b_c","static_url":"https://stereophonic.space/emoji/custom/8b_c.png","url":"https://stereophonic.space/emoji/custom/8b_c.png","visible_in_picker":false},{"shortcode":"8b_d","static_url":"https://stereophonic.space/emoji/custom/8b_d.png","url":"https://stereophonic.space/emoji/custom/8b_d.png","visible_in_picker":false},{"shortcode":"8b_e","static_url":"https://stereophonic.space/emoji/custom/8b_e.png","url":"https://stereophonic.space/emoji/custom/8b_e.png","visible_in_picker":false},{"shortcode":"8b_i","static_url":"https://stereophonic.space/emoji/custom/8b_i.png","url":"https://stereophonic.space/emoji/custom/8b_i.png","visible_in_picker":false},{"shortcode":"8b_l","static_url":"https://stereophonic.space/emoji/custom/8b_l.png","url":"https://stereophonic.space/emoji/custom/8b_l.png","visible_in_picker":false},{"shortcode":"8b_m","static_url":"https://stereophonic.space/emoji/custom/8b_m.png","url":"https://stereophonic.space/emoji/custom/8b_m.png","visible_in_picker":false},{"shortcode":"8b_o","static_url":"https://stereophonic.space/emoji/custom/8b_o.png","url":"https://stereophonic.space/emoji/custom/8b_o.png","visible_in_picker":false},{"shortcode":"8b_p","static_url":"https://stereophonic.space/emoji/custom/8b_p.png","url":"https://stereophonic.space/emoji/custom/8b_p.png","visible_in_picker":false},{"shortcode":"8b_r","static_url":"https://stereophonic.space/emoji/custom/8b_r.png","url":"https://stereophonic.space/emoji/custom/8b_r.png","visible_in_picker":false},{"shortcode":"8b_s","static_url":"https://stereophonic.space/emoji/custom/8b_s.png","url":"https://stereophonic.space/emoji/custom/8b_s.png","visible_in_picker":false},{"shortcode":"8b_t","static_url":"https://stereophonic.space/emoji/custom/8b_t.png","url":"https://stereophonic.space/emoji/custom/8b_t.png","visible_in_picker":false},{"shortcode":"8b_u","static_url":"https://stereophonic.space/emoji/custom/8b_u.png","url":"https://stereophonic.space/emoji/custom/8b_u.png","visible_in_picker":false},{"shortcode":"8b_v","static_url":"https://stereophonic.space/emoji/custom/8b_v.png","url":"https://stereophonic.space/emoji/custom/8b_v.png","visible_in_picker":false},{"shortcode":"8b_y","static_url":"https://stereophonic.space/emoji/custom/8b_y.png","url":"https://stereophonic.space/emoji/custom/8b_y.png","visible_in_picker":false},{"shortcode":"comfycofesmirk","static_url":"https://stereophonic.space/emoji/comfy/comfycofesmirk.png","url":"https://stereophonic.space/emoji/comfy/comfycofesmirk.png","visible_in_picker":false}],"fields":[{"name":"cofe","value":":comfycofesmirk:"}],"follow_requests_count":0,"followers_count":315,"following_count":198,"header":"https://stereophonic.space/media/e43024f466693cad7887a60ffce07861bd15b9b54dd67fee90c774534787ee4d.jpg","header_static":"https://stereophonic.space/media/e43024f466693cad7887a60ffce07861bd15b9b54dd67fee90c774534787ee4d.jpg","id":"9rZ2STPb7FA7JnMRii","locked":false,"note":"Chaos evangelist.<br/>Sometimes evil.<br/>Almost godlike.<br/>Better, even more magnificent than before.<br/>Not for the faint of heart.<br/><br/>:8b_v:<br/>:8b_e:<br/>:8b_r:<br/>:8b_t:<br/>:8b_i:<br/>:8b_c:<br/>:8b_a:<br/>:8b_l:<br/><br/>:8b_s:<br/>:8b_u:<br/>:8b_p:<br/>:8b_r:<br/>:8b_e:<br/>:8b_m:<br/>:8b_a:<br/>:8b_c:<br/>:8b_y:<br/><br/>:8b_a:<br/>:8b_d:<br/>:8b_v:<br/>:8b_o:<br/>:8b_c:<br/>:8b_a:<br/>:8b_t:<br/>:8b_e:<br/><br/><a class=\"hashtag\" data-tag=\"niu\" href=\"https://stereophonic.space/tag/niu\">#niu</a> refugee. <br/>Programming and tech talk is mostly at <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"9jCuHkYZPSuOlVU6qm\" href=\"https://functional.cafe/@pureevil\">@<span>pureevil@functional.cafe</span></a></span> but occasionally leaks.<br/>I write and actively use proprietary software. <br/><br/>Duke Nukem did nothing wrong.","pleroma":{"accepts_chat_messages":true,"allow_following_move":true,"ap_id":"https://stereophonic.space/users/newt","background_image":null,"confirmation_pending":false,"deactivated":false,"favicon":null,"hide_favorites":true,"hide_followers":false,"hide_followers_count":false,"hide_follows":false,"hide_follows_count":false,"is_admin":true,"is_moderator":false,"notification_settings":{"block_from_strangers":false,"hide_notification_contents":false},"relationship":{},"skip_thread_containment":false,"tags":[],"unread_conversation_count":34,"unread_notifications_count":10},"source":{"fields":[{"name":"cofe","value":":comfycofesmirk:"}],"note":"Chaos evangelist.\nSometimes evil.\nAlmost godlike.\nBetter, even more magnificent than before.\nNot for the faint of heart.\n\n:8b_v:\n:8b_e:\n:8b_r:\n:8b_t:\n:8b_i:\n:8b_c:\n:8b_a:\n:8b_l:\n\n:8b_s:\n:8b_u:\n:8b_p:\n:8b_r:\n:8b_e:\n:8b_m:\n:8b_a:\n:8b_c:\n:8b_y:\n\n:8b_a:\n:8b_d:\n:8b_v:\n:8b_o:\n:8b_c:\n:8b_a:\n:8b_t:\n:8b_e:\n\n#niu refugee. \nProgramming and tech talk is mostly at @pureevil@functional.cafe but occasionally leaks.\nI write and actively use proprietary software. \n\nDuke Nukem did nothing wrong.","pleroma":{"actor_type":"Person","discoverable":false,"no_rich_text":true,"show_role":false},"privacy":"public","sensitive":false},"statuses_count":9437,"url":"https://stereophonic.space/users/newt","username":"newt"},"application":{"name":"Web","website":null},"bookmarked":false,"card":null,"content":"<span class=\"h-card\"><a class=\"u-url mention\" data-user=\"9qrXewWxfr80iavPVY\" href=\"https://lain.com/users/lain\">@<span>lain</span></a></span> don&#39;t telegram devs live in Russia?","created_at":"2021-01-16T00:05:52.000Z","emojis":[],"favourited":false,"favourites_count":1,"id":"A3HHYP1mbbiHdirCDo","in_reply_to_account_id":"9qrXewWxfr80iavPVY","in_reply_to_id":"A3HHVhvzr2r9PPriW8","language":null,"media_attachments":[],"mentions":[{"acct":"lain@lain.com","id":"9qrXewWxfr80iavPVY","url":"https://lain.com/users/lain","username":"lain"}],"muted":false,"pinned":false,"pleroma":{"content":{"text/plain":"@lain don't telegram devs live in Russia?"},"conversation_id":20784105,"direct_conversation_id":null,"emoji_reactions":[],"expires_at":null,"in_reply_to_account_acct":"lain@lain.com","local":true,"parent_visible":true,"spoiler_text":{"text/plain":""},"thread_muted":false},"poll":null,"reblog":null,"reblogged":false,"reblogs_count":0,"replies_count":2,"sensitive":false,"spoiler_text":"","tags":[],"text":null,"uri":"https://stereophonic.space/objects/504d2239-b8ef-4f8f-848c-9724e091216b","url":"https://stereophonic.space/notice/A3HHYP1mbbiHdirCDo","visibility":"public"},"type":"favourite"},{"account":{"acct":"lain@lain.com","avatar":"https://stereophonic.space/proxy/1jt_Q-4Svj4502XuohIeuwtCRS4/aHR0cHM6Ly9sYWluLmNvbS9tZWRpYS84YTY1MjMzNDIxMTYwZDU2MjU2YzFlYjljNGI0NTJmZDJmZmE5YTA4ZjlmZTZkOWE5YTllMDdjYTc4NDlkODI5LmJsb2I/8a65233421160d56256c1eb9c4b452fd2ffa9a08f9fe6d9a9a9e07ca7849d829.blob","avatar_static":"https://stereophonic.space/proxy/1jt_Q-4Svj4502XuohIeuwtCRS4/aHR0cHM6Ly9sYWluLmNvbS9tZWRpYS84YTY1MjMzNDIxMTYwZDU2MjU2YzFlYjljNGI0NTJmZDJmZmE5YTA4ZjlmZTZkOWE5YTllMDdjYTc4NDlkODI5LmJsb2I/8a65233421160d56256c1eb9c4b452fd2ffa9a08f9fe6d9a9a9e07ca7849d829.blob","bot":false,"created_at":"2020-01-10T15:38:37.000Z","display_name":"workin' 12 to 9ish","emojis":[],"fields":[],"followers_count":1587,"following_count":345,"header":"https://stereophonic.space/proxy/BzLFPP43fnB1rOBkAJDMGe2lL-s/aHR0cHM6Ly9sYWluLmNvbS9tZWRpYS8yMzk4ZjIwMDBmNzU3YzA3MDdjOWI0M2RhZTk4NjgyNzE3NjZhNzNlMzE0YjFkNGQ5NDVhZGNmZWVlN2Q2NzRmLmpwZw/2398f2000f757c0707c9b43dae9868271766a73e314b1d4d945adcfeee7d674f.jpg","header_static":"https://stereophonic.space/proxy/BzLFPP43fnB1rOBkAJDMGe2lL-s/aHR0cHM6Ly9sYWluLmNvbS9tZWRpYS8yMzk4ZjIwMDBmNzU3YzA3MDdjOWI0M2RhZTk4NjgyNzE3NjZhNzNlMzE0YjFkNGQ5NDVhZGNmZWVlN2Q2NzRmLmpwZw/2398f2000f757c0707c9b43dae9868271766a73e314b1d4d945adcfeee7d674f.jpg","id":"9qrXewWxfr80iavPVY","locked":false,"note":"No more hiding","pleroma":{"accepts_chat_messages":true,"ap_id":"https://lain.com/users/lain","background_image":null,"confirmation_pending":false,"deactivated":false,"favicon":null,"hide_favorites":true,"hide_followers":false,"hide_followers_count":false,"hide_follows":false,"hide_follows_count":false,"is_admin":false,"is_moderator":false,"relationship":{},"skip_thread_containment":false,"tags":[]},"source":{"fields":[],"note":"","pleroma":{"actor_type":"Person","discoverable":true},"sensitive":false},"statuses_count":46685,"url":"https://lain.com/users/lain","username":"lain"},"created_at":"2021-01-16T00:06:45.000Z","id":"326564","pleroma":{"is_muted":false,"is_seen":true},"status":{"account":{"acct":"lain@lain.com","avatar":"https://stereophonic.space/proxy/1jt_Q-4Svj4502XuohIeuwtCRS4/aHR0cHM6Ly9sYWluLmNvbS9tZWRpYS84YTY1MjMzNDIxMTYwZDU2MjU2YzFlYjljNGI0NTJmZDJmZmE5YTA4ZjlmZTZkOWE5YTllMDdjYTc4NDlkODI5LmJsb2I/8a65233421160d56256c1eb9c4b452fd2ffa9a08f9fe6d9a9a9e07ca7849d829.blob","avatar_static":"https://stereophonic.space/proxy/1jt_Q-4Svj4502XuohIeuwtCRS4/aHR0cHM6Ly9sYWluLmNvbS9tZWRpYS84YTY1MjMzNDIxMTYwZDU2MjU2YzFlYjljNGI0NTJmZDJmZmE5YTA4ZjlmZTZkOWE5YTllMDdjYTc4NDlkODI5LmJsb2I/8a65233421160d56256c1eb9c4b452fd2ffa9a08f9fe6d9a9a9e07ca7849d829.blob","bot":false,"created_at":"2020-01-10T15:38:37.000Z","display_name":"workin' 12 to 9ish","emojis":[],"fields":[],"followers_count":1587,"following_count":345,"header":"https://stereophonic.space/proxy/BzLFPP43fnB1rOBkAJDMGe2lL-s/aHR0cHM6Ly9sYWluLmNvbS9tZWRpYS8yMzk4ZjIwMDBmNzU3YzA3MDdjOWI0M2RhZTk4NjgyNzE3NjZhNzNlMzE0YjFkNGQ5NDVhZGNmZWVlN2Q2NzRmLmpwZw/2398f2000f757c0707c9b43dae9868271766a73e314b1d4d945adcfeee7d674f.jpg","header_static":"https://stereophonic.space/proxy/BzLFPP43fnB1rOBkAJDMGe2lL-s/aHR0cHM6Ly9sYWluLmNvbS9tZWRpYS8yMzk4ZjIwMDBmNzU3YzA3MDdjOWI0M2RhZTk4NjgyNzE3NjZhNzNlMzE0YjFkNGQ5NDVhZGNmZWVlN2Q2NzRmLmpwZw/2398f2000f757c0707c9b43dae9868271766a73e314b1d4d945adcfeee7d674f.jpg","id":"9qrXewWxfr80iavPVY","locked":false,"note":"No more hiding","pleroma":{"accepts_chat_messages":true,"ap_id":"https://lain.com/users/lain","background_image":null,"confirmation_pending":false,"deactivated":false,"favicon":null,"hide_favorites":true,"hide_followers":false,"hide_followers_count":false,"hide_follows":false,"hide_follows_count":false,"is_admin":false,"is_moderator":false,"relationship":{},"skip_thread_containment":false,"tags":[]},"source":{"fields":[],"note":"","pleroma":{"actor_type":"Person","discoverable":true},"sensitive":false},"statuses_count":46685,"url":"https://lain.com/users/lain","username":"lain"},"application":{"name":"Web","website":null},"bookmarked":false,"card":null,"content":"<span class=\"h-card\"><a class=\"u-url mention\" data-user=\"9rZ3P3hbSH1g7QDXwO\" href=\"https://stereophonic.space/users/newt\">@<span>newt</span></a></span> I think so","created_at":"2021-01-16T00:06:41.000Z","emojis":[],"favourited":true,"favourites_count":1,"id":"A3HHdH3JgWNoLvtgXY","in_reply_to_account_id":"9rZ2STPb7FA7JnMRii","in_reply_to_id":"A3HHYP1mbbiHdirCDo","language":null,"media_attachments":[],"mentions":[{"acct":"newt","id":"9rZ2STPb7FA7JnMRii","url":"https://stereophonic.space/users/newt","username":"newt"}],"muted":false,"pinned":false,"pleroma":{"content":{"text/plain":"@newt I think so"},"conversation_id":20784105,"direct_conversation_id":null,"emoji_reactions":[],"expires_at":null,"in_reply_to_account_acct":"newt","local":false,"parent_visible":true,"spoiler_text":{"text/plain":""},"thread_muted":false},"poll":null,"reblog":null,"reblogged":false,"reblogs_count":0,"replies_count":1,"sensitive":false,"spoiler_text":"","tags":[],"text":null,"uri":"https://lain.com/objects/753b3101-575c-44e8-9a46-52f248c896cb","url":"https://lain.com/objects/753b3101-575c-44e8-9a46-52f248c896cb","visibility":"public"},"type":"mention"},{"account":{"acct":"mystik@midnightride.rs","avatar":"https://stereophonic.space/proxy/CiibZFn3pLaq6z33WCA1d6TLDFc/aHR0cHM6Ly9taWRuaWdodHJpZGUucnMvbWVkaWEvNjk5MDllM2Y2Yjg4MDIwNjI0YWYzNDViMmZlZDVkNTNmNmM3NmUwOTUxNzk5ZTgzNGFiYmRhZmMzMTc1NWUxNC5qcGc/69909e3f6b88020624af345b2fed5d53f6c76e0951799e834abbdafc31755e14.jpg","avatar_static":"https://stereophonic.space/proxy/CiibZFn3pLaq6z33WCA1d6TLDFc/aHR0cHM6Ly9taWRuaWdodHJpZGUucnMvbWVkaWEvNjk5MDllM2Y2Yjg4MDIwNjI0YWYzNDViMmZlZDVkNTNmNmM3NmUwOTUxNzk5ZTgzNGFiYmRhZmMzMTc1NWUxNC5qcGc/69909e3f6b88020624af345b2fed5d53f6c76e0951799e834abbdafc31755e14.jpg","bot":false,"created_at":"2020-11-13T07:54:41.000Z","display_name":"mystik","emojis":[],"fields":[],"followers_count":124,"following_count":304,"header":"https://stereophonic.space/proxy/nakuPYK0SG389sIac37pUdOKeDM/aHR0cHM6Ly9taWRuaWdodHJpZGUucnMvbWVkaWEvNWExYjNhNjI1OWUxNTFkZGRjZmRhNWZmNjAxYzVlY2M4ZTA4YjEwMmJkOWIzZjgwZWY2ZWY4MDgxOGUyNGE4MC5qcGc/5a1b3a6259e151dddcfda5ff601c5ecc8e08b102bd9b3f80ef6ef80818e24a80.jpg","header_static":"https://stereophonic.space/proxy/nakuPYK0SG389sIac37pUdOKeDM/aHR0cHM6Ly9taWRuaWdodHJpZGUucnMvbWVkaWEvNWExYjNhNjI1OWUxNTFkZGRjZmRhNWZmNjAxYzVlY2M4ZTA4YjEwMmJkOWIzZjgwZWY2ZWY4MDgxOGUyNGE4MC5qcGc/5a1b3a6259e151dddcfda5ff601c5ecc8e08b102bd9b3f80ef6ef80818e24a80.jpg","id":"A19IVg19shIluyE7Bg","locked":false,"note":"Doesn&#39;t wear the slave mark (aka face mask).<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>Unpopular knowledge.<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>Give me freedom or give me death.","pleroma":{"accepts_chat_messages":true,"ap_id":"https://midnightride.rs/users/mystik","background_image":null,"confirmation_pending":false,"deactivated":false,"favicon":null,"hide_favorites":true,"hide_followers":false,"hide_followers_count":false,"hide_follows":false,"hide_follows_count":false,"is_admin":false,"is_moderator":false,"relationship":{},"skip_thread_containment":false,"tags":[]},"source":{"fields":[],"note":"","pleroma":{"actor_type":"Person","discoverable":false},"sensitive":false},"statuses_count":844,"url":"https://midnightride.rs/users/mystik","username":"mystik"},"created_at":"2021-01-15T22:55:51.000Z","id":"326542","pleroma":{"is_muted":false,"is_seen":true},"status":{"account":{"acct":"newt","avatar":"https://stereophonic.space/media/badfe007441b8daa3da9c1dfcd56a71378e3a2c0022745030cfe017057129582.blob","avatar_static":"https://stereophonic.space/media/badfe007441b8daa3da9c1dfcd56a71378e3a2c0022745030cfe017057129582.blob","bot":false,"created_at":"2020-01-31T15:16:18.000Z","display_name":"NÌ¸Ì¢Ì¡Ì¢Ì¤Ì®Ì¥Ì²ÍÍ‹Í†Î£ÌµÌ›ÌžÌ€ÌˆÌÌ†Ì“ÌÍ›Ì‹áº‚ÌµÌ¢Ì«Ì£Ì¦Ì»Ì©Í‘Ì€ÍTÌµÍ™Ì¯Ì”ÌˆÌÍÍ…","emojis":[{"shortcode":"8b_a","static_url":"https://stereophonic.space/emoji/custom/8b_a.png","url":"https://stereophonic.space/emoji/custom/8b_a.png","visible_in_picker":false},{"shortcode":"8b_c","static_url":"https://stereophonic.space/emoji/custom/8b_c.png","url":"https://stereophonic.space/emoji/custom/8b_c.png","visible_in_picker":false},{"shortcode":"8b_d","static_url":"https://stereophonic.space/emoji/custom/8b_d.png","url":"https://stereophonic.space/emoji/custom/8b_d.png","visible_in_picker":false},{"shortcode":"8b_e","static_url":"https://stereophonic.space/emoji/custom/8b_e.png","url":"https://stereophonic.space/emoji/custom/8b_e.png","visible_in_picker":false},{"shortcode":"8b_i","static_url":"https://stereophonic.space/emoji/custom/8b_i.png","url":"https://stereophonic.space/emoji/custom/8b_i.png","visible_in_picker":false},{"shortcode":"8b_l","static_url":"https://stereophonic.space/emoji/custom/8b_l.png","url":"https://stereophonic.space/emoji/custom/8b_l.png","visible_in_picker":false},{"shortcode":"8b_m","static_url":"https://stereophonic.space/emoji/custom/8b_m.png","url":"https://stereophonic.space/emoji/custom/8b_m.png","visible_in_picker":false},{"shortcode":"8b_o","static_url":"https://stereophonic.space/emoji/custom/8b_o.png","url":"https://stereophonic.space/emoji/custom/8b_o.png","visible_in_picker":false},{"shortcode":"8b_p","static_url":"https://stereophonic.space/emoji/custom/8b_p.png","url":"https://stereophonic.space/emoji/custom/8b_p.png","visible_in_picker":false},{"shortcode":"8b_r","static_url":"https://stereophonic.space/emoji/custom/8b_r.png","url":"https://stereophonic.space/emoji/custom/8b_r.png","visible_in_picker":false},{"shortcode":"8b_s","static_url":"https://stereophonic.space/emoji/custom/8b_s.png","url":"https://stereophonic.space/emoji/custom/8b_s.png","visible_in_picker":false},{"shortcode":"8b_t","static_url":"https://stereophonic.space/emoji/custom/8b_t.png","url":"https://stereophonic.space/emoji/custom/8b_t.png","visible_in_picker":false},{"shortcode":"8b_u","static_url":"https://stereophonic.space/emoji/custom/8b_u.png","url":"https://stereophonic.space/emoji/custom/8b_u.png","visible_in_picker":false},{"shortcode":"8b_v","static_url":"https://stereophonic.space/emoji/custom/8b_v.png","url":"https://stereophonic.space/emoji/custom/8b_v.png","visible_in_picker":false},{"shortcode":"8b_y","static_url":"https://stereophonic.space/emoji/custom/8b_y.png","url":"https://stereophonic.space/emoji/custom/8b_y.png","visible_in_picker":false},{"shortcode":"comfycofesmirk","static_url":"https://stereophonic.space/emoji/comfy/comfycofesmirk.png","url":"https://stereophonic.space/emoji/comfy/comfycofesmirk.png","visible_in_picker":false}],"fields":[{"name":"cofe","value":":comfycofesmirk:"}],"follow_requests_count":0,"followers_count":315,"following_count":198,"header":"https://stereophonic.space/media/e43024f466693cad7887a60ffce07861bd15b9b54dd67fee90c774534787ee4d.jpg","header_static":"https://stereophonic.space/media/e43024f466693cad7887a60ffce07861bd15b9b54dd67fee90c774534787ee4d.jpg","id":"9rZ2STPb7FA7JnMRii","locked":false,"note":"Chaos evangelist.<br/>Sometimes evil.<br/>Almost godlike.<br/>Better, even more magnificent than before.<br/>Not for the faint of heart.<br/><br/>:8b_v:<br/>:8b_e:<br/>:8b_r:<br/>:8b_t:<br/>:8b_i:<br/>:8b_c:<br/>:8b_a:<br/>:8b_l:<br/><br/>:8b_s:<br/>:8b_u:<br/>:8b_p:<br/>:8b_r:<br/>:8b_e:<br/>:8b_m:<br/>:8b_a:<br/>:8b_c:<br/>:8b_y:<br/><br/>:8b_a:<br/>:8b_d:<br/>:8b_v:<br/>:8b_o:<br/>:8b_c:<br/>:8b_a:<br/>:8b_t:<br/>:8b_e:<br/><br/><a class=\"hashtag\" data-tag=\"niu\" href=\"https://stereophonic.space/tag/niu\">#niu</a> refugee. <br/>Programming and tech talk is mostly at <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"9jCuHkYZPSuOlVU6qm\" href=\"https://functional.cafe/@pureevil\">@<span>pureevil@functional.cafe</span></a></span> but occasionally leaks.<br/>I write and actively use proprietary software. <br/><br/>Duke Nukem did nothing wrong.","pleroma":{"accepts_chat_messages":true,"allow_following_move":true,"ap_id":"https://stereophonic.space/users/newt","background_image":null,"confirmation_pending":false,"deactivated":false,"favicon":null,"hide_favorites":true,"hide_followers":false,"hide_followers_count":false,"hide_follows":false,"hide_follows_count":false,"is_admin":true,"is_moderator":false,"notification_settings":{"block_from_strangers":false,"hide_notification_contents":false},"relationship":{},"skip_thread_containment":false,"tags":[],"unread_conversation_count":34,"unread_notifications_count":10},"source":{"fields":[{"name":"cofe","value":":comfycofesmirk:"}],"note":"Chaos evangelist.\nSometimes evil.\nAlmost godlike.\nBetter, even more magnificent than before.\nNot for the faint of heart.\n\n:8b_v:\n:8b_e:\n:8b_r:\n:8b_t:\n:8b_i:\n:8b_c:\n:8b_a:\n:8b_l:\n\n:8b_s:\n:8b_u:\n:8b_p:\n:8b_r:\n:8b_e:\n:8b_m:\n:8b_a:\n:8b_c:\n:8b_y:\n\n:8b_a:\n:8b_d:\n:8b_v:\n:8b_o:\n:8b_c:\n:8b_a:\n:8b_t:\n:8b_e:\n\n#niu refugee. \nProgramming and tech talk is mostly at @pureevil@functional.cafe but occasionally leaks.\nI write and actively use proprietary software. \n\nDuke Nukem did nothing wrong.","pleroma":{"actor_type":"Person","discoverable":false,"no_rich_text":true,"show_role":false},"privacy":"public","sensitive":false},"statuses_count":9437,"url":"https://stereophonic.space/users/newt","username":"newt"},"application":{"name":"Web","website":null},"bookmarked":false,"card":null,"content":"My internet is ded. Send me more internets please :comfygeek:","created_at":"2021-01-15T22:02:02.000Z","emojis":[{"shortcode":"comfygeek","static_url":"https://stereophonic.space/emoji/comfy/comfygeek.png","url":"https://stereophonic.space/emoji/comfy/comfygeek.png","visible_in_picker":false}],"favourited":false,"favourites_count":2,"id":"A3H6VFhTjIC2LXefVg","in_reply_to_account_id":null,"in_reply_to_id":null,"language":null,"media_attachments":[],"mentions":[],"muted":false,"pinned":false,"pleroma":{"content":{"text/plain":"My internet is ded. Send me more internets please :comfygeek:"},"conversation_id":20781223,"direct_conversation_id":null,"emoji_reactions":[],"expires_at":null,"in_reply_to_account_acct":null,"local":true,"parent_visible":false,"spoiler_text":{"text/plain":""},"thread_muted":false},"poll":null,"reblog":null,"reblogged":false,"reblogs_count":0,"replies_count":3,"sensitive":false,"spoiler_text":"","tags":[],"text":null,"uri":"https://stereophonic.space/objects/5f533d84-01a8-4f3d-baa7-ed079b089138","url":"https://stereophonic.space/notice/A3H6VFhTjIC2LXefVg","visibility":"public"},"type":"favourite"},{"account":{"acct":"sathariel@gentoo.live","avatar":"https://stereophonic.space/proxy/KIgV_Ed9V9-8IKk-die8es3zBXI/aHR0cHM6Ly9nZW50b28ubGl2ZS9tZWRpYS8zNzk1MjQ4NzcxMDFhZDUxZjllMWU3ZmE0MWY0MGJkY2FjOGQxODg5MjBhZWM4YTEwMDI4Y2M3ZGNiYTc2MTczLmJsb2I/379524877101ad51f9e1e7fa41f40bdcac8d188920aec8a10028cc7dcba76173.blob","avatar_static":"https://stereophonic.space/proxy/KIgV_Ed9V9-8IKk-die8es3zBXI/aHR0cHM6Ly9nZW50b28ubGl2ZS9tZWRpYS8zNzk1MjQ4NzcxMDFhZDUxZjllMWU3ZmE0MWY0MGJkY2FjOGQxODg5MjBhZWM4YTEwMDI4Y2M3ZGNiYTc2MTczLmJsb2I/379524877101ad51f9e1e7fa41f40bdcac8d188920aec8a10028cc7dcba76173.blob","bot":false,"created_at":"2020-05-30T00:22:44.000Z","display_name":"Sathariel :chaos_pink: Laugh is the Law","emojis":[{"shortcode":"chaos_pink","static_url":"https://stereophonic.space/proxy/ulolyNhFhc2ZfkCkjG2UKWgp1ko/aHR0cHM6Ly9nZW50b28ubGl2ZS9lbW9qaS9jdXN0b20vY2hhb3NfcGluay5wbmc/chaos_pink.png","url":"https://stereophonic.space/proxy/ulolyNhFhc2ZfkCkjG2UKWgp1ko/aHR0cHM6Ly9nZW50b28ubGl2ZS9lbW9qaS9jdXN0b20vY2hhb3NfcGluay5wbmc/chaos_pink.png","visible_in_picker":false}],"fields":[{"name":"XMPP","value":"sathariel@magicadro.ga"},{"name":"Matrix","value":"<a href=\"https://gentoo.live/users/sathariel\" rel=\"ugc\">@sathariel</a>:blob.cat"}],"followers_count":320,"following_count":234,"header":"https://stereophonic.space/proxy/xyLTi9kvPEnNBvvMWTjqlZZNaHo/aHR0cHM6Ly9nZW50b28ubGl2ZS9tZWRpYS83YTc0NTk4ODk0YmRmNjNiMDM2YmI0NWIyM2E3NDcyOGQ3ODJmMDQxZWIwODM3MWQ1YmE2NGYzMTFjMTYxYWRmLnBuZw/7a74598894bdf63b036bb45b23a74728d782f041eb08371d5ba64f311c161adf.png","header_static":"https://stereophonic.space/proxy/xyLTi9kvPEnNBvvMWTjqlZZNaHo/aHR0cHM6Ly9nZW50b28ubGl2ZS9tZWRpYS83YTc0NTk4ODk0YmRmNjNiMDM2YmI0NWIyM2E3NDcyOGQ3ODJmMDQxZWIwODM3MWQ1YmE2NGYzMTFjMTYxYWRmLnBuZw/7a74598894bdf63b036bb45b23a74728d782f041eb08371d5ba64f311c161adf.png","id":"9vYUMtDznVwH6ixy6q","locked":false,"note":"Magician of Paradoxes.<br/>I have no interest on ordinary humans, but if you have got magic or psychic powers, have traveled in time, discovered a conspiracy, came from another planet or dimension please add me.<br/><br/><a href=\"https://sathariel.tk\">https://sathariel.tk</a><br/><br/><br/>for as much as you claim to be crazy, sathy, you&#39;re more reasonable than 2/3 of the internet<br/>- Nerthos at SPC<br/><br/>sathy is a mystery box~<br/>- Kogomi (Rina-chan) at RaRuRe<br/>","pleroma":{"accepts_chat_messages":true,"ap_id":"https://gentoo.live/users/sathariel","background_image":null,"confirmation_pending":false,"deactivated":false,"favicon":null,"hide_favorites":true,"hide_followers":false,"hide_followers_count":false,"hide_follows":false,"hide_follows_count":false,"is_admin":false,"is_moderator":false,"relationship":{},"skip_thread_containment":false,"tags":[]},"source":{"fields":[],"note":"","pleroma":{"actor_type":"Person","discoverable":false},"sensitive":false},"statuses_count":6544,"url":"https://gentoo.live/users/sathariel","username":"sathariel"},"created_at":"2021-01-15T22:09:58.000Z","id":"326520","pleroma":{"is_muted":false,"is_seen":true},"status":{"account":{"acct":"sathariel@gentoo.live","avatar":"https://stereophonic.space/proxy/KIgV_Ed9V9-8IKk-die8es3zBXI/aHR0cHM6Ly9nZW50b28ubGl2ZS9tZWRpYS8zNzk1MjQ4NzcxMDFhZDUxZjllMWU3ZmE0MWY0MGJkY2FjOGQxODg5MjBhZWM4YTEwMDI4Y2M3ZGNiYTc2MTczLmJsb2I/379524877101ad51f9e1e7fa41f40bdcac8d188920aec8a10028cc7dcba76173.blob","avatar_static":"https://stereophonic.space/proxy/KIgV_Ed9V9-8IKk-die8es3zBXI/aHR0cHM6Ly9nZW50b28ubGl2ZS9tZWRpYS8zNzk1MjQ4NzcxMDFhZDUxZjllMWU3ZmE0MWY0MGJkY2FjOGQxODg5MjBhZWM4YTEwMDI4Y2M3ZGNiYTc2MTczLmJsb2I/379524877101ad51f9e1e7fa41f40bdcac8d188920aec8a10028cc7dcba76173.blob","bot":false,"created_at":"2020-05-30T00:22:44.000Z","display_name":"Sathariel :chaos_pink: Laugh is the Law","emojis":[{"shortcode":"chaos_pink","static_url":"https://stereophonic.space/proxy/ulolyNhFhc2ZfkCkjG2UKWgp1ko/aHR0cHM6Ly9nZW50b28ubGl2ZS9lbW9qaS9jdXN0b20vY2hhb3NfcGluay5wbmc/chaos_pink.png","url":"https://stereophonic.space/proxy/ulolyNhFhc2ZfkCkjG2UKWgp1ko/aHR0cHM6Ly9nZW50b28ubGl2ZS9lbW9qaS9jdXN0b20vY2hhb3NfcGluay5wbmc/chaos_pink.png","visible_in_picker":false}],"fields":[{"name":"XMPP","value":"sathariel@magicadro.ga"},{"name":"Matrix","value":"<a href=\"https://gentoo.live/users/sathariel\" rel=\"ugc\">@sathariel</a>:blob.cat"}],"followers_count":320,"following_count":234,"header":"https://stereophonic.space/proxy/xyLTi9kvPEnNBvvMWTjqlZZNaHo/aHR0cHM6Ly9nZW50b28ubGl2ZS9tZWRpYS83YTc0NTk4ODk0YmRmNjNiMDM2YmI0NWIyM2E3NDcyOGQ3ODJmMDQxZWIwODM3MWQ1YmE2NGYzMTFjMTYxYWRmLnBuZw/7a74598894bdf63b036bb45b23a74728d782f041eb08371d5ba64f311c161adf.png","header_static":"https://stereophonic.space/proxy/xyLTi9kvPEnNBvvMWTjqlZZNaHo/aHR0cHM6Ly9nZW50b28ubGl2ZS9tZWRpYS83YTc0NTk4ODk0YmRmNjNiMDM2YmI0NWIyM2E3NDcyOGQ3ODJmMDQxZWIwODM3MWQ1YmE2NGYzMTFjMTYxYWRmLnBuZw/7a74598894bdf63b036bb45b23a74728d782f041eb08371d5ba64f311c161adf.png","id":"9vYUMtDznVwH6ixy6q","locked":false,"note":"Magician of Paradoxes.<br/>I have no interest on ordinary humans, but if you have got magic or psychic powers, have traveled in time, discovered a conspiracy, came from another planet or dimension please add me.<br/><br/><a href=\"https://sathariel.tk\">https://sathariel.tk</a><br/><br/><br/>for as much as you claim to be crazy, sathy, you&#39;re more reasonable than 2/3 of the internet<br/>- Nerthos at SPC<br/><br/>sathy is a mystery box~<br/>- Kogomi (Rina-chan) at RaRuRe<br/>","pleroma":{"accepts_chat_messages":true,"ap_id":"https://gentoo.live/users/sathariel","background_image":null,"confirmation_pending":false,"deactivated":false,"favicon":null,"hide_favorites":true,"hide_followers":false,"hide_followers_count":false,"hide_follows":false,"hide_follows_count":false,"is_admin":false,"is_moderator":false,"relationship":{},"skip_thread_containment":false,"tags":[]},"source":{"fields":[],"note":"","pleroma":{"actor_type":"Person","discoverable":false},"sensitive":false},"statuses_count":6544,"url":"https://gentoo.live/users/sathariel","username":"sathariel"},"application":{"name":"Web","website":null},"bookmarked":false,"card":null,"content":"<span class=\"h-card\"><a class=\"u-url mention\" data-user=\"9vYsOX0iD0sfQCQyCu\" href=\"https://stereophonic.space/users/newt\">@<span>newt</span></a></span>","created_at":"2021-01-15T22:10:40.000Z","emojis":[],"favourited":true,"favourites_count":6,"id":"A3H7D5P1NSPv9NvJ5s","in_reply_to_account_id":"9rZ2STPb7FA7JnMRii","in_reply_to_id":"A3H6VFhTjIC2LXefVg","language":null,"media_attachments":[{"description":"","id":"-1561668185","pleroma":{"mime_type":"image/gif"},"preview_url":"https://stereophonic.space/proxy/nKbnyAv1PCRllODqFVg6497mOvo/aHR0cHM6Ly9nZW50b28ubGl2ZS9tZWRpYS82ZmY3ZGE2NWNjYTlkYmVlMGY0ZTJmZDE1YTQxNTdmMDVmODQzMzM1NmRlMmQwYTJhZGM5MWUyOWQ1ODcxZTM4LmdpZg/6ff7da65cca9dbee0f4e2fd15a4157f05f8433356de2d0a2adc91e29d5871e38.gif","remote_url":"https://stereophonic.space/proxy/nKbnyAv1PCRllODqFVg6497mOvo/aHR0cHM6Ly9nZW50b28ubGl2ZS9tZWRpYS82ZmY3ZGE2NWNjYTlkYmVlMGY0ZTJmZDE1YTQxNTdmMDVmODQzMzM1NmRlMmQwYTJhZGM5MWUyOWQ1ODcxZTM4LmdpZg/6ff7da65cca9dbee0f4e2fd15a4157f05f8433356de2d0a2adc91e29d5871e38.gif","text_url":"https://stereophonic.space/proxy/nKbnyAv1PCRllODqFVg6497mOvo/aHR0cHM6Ly9nZW50b28ubGl2ZS9tZWRpYS82ZmY3ZGE2NWNjYTlkYmVlMGY0ZTJmZDE1YTQxNTdmMDVmODQzMzM1NmRlMmQwYTJhZGM5MWUyOWQ1ODcxZTM4LmdpZg/6ff7da65cca9dbee0f4e2fd15a4157f05f8433356de2d0a2adc91e29d5871e38.gif","type":"image","url":"https://stereophonic.space/proxy/nKbnyAv1PCRllODqFVg6497mOvo/aHR0cHM6Ly9nZW50b28ubGl2ZS9tZWRpYS82ZmY3ZGE2NWNjYTlkYmVlMGY0ZTJmZDE1YTQxNTdmMDVmODQzMzM1NmRlMmQwYTJhZGM5MWUyOWQ1ODcxZTM4LmdpZg/6ff7da65cca9dbee0f4e2fd15a4157f05f8433356de2d0a2adc91e29d5871e38.gif"}],"mentions":[{"acct":"newt","id":"9rZ2STPb7FA7JnMRii","url":"https://stereophonic.space/users/newt","username":"newt"}],"muted":false,"pinned":false,"pleroma":{"content":{"text/plain":"@newt"},"conversation_id":20781223,"direct_conversation_id":null,"emoji_reactions":[],"expires_at":null,"in_reply_to_account_acct":"newt","local":false,"parent_visible":true,"spoiler_text":{"text/plain":""},"thread_muted":false},"poll":null,"reblog":null,"reblogged":false,"reblogs_count":4,"replies_count":0,"sensitive":false,"spoiler_text":"","tags":[],"text":null,"uri":"https://gentoo.live/objects/1b3beee0-b353-4c67-be65-399bfa936495","url":"https://gentoo.live/objects/1b3beee0-b353-4c67-be65-399bfa936495","visibility":"public"},"type":"mention"},{"account":{"acct":"Stellar@fedi.absturztau.be","avatar":"https://stereophonic.space/proxy/UY5VCkfndTEtGEXtl2cqsuFVSs8/aHR0cHM6Ly9mZWRpLmFic3R1cnp0YXUuYmUvbWVkaWEvNjVmNWUzMzU5NzY0MzdkMzY4MDVmODRhYzM5MDMzNTY1NmExMjRhZWZiMWZiNTM5YmZhMTc4MDY2M2FiMmZhYS5naWY/65f5e335976437d36805f84ac390335656a124aefb1fb539bfa1780663ab2faa.gif","avatar_static":"https://stereophonic.space/proxy/UY5VCkfndTEtGEXtl2cqsuFVSs8/aHR0cHM6Ly9mZWRpLmFic3R1cnp0YXUuYmUvbWVkaWEvNjVmNWUzMzU5NzY0MzdkMzY4MDVmODRhYzM5MDMzNTY1NmExMjRhZWZiMWZiNTM5YmZhMTc4MDY2M2FiMmZhYS5naWY/65f5e335976437d36805f84ac390335656a124aefb1fb539bfa1780663ab2faa.gif","bot":false,"created_at":"2019-08-06T21:58:05.000Z","display_name":"ï¼³ï½”ï½…ï½Œï½Œï½ï½’ :ms_pleroma:â€‹â€‹","emojis":[{"shortcode":"ms_pleroma","static_url":"https://stereophonic.space/proxy/CMfON3VPh-np1C4ggKZSyukVqXU/aHR0cHM6Ly9mZWRpLmFic3R1cnp0YXUuYmUvZW1vamkvY3VzdG9tL21zX3BsZXJvbWEucG5n/ms_pleroma.png","url":"https://stereophonic.space/proxy/CMfON3VPh-np1C4ggKZSyukVqXU/aHR0cHM6Ly9mZWRpLmFic3R1cnp0YXUuYmUvZW1vamkvY3VzdG9tL21zX3BsZXJvbWEucG5n/ms_pleroma.png","visible_in_picker":false}],"fields":[{"name":"English","value":"French"},{"name":"Very","value":"Lewd"},{"name":"DONT","value":"DEAD"},{"name":"OPEN","value":"INSIDE"}],"followers_count":272,"following_count":399,"header":"https://stereophonic.space/proxy/yY_OPvFzFoJQJEnKyHi2qb4p_WM/aHR0cHM6Ly9mZWRpLmFic3R1cnp0YXUuYmUvbWVkaWEvNzZmMDk5ZDQxNjU2NzNmOWVjN2VhZGMyOTIzYWRhOGI0ZTc3Njc5NWRkYjUxZjI4MGU3ZWE1NWRlMjYxNTljMC5naWY/76f099d4165673f9ec7eadc2923ada8b4e776795ddb51f280e7ea55de26159c0.gif","header_static":"https://stereophonic.space/proxy/yY_OPvFzFoJQJEnKyHi2qb4p_WM/aHR0cHM6Ly9mZWRpLmFic3R1cnp0YXUuYmUvbWVkaWEvNzZmMDk5ZDQxNjU2NzNmOWVjN2VhZGMyOTIzYWRhOGI0ZTc3Njc5NWRkYjUxZjI4MGU3ZWE1NWRlMjYxNTljMC5naWY/76f099d4165673f9ec7eadc2923ada8b4e776795ddb51f280e7ea55de26159c0.gif","id":"9lcer8OuWEeNQCFmtc","locked":false,"note":"I love music, I love abstract art, i love old computers and cars, i love vaporwave and i make art.","pleroma":{"accepts_chat_messages":true,"ap_id":"https://fedi.absturztau.be/users/Stellar","background_image":null,"confirmation_pending":false,"deactivated":false,"favicon":null,"hide_favorites":true,"hide_followers":false,"hide_followers_count":false,"hide_follows":false,"hide_follows_count":false,"is_admin":false,"is_moderator":false,"relationship":{},"skip_thread_containment":false,"tags":[]},"source":{"fields":[],"note":"","pleroma":{"actor_type":"Person","discoverable":false},"sensitive":false},"statuses_count":16796,"url":"https://fedi.absturztau.be/users/Stellar","username":"Stellar"},"created_at":"2021-01-15T22:05:57.000Z","id":"326519","pleroma":{"is_muted":false,"is_seen":true},"status":{"account":{"acct":"newt","avatar":"https://stereophonic.space/media/badfe007441b8daa3da9c1dfcd56a71378e3a2c0022745030cfe017057129582.blob","avatar_static":"https://stereophonic.space/media/badfe007441b8daa3da9c1dfcd56a71378e3a2c0022745030cfe017057129582.blob","bot":false,"created_at":"2020-01-31T15:16:18.000Z","display_name":"NÌ¸Ì¢Ì¡Ì¢Ì¤Ì®Ì¥Ì²ÍÍ‹Í†Î£ÌµÌ›ÌžÌ€ÌˆÌÌ†Ì“ÌÍ›Ì‹áº‚ÌµÌ¢Ì«Ì£Ì¦Ì»Ì©Í‘Ì€ÍTÌµÍ™Ì¯Ì”ÌˆÌÍÍ…","emojis":[{"shortcode":"8b_a","static_url":"https://stereophonic.space/emoji/custom/8b_a.png","url":"https://stereophonic.space/emoji/custom/8b_a.png","visible_in_picker":false},{"shortcode":"8b_c","static_url":"https://stereophonic.space/emoji/custom/8b_c.png","url":"https://stereophonic.space/emoji/custom/8b_c.png","visible_in_picker":false},{"shortcode":"8b_d","static_url":"https://stereophonic.space/emoji/custom/8b_d.png","url":"https://stereophonic.space/emoji/custom/8b_d.png","visible_in_picker":false},{"shortcode":"8b_e","static_url":"https://stereophonic.space/emoji/custom/8b_e.png","url":"https://stereophonic.space/emoji/custom/8b_e.png","visible_in_picker":false},{"shortcode":"8b_i","static_url":"https://stereophonic.space/emoji/custom/8b_i.png","url":"https://stereophonic.space/emoji/custom/8b_i.png","visible_in_picker":false},{"shortcode":"8b_l","static_url":"https://stereophonic.space/emoji/custom/8b_l.png","url":"https://stereophonic.space/emoji/custom/8b_l.png","visible_in_picker":false},{"shortcode":"8b_m","static_url":"https://stereophonic.space/emoji/custom/8b_m.png","url":"https://stereophonic.space/emoji/custom/8b_m.png","visible_in_picker":false},{"shortcode":"8b_o","static_url":"https://stereophonic.space/emoji/custom/8b_o.png","url":"https://stereophonic.space/emoji/custom/8b_o.png","visible_in_picker":false},{"shortcode":"8b_p","static_url":"https://stereophonic.space/emoji/custom/8b_p.png","url":"https://stereophonic.space/emoji/custom/8b_p.png","visible_in_picker":false},{"shortcode":"8b_r","static_url":"https://stereophonic.space/emoji/custom/8b_r.png","url":"https://stereophonic.space/emoji/custom/8b_r.png","visible_in_picker":false},{"shortcode":"8b_s","static_url":"https://stereophonic.space/emoji/custom/8b_s.png","url":"https://stereophonic.space/emoji/custom/8b_s.png","visible_in_picker":false},{"shortcode":"8b_t","static_url":"https://stereophonic.space/emoji/custom/8b_t.png","url":"https://stereophonic.space/emoji/custom/8b_t.png","visible_in_picker":false},{"shortcode":"8b_u","static_url":"https://stereophonic.space/emoji/custom/8b_u.png","url":"https://stereophonic.space/emoji/custom/8b_u.png","visible_in_picker":false},{"shortcode":"8b_v","static_url":"https://stereophonic.space/emoji/custom/8b_v.png","url":"https://stereophonic.space/emoji/custom/8b_v.png","visible_in_picker":false},{"shortcode":"8b_y","static_url":"https://stereophonic.space/emoji/custom/8b_y.png","url":"https://stereophonic.space/emoji/custom/8b_y.png","visible_in_picker":false},{"shortcode":"comfycofesmirk","static_url":"https://stereophonic.space/emoji/comfy/comfycofesmirk.png","url":"https://stereophonic.space/emoji/comfy/comfycofesmirk.png","visible_in_picker":false}],"fields":[{"name":"cofe","value":":comfycofesmirk:"}],"follow_requests_count":0,"followers_count":315,"following_count":198,"header":"https://stereophonic.space/media/e43024f466693cad7887a60ffce07861bd15b9b54dd67fee90c774534787ee4d.jpg","header_static":"https://stereophonic.space/media/e43024f466693cad7887a60ffce07861bd15b9b54dd67fee90c774534787ee4d.jpg","id":"9rZ2STPb7FA7JnMRii","locked":false,"note":"Chaos evangelist.<br/>Sometimes evil.<br/>Almost godlike.<br/>Better, even more magnificent than before.<br/>Not for the faint of heart.<br/><br/>:8b_v:<br/>:8b_e:<br/>:8b_r:<br/>:8b_t:<br/>:8b_i:<br/>:8b_c:<br/>:8b_a:<br/>:8b_l:<br/><br/>:8b_s:<br/>:8b_u:<br/>:8b_p:<br/>:8b_r:<br/>:8b_e:<br/>:8b_m:<br/>:8b_a:<br/>:8b_c:<br/>:8b_y:<br/><br/>:8b_a:<br/>:8b_d:<br/>:8b_v:<br/>:8b_o:<br/>:8b_c:<br/>:8b_a:<br/>:8b_t:<br/>:8b_e:<br/><br/><a class=\"hashtag\" data-tag=\"niu\" href=\"https://stereophonic.space/tag/niu\">#niu</a> refugee. <br/>Programming and tech talk is mostly at <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"9jCuHkYZPSuOlVU6qm\" href=\"https://functional.cafe/@pureevil\">@<span>pureevil@functional.cafe</span></a></span> but occasionally leaks.<br/>I write and actively use proprietary software. <br/><br/>Duke Nukem did nothing wrong.","pleroma":{"accepts_chat_messages":true,"allow_following_move":true,"ap_id":"https://stereophonic.space/users/newt","background_image":null,"confirmation_pending":false,"deactivated":false,"favicon":null,"hide_favorites":true,"hide_followers":false,"hide_followers_count":false,"hide_follows":false,"hide_follows_count":false,"is_admin":true,"is_moderator":false,"notification_settings":{"block_from_strangers":false,"hide_notification_contents":false},"relationship":{},"skip_thread_containment":false,"tags":[],"unread_conversation_count":34,"unread_notifications_count":10},"source":{"fields":[{"name":"cofe","value":":comfycofesmirk:"}],"note":"Chaos evangelist.\nSometimes evil.\nAlmost godlike.\nBetter, even more magnificent than before.\nNot for the faint of heart.\n\n:8b_v:\n:8b_e:\n:8b_r:\n:8b_t:\n:8b_i:\n:8b_c:\n:8b_a:\n:8b_l:\n\n:8b_s:\n:8b_u:\n:8b_p:\n:8b_r:\n:8b_e:\n:8b_m:\n:8b_a:\n:8b_c:\n:8b_y:\n\n:8b_a:\n:8b_d:\n:8b_v:\n:8b_o:\n:8b_c:\n:8b_a:\n:8b_t:\n:8b_e:\n\n#niu refugee. \nProgramming and tech talk is mostly at @pureevil@functional.cafe but occasionally leaks.\nI write and actively use proprietary software. \n\nDuke Nukem did nothing wrong.","pleroma":{"actor_type":"Person","discoverable":false,"no_rich_text":true,"show_role":false},"privacy":"public","sensitive":false},"statuses_count":9437,"url":"https://stereophonic.space/users/newt","username":"newt"},"application":{"name":"Web","website":null},"bookmarked":false,"card":null,"content":"<span class=\"h-card\"><a class=\"u-url mention\" data-user=\"9zzoVd0oJZMuqGNzLk\" href=\"https://cdrom.tokyo/users/emilis\">@<span>emilis</span></a></span> :comfyevil:","created_at":"2021-01-15T22:02:51.000Z","emojis":[{"shortcode":"comfyevil","static_url":"https://stereophonic.space/emoji/comfy/comfyevil.png","url":"https://stereophonic.space/emoji/comfy/comfyevil.png","visible_in_picker":false}],"favourited":false,"favourites_count":1,"id":"A3H6ZlSxZCx01b11km","in_reply_to_account_id":"9zzoVd0oJZMuqGNzLk","in_reply_to_id":"A3H6X8mUQSilSxtp44","language":null,"media_attachments":[],"mentions":[{"acct":"emilis@cdrom.tokyo","id":"9zzoVd0oJZMuqGNzLk","url":"https://cdrom.tokyo/users/emilis","username":"emilis"}],"muted":false,"pinned":false,"pleroma":{"content":{"text/plain":"@emilis :comfyevil:"},"conversation_id":20781223,"direct_conversation_id":null,"emoji_reactions":[],"expires_at":null,"in_reply_to_account_acct":"emilis@cdrom.tokyo","local":true,"parent_visible":true,"spoiler_text":{"text/plain":""},"thread_muted":false},"poll":null,"reblog":null,"reblogged":false,"reblogs_count":0,"replies_count":1,"sensitive":false,"spoiler_text":"","tags":[],"text":null,"uri":"https://stereophonic.space/objects/8fd0a989-3489-4e32-9c92-b96081ae6d1f","url":"https://stereophonic.space/notice/A3H6ZlSxZCx01b11km","visibility":"public"},"type":"favourite"},{"account":{"acct":"Stellar@fedi.absturztau.be","avatar":"https://stereophonic.space/proxy/UY5VCkfndTEtGEXtl2cqsuFVSs8/aHR0cHM6Ly9mZWRpLmFic3R1cnp0YXUuYmUvbWVkaWEvNjVmNWUzMzU5NzY0MzdkMzY4MDVmODRhYzM5MDMzNTY1NmExMjRhZWZiMWZiNTM5YmZhMTc4MDY2M2FiMmZhYS5naWY/65f5e335976437d36805f84ac390335656a124aefb1fb539bfa1780663ab2faa.gif","avatar_static":"https://stereophonic.space/proxy/UY5VCkfndTEtGEXtl2cqsuFVSs8/aHR0cHM6Ly9mZWRpLmFic3R1cnp0YXUuYmUvbWVkaWEvNjVmNWUzMzU5NzY0MzdkMzY4MDVmODRhYzM5MDMzNTY1NmExMjRhZWZiMWZiNTM5YmZhMTc4MDY2M2FiMmZhYS5naWY/65f5e335976437d36805f84ac390335656a124aefb1fb539bfa1780663ab2faa.gif","bot":false,"created_at":"2019-08-06T21:58:05.000Z","display_name":"ï¼³ï½”ï½…ï½Œï½Œï½ï½’ :ms_pleroma:â€‹â€‹","emojis":[{"shortcode":"ms_pleroma","static_url":"https://stereophonic.space/proxy/CMfON3VPh-np1C4ggKZSyukVqXU/aHR0cHM6Ly9mZWRpLmFic3R1cnp0YXUuYmUvZW1vamkvY3VzdG9tL21zX3BsZXJvbWEucG5n/ms_pleroma.png","url":"https://stereophonic.space/proxy/CMfON3VPh-np1C4ggKZSyukVqXU/aHR0cHM6Ly9mZWRpLmFic3R1cnp0YXUuYmUvZW1vamkvY3VzdG9tL21zX3BsZXJvbWEucG5n/ms_pleroma.png","visible_in_picker":false}],"fields":[{"name":"English","value":"French"},{"name":"Very","value":"Lewd"},{"name":"DONT","value":"DEAD"},{"name":"OPEN","value":"INSIDE"}],"followers_count":272,"following_count":399,"header":"https://stereophonic.space/proxy/yY_OPvFzFoJQJEnKyHi2qb4p_WM/aHR0cHM6Ly9mZWRpLmFic3R1cnp0YXUuYmUvbWVkaWEvNzZmMDk5ZDQxNjU2NzNmOWVjN2VhZGMyOTIzYWRhOGI0ZTc3Njc5NWRkYjUxZjI4MGU3ZWE1NWRlMjYxNTljMC5naWY/76f099d4165673f9ec7eadc2923ada8b4e776795ddb51f280e7ea55de26159c0.gif","header_static":"https://stereophonic.space/proxy/yY_OPvFzFoJQJEnKyHi2qb4p_WM/aHR0cHM6Ly9mZWRpLmFic3R1cnp0YXUuYmUvbWVkaWEvNzZmMDk5ZDQxNjU2NzNmOWVjN2VhZGMyOTIzYWRhOGI0ZTc3Njc5NWRkYjUxZjI4MGU3ZWE1NWRlMjYxNTljMC5naWY/76f099d4165673f9ec7eadc2923ada8b4e776795ddb51f280e7ea55de26159c0.gif","id":"9lcer8OuWEeNQCFmtc","locked":false,"note":"I love music, I love abstract art, i love old computers and cars, i love vaporwave and i make art.","pleroma":{"accepts_chat_messages":true,"ap_id":"https://fedi.absturztau.be/users/Stellar","background_image":null,"confirmation_pending":false,"deactivated":false,"favicon":null,"hide_favorites":true,"hide_followers":false,"hide_followers_count":false,"hide_follows":false,"hide_follows_count":false,"is_admin":false,"is_moderator":false,"relationship":{},"skip_thread_containment":false,"tags":[]},"source":{"fields":[],"note":"","pleroma":{"actor_type":"Person","discoverable":false},"sensitive":false},"statuses_count":16796,"url":"https://fedi.absturztau.be/users/Stellar","username":"Stellar"},"created_at":"2021-01-15T22:05:56.000Z","id":"326518","pleroma":{"is_muted":false,"is_seen":true},"status":{"account":{"acct":"newt","avatar":"https://stereophonic.space/media/badfe007441b8daa3da9c1dfcd56a71378e3a2c0022745030cfe017057129582.blob","avatar_static":"https://stereophonic.space/media/badfe007441b8daa3da9c1dfcd56a71378e3a2c0022745030cfe017057129582.blob","bot":false,"created_at":"2020-01-31T15:16:18.000Z","display_name":"NÌ¸Ì¢Ì¡Ì¢Ì¤Ì®Ì¥Ì²ÍÍ‹Í†Î£ÌµÌ›ÌžÌ€ÌˆÌÌ†Ì“ÌÍ›Ì‹áº‚ÌµÌ¢Ì«Ì£Ì¦Ì»Ì©Í‘Ì€ÍTÌµÍ™Ì¯Ì”ÌˆÌÍÍ…","emojis":[{"shortcode":"8b_a","static_url":"https://stereophonic.space/emoji/custom/8b_a.png","url":"https://stereophonic.space/emoji/custom/8b_a.png","visible_in_picker":false},{"shortcode":"8b_c","static_url":"https://stereophonic.space/emoji/custom/8b_c.png","url":"https://stereophonic.space/emoji/custom/8b_c.png","visible_in_picker":false},{"shortcode":"8b_d","static_url":"https://stereophonic.space/emoji/custom/8b_d.png","url":"https://stereophonic.space/emoji/custom/8b_d.png","visible_in_picker":false},{"shortcode":"8b_e","static_url":"https://stereophonic.space/emoji/custom/8b_e.png","url":"https://stereophonic.space/emoji/custom/8b_e.png","visible_in_picker":false},{"shortcode":"8b_i","static_url":"https://stereophonic.space/emoji/custom/8b_i.png","url":"https://stereophonic.space/emoji/custom/8b_i.png","visible_in_picker":false},{"shortcode":"8b_l","static_url":"https://stereophonic.space/emoji/custom/8b_l.png","url":"https://stereophonic.space/emoji/custom/8b_l.png","visible_in_picker":false},{"shortcode":"8b_m","static_url":"https://stereophonic.space/emoji/custom/8b_m.png","url":"https://stereophonic.space/emoji/custom/8b_m.png","visible_in_picker":false},{"shortcode":"8b_o","static_url":"https://stereophonic.space/emoji/custom/8b_o.png","url":"https://stereophonic.space/emoji/custom/8b_o.png","visible_in_picker":false},{"shortcode":"8b_p","static_url":"https://stereophonic.space/emoji/custom/8b_p.png","url":"https://stereophonic.space/emoji/custom/8b_p.png","visible_in_picker":false},{"shortcode":"8b_r","static_url":"https://stereophonic.space/emoji/custom/8b_r.png","url":"https://stereophonic.space/emoji/custom/8b_r.png","visible_in_picker":false},{"shortcode":"8b_s","static_url":"https://stereophonic.space/emoji/custom/8b_s.png","url":"https://stereophonic.space/emoji/custom/8b_s.png","visible_in_picker":false},{"shortcode":"8b_t","static_url":"https://stereophonic.space/emoji/custom/8b_t.png","url":"https://stereophonic.space/emoji/custom/8b_t.png","visible_in_picker":false},{"shortcode":"8b_u","static_url":"https://stereophonic.space/emoji/custom/8b_u.png","url":"https://stereophonic.space/emoji/custom/8b_u.png","visible_in_picker":false},{"shortcode":"8b_v","static_url":"https://stereophonic.space/emoji/custom/8b_v.png","url":"https://stereophonic.space/emoji/custom/8b_v.png","visible_in_picker":false},{"shortcode":"8b_y","static_url":"https://stereophonic.space/emoji/custom/8b_y.png","url":"https://stereophonic.space/emoji/custom/8b_y.png","visible_in_picker":false},{"shortcode":"comfycofesmirk","static_url":"https://stereophonic.space/emoji/comfy/comfycofesmirk.png","url":"https://stereophonic.space/emoji/comfy/comfycofesmirk.png","visible_in_picker":false}],"fields":[{"name":"cofe","value":":comfycofesmirk:"}],"follow_requests_count":0,"followers_count":315,"following_count":198,"header":"https://stereophonic.space/media/e43024f466693cad7887a60ffce07861bd15b9b54dd67fee90c774534787ee4d.jpg","header_static":"https://stereophonic.space/media/e43024f466693cad7887a60ffce07861bd15b9b54dd67fee90c774534787ee4d.jpg","id":"9rZ2STPb7FA7JnMRii","locked":false,"note":"Chaos evangelist.<br/>Sometimes evil.<br/>Almost godlike.<br/>Better, even more magnificent than before.<br/>Not for the faint of heart.<br/><br/>:8b_v:<br/>:8b_e:<br/>:8b_r:<br/>:8b_t:<br/>:8b_i:<br/>:8b_c:<br/>:8b_a:<br/>:8b_l:<br/><br/>:8b_s:<br/>:8b_u:<br/>:8b_p:<br/>:8b_r:<br/>:8b_e:<br/>:8b_m:<br/>:8b_a:<br/>:8b_c:<br/>:8b_y:<br/><br/>:8b_a:<br/>:8b_d:<br/>:8b_v:<br/>:8b_o:<br/>:8b_c:<br/>:8b_a:<br/>:8b_t:<br/>:8b_e:<br/><br/><a class=\"hashtag\" data-tag=\"niu\" href=\"https://stereophonic.space/tag/niu\">#niu</a> refugee. <br/>Programming and tech talk is mostly at <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"9jCuHkYZPSuOlVU6qm\" href=\"https://functional.cafe/@pureevil\">@<span>pureevil@functional.cafe</span></a></span> but occasionally leaks.<br/>I write and actively use proprietary software. <br/><br/>Duke Nukem did nothing wrong.","pleroma":{"accepts_chat_messages":true,"allow_following_move":true,"ap_id":"https://stereophonic.space/users/newt","background_image":null,"confirmation_pending":false,"deactivated":false,"favicon":null,"hide_favorites":true,"hide_followers":false,"hide_followers_count":false,"hide_follows":false,"hide_follows_count":false,"is_admin":true,"is_moderator":false,"notification_settings":{"block_from_strangers":false,"hide_notification_contents":false},"relationship":{},"skip_thread_containment":false,"tags":[],"unread_conversation_count":34,"unread_notifications_count":10},"source":{"fields":[{"name":"cofe","value":":comfycofesmirk:"}],"note":"Chaos evangelist.\nSometimes evil.\nAlmost godlike.\nBetter, even more magnificent than before.\nNot for the faint of heart.\n\n:8b_v:\n:8b_e:\n:8b_r:\n:8b_t:\n:8b_i:\n:8b_c:\n:8b_a:\n:8b_l:\n\n:8b_s:\n:8b_u:\n:8b_p:\n:8b_r:\n:8b_e:\n:8b_m:\n:8b_a:\n:8b_c:\n:8b_y:\n\n:8b_a:\n:8b_d:\n:8b_v:\n:8b_o:\n:8b_c:\n:8b_a:\n:8b_t:\n:8b_e:\n\n#niu refugee. \nProgramming and tech talk is mostly at @pureevil@functional.cafe but occasionally leaks.\nI write and actively use proprietary software. \n\nDuke Nukem did nothing wrong.","pleroma":{"actor_type":"Person","discoverable":false,"no_rich_text":true,"show_role":false},"privacy":"public","sensitive":false},"statuses_count":9437,"url":"https://stereophonic.space/users/newt","username":"newt"},"application":{"name":"Web","website":null},"bookmarked":false,"card":null,"content":"My internet is ded. Send me more internets please :comfygeek:","created_at":"2021-01-15T22:02:02.000Z","emojis":[{"shortcode":"comfygeek","static_url":"https://stereophonic.space/emoji/comfy/comfygeek.png","url":"https://stereophonic.space/emoji/comfy/comfygeek.png","visible_in_picker":false}],"favourited":false,"favourites_count":2,"id":"A3H6VFhTjIC2LXefVg","in_reply_to_account_id":null,"in_reply_to_id":null,"language":null,"media_attachments":[],"mentions":[],"muted":false,"pinned":false,"pleroma":{"content":{"text/plain":"My internet is ded. Send me more internets please :comfygeek:"},"conversation_id":20781223,"direct_conversation_id":null,"emoji_reactions":[],"expires_at":null,"in_reply_to_account_acct":null,"local":true,"parent_visible":false,"spoiler_text":{"text/plain":""},"thread_muted":false},"poll":null,"reblog":null,"reblogged":false,"reblogs_count":0,"replies_count":3,"sensitive":false,"spoiler_text":"","tags":[],"text":null,"uri":"https://stereophonic.space/objects/5f533d84-01a8-4f3d-baa7-ed079b089138","url":"https://stereophonic.space/notice/A3H6VFhTjIC2LXefVg","visibility":"public"},"type":"favourite"},{"account":{"acct":"emilis@cdrom.tokyo","avatar":"https://stereophonic.space/proxy/8V0mOwZFa_B-_CynqAMBTct_6gY/aHR0cHM6Ly9jZHJvbS50b2t5by9tZWRpYS9lODIxMzc0MWJjZWE5MmIzN2JhNWFmM2EzZmE5NjZjNTU2NzFkZDMxZTUyZjZiNWRmNzJmYTM0ZDk1YTI0NTdmLmpwZw/e8213741bcea92b37ba5af3a3fa966c55671dd31e52f6b5df72fa34d95a2457f.jpg","avatar_static":"https://stereophonic.space/proxy/8V0mOwZFa_B-_CynqAMBTct_6gY/aHR0cHM6Ly9jZHJvbS50b2t5by9tZWRpYS9lODIxMzc0MWJjZWE5MmIzN2JhNWFmM2EzZmE5NjZjNTU2NzFkZDMxZTUyZjZiNWRmNzJmYTM0ZDk1YTI0NTdmLmpwZw/e8213741bcea92b37ba5af3a3fa966c55671dd31e52f6b5df72fa34d95a2457f.jpg","bot":false,"created_at":"2020-10-09T20:14:01.000Z","display_name":"romaboo :jigglypuff:","emojis":[{"shortcode":"jigglypuff","static_url":"https://stereophonic.space/proxy/bnKBn39yPRzUVLRRsLrf-6g4u04/aHR0cHM6Ly9jZHJvbS50b2t5by9lbW9qaS9jZHJvbS9qaWdnbHlwdWZmLnBuZw/jigglypuff.png","url":"https://stereophonic.space/proxy/bnKBn39yPRzUVLRRsLrf-6g4u04/aHR0cHM6Ly9jZHJvbS50b2t5by9lbW9qaS9jZHJvbS9qaWdnbHlwdWZmLnBuZw/jigglypuff.png","visible_in_picker":false}],"fields":[],"followers_count":6,"following_count":12,"header":"https://stereophonic.space/proxy/oeQXvgFN5DnvG8xvOo-NU7BBbO0/aHR0cHM6Ly9jZHJvbS50b2t5by9tZWRpYS81NTE1MThhYzRlNGQ0YTJiZWI1M2ExNTgxOTIwYzJkNDNmYjUzMDA1ZWI2MTU4MjBiMDE2NGYxMDczMTRmMjk4LmpwZw/551518ac4e4d4a2beb53a1581920c2d43fb53005eb615820b0164f107314f298.jpg","header_static":"https://stereophonic.space/proxy/oeQXvgFN5DnvG8xvOo-NU7BBbO0/aHR0cHM6Ly9jZHJvbS50b2t5by9tZWRpYS81NTE1MThhYzRlNGQ0YTJiZWI1M2ExNTgxOTIwYzJkNDNmYjUzMDA1ZWI2MTU4MjBiMDE2NGYxMDczMTRmMjk4LmpwZw/551518ac4e4d4a2beb53a1581920c2d43fb53005eb615820b0164f107314f298.jpg","id":"9zzoVd0oJZMuqGNzLk","locked":false,"note":"lego is based on nipples<br/><br/>In lingua latina: <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"9vqY7exhRY86vqnH6m\" href=\"https://cdrom.tokyo/users/aemilivs\">@<span>aemilivs</span></a></span>","pleroma":{"accepts_chat_messages":true,"ap_id":"https://cdrom.tokyo/users/emilis","background_image":null,"confirmation_pending":false,"deactivated":false,"favicon":null,"hide_favorites":true,"hide_followers":false,"hide_followers_count":false,"hide_follows":false,"hide_follows_count":false,"is_admin":false,"is_moderator":false,"relationship":{},"skip_thread_containment":false,"tags":[]},"source":{"fields":[],"note":"","pleroma":{"actor_type":"Person","discoverable":true},"sensitive":false},"statuses_count":4721,"url":"https://cdrom.tokyo/users/emilis","username":"emilis"},"created_at":"2021-01-15T22:05:04.000Z","id":"326517","pleroma":{"is_muted":false,"is_seen":true},"status":{"account":{"acct":"emilis@cdrom.tokyo","avatar":"https://stereophonic.space/proxy/8V0mOwZFa_B-_CynqAMBTct_6gY/aHR0cHM6Ly9jZHJvbS50b2t5by9tZWRpYS9lODIxMzc0MWJjZWE5MmIzN2JhNWFmM2EzZmE5NjZjNTU2NzFkZDMxZTUyZjZiNWRmNzJmYTM0ZDk1YTI0NTdmLmpwZw/e8213741bcea92b37ba5af3a3fa966c55671dd31e52f6b5df72fa34d95a2457f.jpg","avatar_static":"https://stereophonic.space/proxy/8V0mOwZFa_B-_CynqAMBTct_6gY/aHR0cHM6Ly9jZHJvbS50b2t5by9tZWRpYS9lODIxMzc0MWJjZWE5MmIzN2JhNWFmM2EzZmE5NjZjNTU2NzFkZDMxZTUyZjZiNWRmNzJmYTM0ZDk1YTI0NTdmLmpwZw/e8213741bcea92b37ba5af3a3fa966c55671dd31e52f6b5df72fa34d95a2457f.jpg","bot":false,"created_at":"2020-10-09T20:14:01.000Z","display_name":"romaboo :jigglypuff:","emojis":[{"shortcode":"jigglypuff","static_url":"https://stereophonic.space/proxy/bnKBn39yPRzUVLRRsLrf-6g4u04/aHR0cHM6Ly9jZHJvbS50b2t5by9lbW9qaS9jZHJvbS9qaWdnbHlwdWZmLnBuZw/jigglypuff.png","url":"https://stereophonic.space/proxy/bnKBn39yPRzUVLRRsLrf-6g4u04/aHR0cHM6Ly9jZHJvbS50b2t5by9lbW9qaS9jZHJvbS9qaWdnbHlwdWZmLnBuZw/jigglypuff.png","visible_in_picker":false}],"fields":[],"followers_count":6,"following_count":12,"header":"https://stereophonic.space/proxy/oeQXvgFN5DnvG8xvOo-NU7BBbO0/aHR0cHM6Ly9jZHJvbS50b2t5by9tZWRpYS81NTE1MThhYzRlNGQ0YTJiZWI1M2ExNTgxOTIwYzJkNDNmYjUzMDA1ZWI2MTU4MjBiMDE2NGYxMDczMTRmMjk4LmpwZw/551518ac4e4d4a2beb53a1581920c2d43fb53005eb615820b0164f107314f298.jpg","header_static":"https://stereophonic.space/proxy/oeQXvgFN5DnvG8xvOo-NU7BBbO0/aHR0cHM6Ly9jZHJvbS50b2t5by9tZWRpYS81NTE1MThhYzRlNGQ0YTJiZWI1M2ExNTgxOTIwYzJkNDNmYjUzMDA1ZWI2MTU4MjBiMDE2NGYxMDczMTRmMjk4LmpwZw/551518ac4e4d4a2beb53a1581920c2d43fb53005eb615820b0164f107314f298.jpg","id":"9zzoVd0oJZMuqGNzLk","locked":false,"note":"lego is based on nipples<br/><br/>In lingua latina: <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"9vqY7exhRY86vqnH6m\" href=\"https://cdrom.tokyo/users/aemilivs\">@<span>aemilivs</span></a></span>","pleroma":{"accepts_chat_messages":true,"ap_id":"https://cdrom.tokyo/users/emilis","background_image":null,"confirmation_pending":false,"deactivated":false,"favicon":null,"hide_favorites":true,"hide_followers":false,"hide_followers_count":false,"hide_follows":false,"hide_follows_count":false,"is_admin":false,"is_moderator":false,"relationship":{},"skip_thread_containment":false,"tags":[]},"source":{"fields":[],"note":"","pleroma":{"actor_type":"Person","discoverable":true},"sensitive":false},"statuses_count":4721,"url":"https://cdrom.tokyo/users/emilis","username":"emilis"},"application":{"name":"Web","website":null},"bookmarked":false,"card":null,"content":"<p><span class=\"h-card\"><a class=\"u-url mention\" data-user=\"9vLK6FwkZYqQAO4wIS\" href=\"https://stereophonic.space/users/newt\">@<span>newt</span></a></span> bojo took my fucking internet :angryduck:</p>","created_at":"2021-01-15T22:05:03.000Z","emojis":[{"shortcode":"angryduck","static_url":"https://stereophonic.space/proxy/yHQSc7EX9LDoKI9p60DsxUKBMEo/aHR0cHM6Ly9jZHJvbS50b2t5by9lbW9qaS9zdG9sZW4vYW5ncnlkdWNrLnBuZw/angryduck.png","url":"https://stereophonic.space/proxy/yHQSc7EX9LDoKI9p60DsxUKBMEo/aHR0cHM6Ly9jZHJvbS50b2t5by9lbW9qaS9zdG9sZW4vYW5ncnlkdWNrLnBuZw/angryduck.png","visible_in_picker":false}],"favourited":false,"favourites_count":1,"id":"A3H6m2L8ejrppiD1iS","in_reply_to_account_id":"9rZ2STPb7FA7JnMRii","in_reply_to_id":"A3H6ZlSxZCx01b11km","language":null,"media_attachments":[],"mentions":[{"acct":"newt","id":"9rZ2STPb7FA7JnMRii","url":"https://stereophonic.space/users/newt","username":"newt"}],"muted":false,"pinned":false,"pleroma":{"content":{"text/plain":"@newt bojo took my fucking internet :angryduck:"},"conversation_id":20781223,"direct_conversation_id":null,"emoji_reactions":[],"expires_at":null,"in_reply_to_account_acct":"newt","local":false,"parent_visible":true,"spoiler_text":{"text/plain":""},"thread_muted":false},"poll":null,"reblog":null,"reblogged":false,"reblogs_count":0,"replies_count":0,"sensitive":false,"spoiler_text":"","tags":[],"text":null,"uri":"https://cdrom.tokyo/objects/8c1f9c70-29a7-4538-a999-649f5de02d2b","url":"https://cdrom.tokyo/objects/8c1f9c70-29a7-4538-a999-649f5de02d2b","visibility":"public"},"type":"mention"},{"account":{"acct":"Mitsu@shitposter.club","avatar":"https://stereophonic.space/proxy/nbixOd_jb_p8mZMKawPwrvkZzcY/aHR0cHM6Ly9zaGl0cG9zdGVyLmNsdWIvbWVkaWEvMmI1N2Y5ODc1MWE2NjVhNGVhOGI3NzlkMWVlNTEzOWY5NDQwZWQ3NzcwMjY4Nzg0ZjY4MmRhNjA4Mzc3MmJmZC5wbmc_bmFtZT1OWE5FSTRRTDZYSjgucG5n/2b57f98751a665a4ea8b779d1ee5139f9440ed7770268784f682da6083772bfd.png","avatar_static":"https://stereophonic.space/proxy/nbixOd_jb_p8mZMKawPwrvkZzcY/aHR0cHM6Ly9zaGl0cG9zdGVyLmNsdWIvbWVkaWEvMmI1N2Y5ODc1MWE2NjVhNGVhOGI3NzlkMWVlNTEzOWY5NDQwZWQ3NzcwMjY4Nzg0ZjY4MmRhNjA4Mzc3MmJmZC5wbmc_bmFtZT1OWE5FSTRRTDZYSjgucG5n/2b57f98751a665a4ea8b779d1ee5139f9440ed7770268784f682da6083772bfd.png","bot":false,"created_at":"2019-09-07T22:53:17.000Z","display_name":"Mitsu","emojis":[],"fields":[],"followers_count":346,"following_count":187,"header":"https://stereophonic.space/proxy/QPTIvD_T53_WPuCHyrA2AVL6uvo/aHR0cHM6Ly9zaGl0cG9zdGVyLmNsdWIvbWVkaWEvZDVhZmFkNWFjNzMxMzUyYTdiMjdhZTM0MzhhNjcwZjBhMDJjZjIwOTcwNDE4YzJkMjJiMTgyNjY0Nzg2YmRmNi5naWY_bmFtZT10dW1ibHJfaW5saW5lX3BpNnVwaWNjbGUxc3I5a3JuXzU0MC5naWY/d5afad5ac731352a7b27ae3438a670f0a02cf20970418c2d22b182664786bdf6.gif","header_static":"https://stereophonic.space/proxy/QPTIvD_T53_WPuCHyrA2AVL6uvo/aHR0cHM6Ly9zaGl0cG9zdGVyLmNsdWIvbWVkaWEvZDVhZmFkNWFjNzMxMzUyYTdiMjdhZTM0MzhhNjcwZjBhMDJjZjIwOTcwNDE4YzJkMjJiMTgyNjY0Nzg2YmRmNi5naWY_bmFtZT10dW1ibHJfaW5saW5lX3BpNnVwaWNjbGUxc3I5a3JuXzU0MC5naWY/d5afad5ac731352a7b27ae3438a670f0a02cf20970418c2d22b182664786bdf6.gif","id":"9mh4E0Ch5KoiDZBSQC","locked":false,"note":"ðŸ‘©ðŸ»â€ðŸ¦°â¤ï¸ðŸ¶ðŸ±ðŸ°<br/><br/>Bf: <span class=\"h-card\"><a data-user=\"9kwuqJiifRDOsgQ5ku\" class=\"u-url mention\" href=\"https://pleroma.guizzyordi.info/users/guizzy\">@<span>guizzy@pleroma.guizzyordi.info</span></a></span>","pleroma":{"accepts_chat_messages":true,"ap_id":"https://shitposter.club/users/Mitsu","background_image":null,"confirmation_pending":false,"deactivated":false,"favicon":null,"hide_favorites":true,"hide_followers":false,"hide_followers_count":false,"hide_follows":false,"hide_follows_count":false,"is_admin":false,"is_moderator":false,"relationship":{},"skip_thread_containment":false,"tags":[]},"source":{"fields":[],"note":"","pleroma":{"actor_type":"Person","discoverable":false},"sensitive":false},"statuses_count":37484,"url":"https://shitposter.club/users/Mitsu","username":"Mitsu"},"created_at":"2021-01-15T22:02:28.000Z","id":"326516","pleroma":{"is_muted":false,"is_seen":true},"status":{"account":{"acct":"Mitsu@shitposter.club","avatar":"https://stereophonic.space/proxy/nbixOd_jb_p8mZMKawPwrvkZzcY/aHR0cHM6Ly9zaGl0cG9zdGVyLmNsdWIvbWVkaWEvMmI1N2Y5ODc1MWE2NjVhNGVhOGI3NzlkMWVlNTEzOWY5NDQwZWQ3NzcwMjY4Nzg0ZjY4MmRhNjA4Mzc3MmJmZC5wbmc_bmFtZT1OWE5FSTRRTDZYSjgucG5n/2b57f98751a665a4ea8b779d1ee5139f9440ed7770268784f682da6083772bfd.png","avatar_static":"https://stereophonic.space/proxy/nbixOd_jb_p8mZMKawPwrvkZzcY/aHR0cHM6Ly9zaGl0cG9zdGVyLmNsdWIvbWVkaWEvMmI1N2Y5ODc1MWE2NjVhNGVhOGI3NzlkMWVlNTEzOWY5NDQwZWQ3NzcwMjY4Nzg0ZjY4MmRhNjA4Mzc3MmJmZC5wbmc_bmFtZT1OWE5FSTRRTDZYSjgucG5n/2b57f98751a665a4ea8b779d1ee5139f9440ed7770268784f682da6083772bfd.png","bot":false,"created_at":"2019-09-07T22:53:17.000Z","display_name":"Mitsu","emojis":[],"fields":[],"followers_count":346,"following_count":187,"header":"https://stereophonic.space/proxy/QPTIvD_T53_WPuCHyrA2AVL6uvo/aHR0cHM6Ly9zaGl0cG9zdGVyLmNsdWIvbWVkaWEvZDVhZmFkNWFjNzMxMzUyYTdiMjdhZTM0MzhhNjcwZjBhMDJjZjIwOTcwNDE4YzJkMjJiMTgyNjY0Nzg2YmRmNi5naWY_bmFtZT10dW1ibHJfaW5saW5lX3BpNnVwaWNjbGUxc3I5a3JuXzU0MC5naWY/d5afad5ac731352a7b27ae3438a670f0a02cf20970418c2d22b182664786bdf6.gif","header_static":"https://stereophonic.space/proxy/QPTIvD_T53_WPuCHyrA2AVL6uvo/aHR0cHM6Ly9zaGl0cG9zdGVyLmNsdWIvbWVkaWEvZDVhZmFkNWFjNzMxMzUyYTdiMjdhZTM0MzhhNjcwZjBhMDJjZjIwOTcwNDE4YzJkMjJiMTgyNjY0Nzg2YmRmNi5naWY_bmFtZT10dW1ibHJfaW5saW5lX3BpNnVwaWNjbGUxc3I5a3JuXzU0MC5naWY/d5afad5ac731352a7b27ae3438a670f0a02cf20970418c2d22b182664786bdf6.gif","id":"9mh4E0Ch5KoiDZBSQC","locked":false,"note":"ðŸ‘©ðŸ»â€ðŸ¦°â¤ï¸ðŸ¶ðŸ±ðŸ°<br/><br/>Bf: <span class=\"h-card\"><a data-user=\"9kwuqJiifRDOsgQ5ku\" class=\"u-url mention\" href=\"https://pleroma.guizzyordi.info/users/guizzy\">@<span>guizzy@pleroma.guizzyordi.info</span></a></span>","pleroma":{"accepts_chat_messages":true,"ap_id":"https://shitposter.club/users/Mitsu","background_image":null,"confirmation_pending":false,"deactivated":false,"favicon":null,"hide_favorites":true,"hide_followers":false,"hide_followers_count":false,"hide_follows":false,"hide_follows_count":false,"is_admin":false,"is_moderator":false,"relationship":{},"skip_thread_containment":false,"tags":[]},"source":{"fields":[],"note":"","pleroma":{"actor_type":"Person","discoverable":false},"sensitive":false},"statuses_count":37484,"url":"https://shitposter.club/users/Mitsu","username":"Mitsu"},"application":{"name":"Web","website":null},"bookmarked":false,"card":null,"content":"<span class=\"h-card\"><a class=\"u-url mention\" data-user=\"9rZ38To3IPHp89NigC\" href=\"https://stereophonic.space/users/newt\">@<span>newt</span></a></span> No","created_at":"2021-01-15T22:02:27.000Z","emojis":[],"favourited":false,"favourites_count":0,"id":"A3H6Xba5Lf1umtJpFw","in_reply_to_account_id":"9rZ2STPb7FA7JnMRii","in_reply_to_id":"A3H6VFhTjIC2LXefVg","language":null,"media_attachments":[],"mentions":[{"acct":"newt","id":"9rZ2STPb7FA7JnMRii","url":"https://stereophonic.space/users/newt","username":"newt"}],"muted":false,"pinned":false,"pleroma":{"content":{"text/plain":"@newt No"},"conversation_id":20781223,"direct_conversation_id":null,"emoji_reactions":[],"expires_at":null,"in_reply_to_account_acct":"newt","local":false,"parent_visible":true,"spoiler_text":{"text/plain":""},"thread_muted":false},"poll":null,"reblog":null,"reblogged":false,"reblogs_count":0,"replies_count":0,"sensitive":false,"spoiler_text":"","tags":[],"text":null,"uri":"https://shitposter.club/objects/9973180c-c8b6-43c1-8864-0a21bbce15e0","url":"https://shitposter.club/objects/9973180c-c8b6-43c1-8864-0a21bbce15e0","visibility":"public"},"type":"mention"},{"account":{"acct":"emilis@cdrom.tokyo","avatar":"https://stereophonic.space/proxy/8V0mOwZFa_B-_CynqAMBTct_6gY/aHR0cHM6Ly9jZHJvbS50b2t5by9tZWRpYS9lODIxMzc0MWJjZWE5MmIzN2JhNWFmM2EzZmE5NjZjNTU2NzFkZDMxZTUyZjZiNWRmNzJmYTM0ZDk1YTI0NTdmLmpwZw/e8213741bcea92b37ba5af3a3fa966c55671dd31e52f6b5df72fa34d95a2457f.jpg","avatar_static":"https://stereophonic.space/proxy/8V0mOwZFa_B-_CynqAMBTct_6gY/aHR0cHM6Ly9jZHJvbS50b2t5by9tZWRpYS9lODIxMzc0MWJjZWE5MmIzN2JhNWFmM2EzZmE5NjZjNTU2NzFkZDMxZTUyZjZiNWRmNzJmYTM0ZDk1YTI0NTdmLmpwZw/e8213741bcea92b37ba5af3a3fa966c55671dd31e52f6b5df72fa34d95a2457f.jpg","bot":false,"created_at":"2020-10-09T20:14:01.000Z","display_name":"romaboo :jigglypuff:","emojis":[{"shortcode":"jigglypuff","static_url":"https://stereophonic.space/proxy/bnKBn39yPRzUVLRRsLrf-6g4u04/aHR0cHM6Ly9jZHJvbS50b2t5by9lbW9qaS9jZHJvbS9qaWdnbHlwdWZmLnBuZw/jigglypuff.png","url":"https://stereophonic.space/proxy/bnKBn39yPRzUVLRRsLrf-6g4u04/aHR0cHM6Ly9jZHJvbS50b2t5by9lbW9qaS9jZHJvbS9qaWdnbHlwdWZmLnBuZw/jigglypuff.png","visible_in_picker":false}],"fields":[],"followers_count":6,"following_count":12,"header":"https://stereophonic.space/proxy/oeQXvgFN5DnvG8xvOo-NU7BBbO0/aHR0cHM6Ly9jZHJvbS50b2t5by9tZWRpYS81NTE1MThhYzRlNGQ0YTJiZWI1M2ExNTgxOTIwYzJkNDNmYjUzMDA1ZWI2MTU4MjBiMDE2NGYxMDczMTRmMjk4LmpwZw/551518ac4e4d4a2beb53a1581920c2d43fb53005eb615820b0164f107314f298.jpg","header_static":"https://stereophonic.space/proxy/oeQXvgFN5DnvG8xvOo-NU7BBbO0/aHR0cHM6Ly9jZHJvbS50b2t5by9tZWRpYS81NTE1MThhYzRlNGQ0YTJiZWI1M2ExNTgxOTIwYzJkNDNmYjUzMDA1ZWI2MTU4MjBiMDE2NGYxMDczMTRmMjk4LmpwZw/551518ac4e4d4a2beb53a1581920c2d43fb53005eb615820b0164f107314f298.jpg","id":"9zzoVd0oJZMuqGNzLk","locked":false,"note":"lego is based on nipples<br/><br/>In lingua latina: <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"9vqY7exhRY86vqnH6m\" href=\"https://cdrom.tokyo/users/aemilivs\">@<span>aemilivs</span></a></span>","pleroma":{"accepts_chat_messages":true,"ap_id":"https://cdrom.tokyo/users/emilis","background_image":null,"confirmation_pending":false,"deactivated":false,"favicon":null,"hide_favorites":true,"hide_followers":false,"hide_followers_count":false,"hide_follows":false,"hide_follows_count":false,"is_admin":false,"is_moderator":false,"relationship":{},"skip_thread_containment":false,"tags":[]},"source":{"fields":[],"note":"","pleroma":{"actor_type":"Person","discoverable":true},"sensitive":false},"statuses_count":4721,"url":"https://cdrom.tokyo/users/emilis","username":"emilis"},"created_at":"2021-01-15T22:02:23.000Z","id":"326515","pleroma":{"is_muted":false,"is_seen":true},"status":{"account":{"acct":"emilis@cdrom.tokyo","avatar":"https://stereophonic.space/proxy/8V0mOwZFa_B-_CynqAMBTct_6gY/aHR0cHM6Ly9jZHJvbS50b2t5by9tZWRpYS9lODIxMzc0MWJjZWE5MmIzN2JhNWFmM2EzZmE5NjZjNTU2NzFkZDMxZTUyZjZiNWRmNzJmYTM0ZDk1YTI0NTdmLmpwZw/e8213741bcea92b37ba5af3a3fa966c55671dd31e52f6b5df72fa34d95a2457f.jpg","avatar_static":"https://stereophonic.space/proxy/8V0mOwZFa_B-_CynqAMBTct_6gY/aHR0cHM6Ly9jZHJvbS50b2t5by9tZWRpYS9lODIxMzc0MWJjZWE5MmIzN2JhNWFmM2EzZmE5NjZjNTU2NzFkZDMxZTUyZjZiNWRmNzJmYTM0ZDk1YTI0NTdmLmpwZw/e8213741bcea92b37ba5af3a3fa966c55671dd31e52f6b5df72fa34d95a2457f.jpg","bot":false,"created_at":"2020-10-09T20:14:01.000Z","display_name":"romaboo :jigglypuff:","emojis":[{"shortcode":"jigglypuff","static_url":"https://stereophonic.space/proxy/bnKBn39yPRzUVLRRsLrf-6g4u04/aHR0cHM6Ly9jZHJvbS50b2t5by9lbW9qaS9jZHJvbS9qaWdnbHlwdWZmLnBuZw/jigglypuff.png","url":"https://stereophonic.space/proxy/bnKBn39yPRzUVLRRsLrf-6g4u04/aHR0cHM6Ly9jZHJvbS50b2t5by9lbW9qaS9jZHJvbS9qaWdnbHlwdWZmLnBuZw/jigglypuff.png","visible_in_picker":false}],"fields":[],"followers_count":6,"following_count":12,"header":"https://stereophonic.space/proxy/oeQXvgFN5DnvG8xvOo-NU7BBbO0/aHR0cHM6Ly9jZHJvbS50b2t5by9tZWRpYS81NTE1MThhYzRlNGQ0YTJiZWI1M2ExNTgxOTIwYzJkNDNmYjUzMDA1ZWI2MTU4MjBiMDE2NGYxMDczMTRmMjk4LmpwZw/551518ac4e4d4a2beb53a1581920c2d43fb53005eb615820b0164f107314f298.jpg","header_static":"https://stereophonic.space/proxy/oeQXvgFN5DnvG8xvOo-NU7BBbO0/aHR0cHM6Ly9jZHJvbS50b2t5by9tZWRpYS81NTE1MThhYzRlNGQ0YTJiZWI1M2ExNTgxOTIwYzJkNDNmYjUzMDA1ZWI2MTU4MjBiMDE2NGYxMDczMTRmMjk4LmpwZw/551518ac4e4d4a2beb53a1581920c2d43fb53005eb615820b0164f107314f298.jpg","id":"9zzoVd0oJZMuqGNzLk","locked":false,"note":"lego is based on nipples<br/><br/>In lingua latina: <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"9vqY7exhRY86vqnH6m\" href=\"https://cdrom.tokyo/users/aemilivs\">@<span>aemilivs</span></a></span>","pleroma":{"accepts_chat_messages":true,"ap_id":"https://cdrom.tokyo/users/emilis","background_image":null,"confirmation_pending":false,"deactivated":false,"favicon":null,"hide_favorites":true,"hide_followers":false,"hide_followers_count":false,"hide_follows":false,"hide_follows_count":false,"is_admin":false,"is_moderator":false,"relationship":{},"skip_thread_containment":false,"tags":[]},"source":{"fields":[],"note":"","pleroma":{"actor_type":"Person","discoverable":true},"sensitive":false},"statuses_count":4721,"url":"https://cdrom.tokyo/users/emilis","username":"emilis"},"application":{"name":"Web","website":null},"bookmarked":false,"card":null,"content":"<p><span class=\"h-card\"><a class=\"u-url mention\" data-user=\"9vLK6FwkZYqQAO4wIS\" href=\"https://stereophonic.space/users/newt\">@<span>newt</span></a></span> canâ€™t, itâ€™s all closed til march here</p>","created_at":"2021-01-15T22:02:22.000Z","emojis":[],"favourited":false,"favourites_count":1,"id":"A3H6X8mUQSilSxtp44","in_reply_to_account_id":"9rZ2STPb7FA7JnMRii","in_reply_to_id":"A3H6VFhTjIC2LXefVg","language":null,"media_attachments":[],"mentions":[{"acct":"newt","id":"9rZ2STPb7FA7JnMRii","url":"https://stereophonic.space/users/newt","username":"newt"}],"muted":false,"pinned":false,"pleroma":{"content":{"text/plain":"@newt canâ€™t, itâ€™s all closed til march here"},"conversation_id":20781223,"direct_conversation_id":null,"emoji_reactions":[],"expires_at":null,"in_reply_to_account_acct":"newt","local":false,"parent_visible":true,"spoiler_text":{"text/plain":""},"thread_muted":false},"poll":null,"reblog":null,"reblogged":false,"reblogs_count":0,"replies_count":1,"sensitive":false,"spoiler_text":"","tags":[],"text":null,"uri":"https://cdrom.tokyo/objects/ea900ed9-5364-4caf-8dbe-97e04c5dae63","url":"https://cdrom.tokyo/objects/ea900ed9-5364-4caf-8dbe-97e04c5dae63","visibility":"public"},"type":"mention"}]
 /* eslint-enable */
 
 const fetchTimeline = ({
@@ -866,7 +868,11 @@ const fetchTimeline = ({
     .then((data) => {
       if (!data.errors) {
         if (isNotifications) {
-          return { data: [parseNotification(report)], pagination }
+          // return { data: [parseNotification(report)], pagination }
+          console.log(notifs2.map(n => ({ notif: n, status: n.status })))
+          const parsedNotifs = notifs2.map(parseNotification)
+          console.log(parsedNotifs)
+          return { data: parsedNotifs, pagination }
         }
 
         return { data: data.map(isNotifications ? parseNotification : parseStatus), pagination }
-- 
cgit v1.2.3-70-g09d2


From 9e8513b3129b4e7ae22906522418e04aa3db5235 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Sun, 25 Apr 2021 13:25:42 +0300
Subject: i18n fixes

---
 src/components/notification/notification.vue             |  4 ++--
 src/components/poll/poll.vue                             |  4 ++--
 src/components/post_status_form/post_status_form.vue     |  6 +++---
 src/components/settings_modal/tabs/theme_tab/preview.vue | 10 +++++-----
 4 files changed, 12 insertions(+), 12 deletions(-)

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

diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue
index 0081dee4..cafa1e79 100644
--- a/src/components/notification/notification.vue
+++ b/src/components/notification/notification.vue
@@ -101,9 +101,9 @@
             </span>
             <span v-if="notification.type === 'pleroma:emoji_reaction'">
               <small>
-                <i18n path="notifications.reacted_with">
+                <i18n-t keypath="notifications.reacted_with">
                   <span class="emoji-reaction-emoji">{{ notification.emoji }}</span>
-                </i18n>
+                </i18n-t>
               </small>
             </span>
           </div>
diff --git a/src/components/poll/poll.vue b/src/components/poll/poll.vue
index 187d1829..2215d675 100644
--- a/src/components/poll/poll.vue
+++ b/src/components/poll/poll.vue
@@ -65,13 +65,13 @@
           {{ $tc("polls.votes_count", poll.votes_count, { count: poll.votes_count }) }}&nbsp;·&nbsp;
         </template>
       </div>
-      <i18n :path="expired ? 'polls.expired' : 'polls.expires_in'">
+      <i18n-t :keypath="expired ? 'polls.expired' : 'polls.expires_in'">
         <Timeago
           :time="expiresAt"
           :auto-update="60"
           :now-threshold="0"
         />
-      </i18n>
+      </i18n-t>
     </div>
   </div>
 </template>
diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue
index 6b490aee..c0a85727 100644
--- a/src/components/post_status_form/post_status_form.vue
+++ b/src/components/post_status_form/post_status_form.vue
@@ -18,9 +18,9 @@
         <FAIcon :icon="uploadFileLimitReached ? 'ban' : 'upload'" />
       </div>
       <div class="form-group">
-        <i18n
+        <i18n-t
           v-if="!$store.state.users.currentUser.locked && newStatus.visibility == 'private' && !disableLockWarning"
-          path="post_status.account_not_locked_warning"
+          keypath="post_status.account_not_locked_warning"
           tag="p"
           class="visibility-notice"
         >
@@ -30,7 +30,7 @@
           >
             {{ $t('post_status.account_not_locked_warning_link') }}
           </button>
-        </i18n>
+        </i18n-t>
         <p
           v-if="!hideScopeNotice && newStatus.visibility === 'public'"
           class="visibility-notice notice-dismissible"
diff --git a/src/components/settings_modal/tabs/theme_tab/preview.vue b/src/components/settings_modal/tabs/theme_tab/preview.vue
index 7ac7b9d3..36613d20 100644
--- a/src/components/settings_modal/tabs/theme_tab/preview.vue
+++ b/src/components/settings_modal/tabs/theme_tab/preview.vue
@@ -29,14 +29,14 @@
               {{ $t('settings.style.preview.content') }}
             </h4>
 
-            <i18n path="settings.style.preview.text">
+            <i18n-t keypath="settings.style.preview.text">
               <code style="font-family: var(--postCodeFont)">
                 {{ $t('settings.style.preview.mono') }}
               </code>
               <a style="color: var(--link)">
                 {{ $t('settings.style.preview.link') }}
               </a>
-            </i18n>
+            </i18n-t>
 
             <div class="icons">
               <FAIcon
@@ -72,15 +72,15 @@
             :^)
           </div>
           <div class="content">
-            <i18n
-              path="settings.style.preview.fine_print"
+            <i18n-t
+              keypath="settings.style.preview.fine_print"
               tag="span"
               class="faint"
             >
               <a style="color: var(--faintLink)">
                 {{ $t('settings.style.preview.faint_link') }}
               </a>
-            </i18n>
+            </i18n-t>
           </div>
         </div>
         <div class="separator" />
-- 
cgit v1.2.3-70-g09d2


From b87a9d6675cf7cd8d37d45e62013fab27cbc46e6 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Tue, 8 Jun 2021 16:14:01 +0300
Subject: Rearranged settings, moved more stuff to filtering where apllicable.
 Changed how filering works.

---
 src/components/notification/notification.scss      |   6 +
 src/components/notification/notification.vue       |   1 +
 src/components/notifications/notifications.scss    |   5 -
 .../settings_modal/tabs/filtering_tab.vue          | 195 ++++++++++++++-------
 src/components/settings_modal/tabs/general_tab.vue | 154 ++++++----------
 src/components/status/status.js                    |  44 +++--
 src/components/timeline/timeline_quick_settings.js |   3 +-
 src/i18n/en.json                                   |  14 +-
 src/modules/config.js                              |   2 +
 src/modules/instance.js                            |   3 +
 10 files changed, 242 insertions(+), 185 deletions(-)

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

diff --git a/src/components/notification/notification.scss b/src/components/notification/notification.scss
index f5905560..e075747b 100644
--- a/src/components/notification/notification.scss
+++ b/src/components/notification/notification.scss
@@ -2,6 +2,12 @@
 
 // TODO Copypaste from Status, should unify it somehow
 .Notification {
+  border-bottom: 1px solid;
+  border-color: $fallback--border;
+  border-color: var(--border, $fallback--border);
+  word-wrap: break-word;
+  word-break: break-word;
+
   &.-muted {
     padding: 0.25em 0.6em;
     height: 1.2em;
diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue
index 0081dee4..fb324cec 100644
--- a/src/components/notification/notification.vue
+++ b/src/components/notification/notification.vue
@@ -1,6 +1,7 @@
 <template>
   <Status
     v-if="notification.type === 'mention'"
+    class="Notification"
     :compact="true"
     :statusoid="notification.status"
   />
diff --git a/src/components/notifications/notifications.scss b/src/components/notifications/notifications.scss
index 2bb627a8..b513d8b5 100644
--- a/src/components/notifications/notifications.scss
+++ b/src/components/notifications/notifications.scss
@@ -37,11 +37,6 @@
 
 .notification {
   box-sizing: border-box;
-  border-bottom: 1px solid;
-  border-color: $fallback--border;
-  border-color: var(--border, $fallback--border);
-  word-wrap: break-word;
-  word-break: break-word;
 
   &:hover .animated.Avatar {
     canvas {
diff --git a/src/components/settings_modal/tabs/filtering_tab.vue b/src/components/settings_modal/tabs/filtering_tab.vue
index 6fc9ceaa..5d3c614a 100644
--- a/src/components/settings_modal/tabs/filtering_tab.vue
+++ b/src/components/settings_modal/tabs/filtering_tab.vue
@@ -1,73 +1,138 @@
 <template>
   <div :label="$t('settings.filtering')">
     <div class="setting-item">
-      <div class="select-multiple">
-        <span class="label">{{ $t('settings.notification_visibility') }}</span>
-        <ul class="option-list">
-          <li>
-            <BooleanSetting path="notificationVisibility.likes">
-              {{ $t('settings.notification_visibility_likes') }}
-            </BooleanSetting>
-          </li>
-          <li>
-            <BooleanSetting path="notificationVisibility.repeats">
-              {{ $t('settings.notification_visibility_repeats') }}
-            </BooleanSetting>
-          </li>
-          <li>
-            <BooleanSetting path="notificationVisibility.follows">
-              {{ $t('settings.notification_visibility_follows') }}
-            </BooleanSetting>
-          </li>
-          <li>
-            <BooleanSetting path="notificationVisibility.mentions">
-              {{ $t('settings.notification_visibility_mentions') }}
-            </BooleanSetting>
-          </li>
-          <li>
-            <BooleanSetting path="notificationVisibility.moves">
-              {{ $t('settings.notification_visibility_moves') }}
-            </BooleanSetting>
-          </li>
-          <li>
-            <BooleanSetting path="notificationVisibility.emojiReactions">
-              {{ $t('settings.notification_visibility_emoji_reactions') }}
-            </BooleanSetting>
-          </li>
-        </ul>
-      </div>
-      <ChoiceSetting
-        id="replyVisibility"
-        path="replyVisibility"
-        :options="replyVisibilityOptions"
-      >
-        {{ $t('settings.replies_in_timeline') }}
-      </ChoiceSetting>
-      <div>
-        <BooleanSetting path="hidePostStats">
-          {{ $t('settings.hide_post_stats') }}
-        </BooleanSetting>
-      </div>
-      <div>
-        <BooleanSetting path="hideUserStats">
-          {{ $t('settings.hide_user_stats') }}
-        </BooleanSetting>
-      </div>
+      <h2>{{ $t('settings.posts') }}</h2>
+      <ul class="setting-list">
+        <li>
+          <BooleanSetting path="hideFilteredStatuses">
+            {{ $t('settings.hide_filtered_statuses') }}
+          </BooleanSetting>
+          <ul
+            class="setting-list suboptions"
+            :class="[{disabled: !streaming}]"
+          >
+            <li>
+              <BooleanSetting
+                :disabled="hideFilteredStatuses"
+                path="hideWordFilteredPosts"
+              >
+                {{ $t('settings.hide_wordfiltered_statuses') }}
+              </BooleanSetting>
+            </li>
+            <li>
+              <BooleanSetting
+                :disabled="hideFilteredStatuses"
+                path="hideMutedThreads"
+              >
+                {{ $t('settings.hide_muted_threads') }}
+              </BooleanSetting>
+            </li>
+            <li>
+              <BooleanSetting
+                :disabled="hideFilteredStatuses"
+                path="hideMutedPosts"
+                >
+                {{ $t('settings.hide_muted_posts') }}
+              </BooleanSetting>
+            </li>
+          </ul>
+        </li>
+        <li>
+          <BooleanSetting path="hidePostStats">
+            {{ $t('settings.hide_post_stats') }}
+          </BooleanSetting>
+        </li>
+        <ChoiceSetting
+          id="replyVisibility"
+          path="replyVisibility"
+          :options="replyVisibilityOptions"
+        >
+          {{ $t('settings.replies_in_timeline') }}
+        </ChoiceSetting>
+        <li>
+          <h3>{{ $t('settings.wordfilter') }}</h3>
+          <textarea
+            id="muteWords"
+            v-model="muteWordsString"
+            class="resize-height"
+          />
+          <div>{{ $t('settings.filtering_explanation') }}</div>
+        </li>
+        <h3>{{ $t('settings.attachments') }}</h3>
+        <li>
+          <label for="maxThumbnails">
+            {{ $t('settings.max_thumbnails') }}
+          </label>
+          <input
+            id="maxThumbnails"
+            path.number="maxThumbnails"
+            class="number-input"
+            type="number"
+            min="0"
+            step="1"
+          >
+        </li>
+        <li>
+          <BooleanSetting path="hideAttachments">
+            {{ $t('settings.hide_attachments_in_tl') }}
+          </BooleanSetting>
+        </li>
+        <li>
+          <BooleanSetting path="hideAttachmentsInConv">
+            {{ $t('settings.hide_attachments_in_convo') }}
+          </BooleanSetting>
+        </li>
+      </ul>
     </div>
     <div class="setting-item">
-      <div>
-        <p>{{ $t('settings.filtering_explanation') }}</p>
-        <textarea
-          id="muteWords"
-          v-model="muteWordsString"
-          class="resize-height"
-        />
-      </div>
-      <div>
-        <BooleanSetting path="hideFilteredStatuses">
-          {{ $t('settings.hide_filtered_statuses') }}
-        </BooleanSetting>
-      </div>
+      <h2>{{ $t('settings.user_profiles') }}</h2>
+      <ul class="setting-list">
+        <li>
+          <BooleanSetting path="hideUserStats">
+            {{ $t('settings.hide_user_stats') }}
+          </BooleanSetting>
+        </li>
+      </ul>
+    </div>
+    <div class="setting-item">
+      <h2>{{ $t('settings.notifications') }}</h2>
+      <ul class="setting-list">
+        <li class="select-multiple">
+          <span class="label">{{ $t('settings.notification_visibility') }}</span>
+          <ul class="option-list">
+            <li>
+              <BooleanSetting path="notificationVisibility.likes">
+                {{ $t('settings.notification_visibility_likes') }}
+              </BooleanSetting>
+            </li>
+            <li>
+              <BooleanSetting path="notificationVisibility.repeats">
+                {{ $t('settings.notification_visibility_repeats') }}
+              </BooleanSetting>
+            </li>
+            <li>
+              <BooleanSetting path="notificationVisibility.follows">
+                {{ $t('settings.notification_visibility_follows') }}
+              </BooleanSetting>
+            </li>
+            <li>
+              <BooleanSetting path="notificationVisibility.mentions">
+                {{ $t('settings.notification_visibility_mentions') }}
+              </BooleanSetting>
+            </li>
+            <li>
+              <BooleanSetting path="notificationVisibility.moves">
+                {{ $t('settings.notification_visibility_moves') }}
+              </BooleanSetting>
+            </li>
+            <li>
+              <BooleanSetting path="notificationVisibility.emojiReactions">
+                {{ $t('settings.notification_visibility_emoji_reactions') }}
+              </BooleanSetting>
+            </li>
+          </ul>
+        </li>
+      </ul>
     </div>
   </div>
 </template>
diff --git a/src/components/settings_modal/tabs/general_tab.vue b/src/components/settings_modal/tabs/general_tab.vue
index bdb29edf..5243d336 100644
--- a/src/components/settings_modal/tabs/general_tab.vue
+++ b/src/components/settings_modal/tabs/general_tab.vue
@@ -21,19 +21,9 @@
             {{ $t('settings.hide_wallpaper') }}
           </BooleanSetting>
         </li>
-      </ul>
-    </div>
-    <div class="setting-item">
-      <h2>{{ $t('nav.timeline') }}</h2>
-      <ul class="setting-list">
         <li>
-          <BooleanSetting path="hideMutedPosts">
-            {{ $t('settings.hide_muted_posts') }}
-          </BooleanSetting>
-        </li>
-        <li>
-          <BooleanSetting path="collapseMessageWithSubject">
-            {{ $t('settings.collapse_subject') }}
+          <BooleanSetting path="stopGifs">
+            {{ $t('settings.stop_gifs') }}
           </BooleanSetting>
         </li>
         <li>
@@ -63,98 +53,36 @@
             </small>
           </BooleanSetting>
         </li>
-        <li>
-          <BooleanSetting path="emojiReactionsOnTimeline">
-            {{ $t('settings.emoji_reactions_on_timeline') }}
-          </BooleanSetting>
-        </li>
         <li>
           <BooleanSetting path="virtualScrolling">
             {{ $t('settings.virtual_scrolling') }}
           </BooleanSetting>
         </li>
-      </ul>
-    </div>
-
-    <div class="setting-item">
-      <h2>{{ $t('settings.composing') }}</h2>
-      <ul class="setting-list">
-        <li>
-          <BooleanSetting path="scopeCopy">
-            {{ $t('settings.scope_copy') }}
-          </BooleanSetting>
-        </li>
-        <li>
-          <BooleanSetting path="alwaysShowSubjectInput">
-            {{ $t('settings.subject_input_always_show') }}
-          </BooleanSetting>
-        </li>
-        <li>
-          <ChoiceSetting
-            id="subjectLineBehavior"
-            path="subjectLineBehavior"
-            :options="subjectLineOptions"
-          >
-            {{ $t('settings.subject_line_behavior') }}
-          </ChoiceSetting>
-        </li>
-        <li v-if="postFormats.length > 0">
-          <ChoiceSetting
-            id="postContentType"
-            path="postContentType"
-            :options="postContentOptions"
-          >
-            {{ $t('settings.post_status_content_type') }}
-          </ChoiceSetting>
-        </li>
-        <li>
-          <BooleanSetting path="minimalScopesMode">
-            {{ $t('settings.minimal_scopes_mode') }}
-          </BooleanSetting>
-        </li>
-        <li>
-          <BooleanSetting path="sensitiveByDefault">
-            {{ $t('settings.sensitive_by_default') }}
-          </BooleanSetting>
-        </li>
         <li>
           <BooleanSetting path="autohideFloatingPostButton">
             {{ $t('settings.autohide_floating_post_button') }}
           </BooleanSetting>
         </li>
-        <li>
-          <BooleanSetting path="padEmoji">
-            {{ $t('settings.pad_emoji') }}
-          </BooleanSetting>
-        </li>
       </ul>
     </div>
-
     <div class="setting-item">
-      <h2>{{ $t('settings.attachments') }}</h2>
+      <h2>{{ $t('settings.post_look_feel') }}</h2>
       <ul class="setting-list">
         <li>
-          <BooleanSetting path="hideAttachments">
-            {{ $t('settings.hide_attachments_in_tl') }}
+          <BooleanSetting path="collapseMessageWithSubject">
+            {{ $t('settings.collapse_subject') }}
           </BooleanSetting>
         </li>
         <li>
-          <BooleanSetting path="hideAttachmentsInConv">
-            {{ $t('settings.hide_attachments_in_convo') }}
+          <BooleanSetting path="emojiReactionsOnTimeline">
+            {{ $t('settings.emoji_reactions_on_timeline') }}
           </BooleanSetting>
         </li>
+        <h3>{{ $t('settings.attachments') }}</h3>
         <li>
-          <label for="maxThumbnails">
-            {{ $t('settings.max_thumbnails') }}
-          </label>
-          <input
-            id="maxThumbnails"
-            path.number="maxThumbnails"
-            class="number-input"
-            type="number"
-            min="0"
-            step="1"
-          >
+          <BooleanSetting path="useContainFit">
+            {{ $t('settings.use_contain_fit') }}
+          </BooleanSetting>
         </li>
         <li>
           <BooleanSetting path="hideNsfw">
@@ -179,11 +107,6 @@
             </BooleanSetting>
           </li>
         </ul>
-        <li>
-          <BooleanSetting path="stopGifs">
-            {{ $t('settings.stop_gifs') }}
-          </BooleanSetting>
-        </li>
         <li>
           <BooleanSetting path="loopVideo">
             {{ $t('settings.loop_video') }}
@@ -213,31 +136,70 @@
             {{ $t('settings.play_videos_in_modal') }}
           </BooleanSetting>
         </li>
+        <h3>{{ $t('settings.fun') }}</h3>
         <li>
-          <BooleanSetting path="useContainFit">
-            {{ $t('settings.use_contain_fit') }}
+          <BooleanSetting path="greentext">
+            {{ $t('settings.greentext') }}
           </BooleanSetting>
         </li>
       </ul>
     </div>
 
     <div class="setting-item">
-      <h2>{{ $t('settings.notifications') }}</h2>
+      <h2>{{ $t('settings.composing') }}</h2>
       <ul class="setting-list">
         <li>
-          <BooleanSetting path="webPushNotifications">
-            {{ $t('settings.enable_web_push_notifications') }}
+          <BooleanSetting path="scopeCopy">
+            {{ $t('settings.scope_copy') }}
+          </BooleanSetting>
+        </li>
+        <li>
+          <BooleanSetting path="alwaysShowSubjectInput">
+            {{ $t('settings.subject_input_always_show') }}
+          </BooleanSetting>
+        </li>
+        <li>
+          <ChoiceSetting
+            id="subjectLineBehavior"
+            path="subjectLineBehavior"
+            :options="subjectLineOptions"
+          >
+            {{ $t('settings.subject_line_behavior') }}
+          </ChoiceSetting>
+        </li>
+        <li v-if="postFormats.length > 0">
+          <ChoiceSetting
+            id="postContentType"
+            path="postContentType"
+            :options="postContentOptions"
+          >
+            {{ $t('settings.post_status_content_type') }}
+          </ChoiceSetting>
+        </li>
+        <li>
+          <BooleanSetting path="minimalScopesMode">
+            {{ $t('settings.minimal_scopes_mode') }}
+          </BooleanSetting>
+        </li>
+        <li>
+          <BooleanSetting path="sensitiveByDefault">
+            {{ $t('settings.sensitive_by_default') }}
+          </BooleanSetting>
+        </li>
+        <li>
+          <BooleanSetting path="padEmoji">
+            {{ $t('settings.pad_emoji') }}
           </BooleanSetting>
         </li>
       </ul>
     </div>
 
     <div class="setting-item">
-      <h2>{{ $t('settings.fun') }}</h2>
+      <h2>{{ $t('settings.notifications') }}</h2>
       <ul class="setting-list">
         <li>
-          <BooleanSetting path="greentext">
-            {{ $t('settings.greentext') }}
+          <BooleanSetting path="webPushNotifications">
+            {{ $t('settings.enable_web_push_notifications') }}
           </BooleanSetting>
         </li>
       </ul>
diff --git a/src/components/status/status.js b/src/components/status/status.js
index 470c01f1..5c7caa28 100644
--- a/src/components/status/status.js
+++ b/src/components/status/status.js
@@ -157,26 +157,32 @@ const Status = {
       return muteWordHits(this.status, this.muteWords)
     },
     muted () {
+      if (this.statusoid.user.id === this.currentUser.id) return false
+      const reasonsToMute = this.userIsMuted ||
+        // Thread is muted
+        status.thread_muted ||
+        // Wordfiltered
+        this.muteWordHits.length > 0
+      return !this.unmuted && !this.shouldNotMute && reasonsToMute
+    },
+    userIsMuted () {
       if (this.statusoid.user.id === this.currentUser.id) return false
       const { status } = this
       const { reblog } = status
       const relationship = this.$store.getters.relationship(status.user.id)
       const relationshipReblog = reblog && this.$store.getters.relationship(reblog.user.id)
-      const reasonsToMute = (
-        // Post is muted according to BE
-        status.muted ||
+      return status.muted ||
         // Reprööt of a muted post according to BE
         (reblog && reblog.muted) ||
         // Muted user
         relationship.muting ||
         // Muted user of a reprööt
-        (relationshipReblog && relationshipReblog.muting) ||
-        // Thread is muted
-        status.thread_muted ||
-        // Wordfiltered
-        this.muteWordHits.length > 0
-      )
-      const excusesNotToMute = (
+        (relationshipReblog && relationshipReblog.muting)
+    },
+    shouldNotMute () {
+      const { status } = this
+      const { reblog } = status
+      return (
         (
           this.inProfile && (
             // Don't mute user's posts on user timeline (except reblogs)
@@ -189,14 +195,26 @@ const Status = {
         (this.inConversation && status.thread_muted)
         // No excuses if post has muted words
       ) && !this.muteWordHits.length > 0
-
-      return !this.unmuted && !excusesNotToMute && reasonsToMute
+    },
+    hideMutedUsers () {
+      return this.mergedConfig.hideMutedPosts
+    },
+    hideMutedThreads () {
+      return this.mergedConfig.hideMutedThreads
     },
     hideFilteredStatuses () {
       return this.mergedConfig.hideFilteredStatuses
     },
+    hideWordFilteredPosts () {
+      return this.mergedConfig.hideWordFilteredPosts
+    },
     hideStatus () {
-      return (this.muted && this.hideFilteredStatuses) || this.virtualHidden
+      return (this.virtualHidden || !this.shouldNotMute) && (
+        (this.muted && this.hideFilteredStatuses) ||
+        (this.userIsMuted && this.hideMutedUsers) ||
+        (this.status.thread_muted && this.hideMutedThreads) ||
+        (this.muteWordHits.length > 0 && this.hideWordFilteredPosts)
+      )
     },
     isFocused () {
       // retweet or root of an expanded conversation
diff --git a/src/components/timeline/timeline_quick_settings.js b/src/components/timeline/timeline_quick_settings.js
index eae65a55..7b4931ce 100644
--- a/src/components/timeline/timeline_quick_settings.js
+++ b/src/components/timeline/timeline_quick_settings.js
@@ -48,10 +48,9 @@ const TimelineQuickSettings = {
       }
     },
     hideMutedPosts: {
-      get () { return this.mergedConfig.hideMutedPosts || this.mergedConfig.hideFilteredStatuses },
+      get () { return this.mergedConfig.hideFilteredStatuses },
       set () {
         const value = !this.hideMutedPosts
-        this.$store.dispatch('setOption', { name: 'hideMutedPosts', value })
         this.$store.dispatch('setOption', { name: 'hideFilteredStatuses', value })
       }
     }
diff --git a/src/i18n/en.json b/src/i18n/en.json
index aa440ac1..89e808aa 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -259,6 +259,7 @@
     "security": "Security",
     "setting_changed": "Setting is different from default",
     "enter_current_password_to_confirm": "Enter your current password to confirm your identity",
+    "post_look_feel": "Posts Look & Feel",
     "mfa": {
       "otp": "OTP",
       "setup_otp": "Setup OTP",
@@ -331,6 +332,7 @@
     "emoji_reactions_on_timeline": "Show emoji reactions on timeline",
     "export_theme": "Save preset",
     "filtering": "Filtering",
+    "wordfilter": "Wordfilter",
     "filtering_explanation": "All statuses containing these words will be muted, one per line",
     "word_filter": "Word filter",
     "follow_export": "Follow export",
@@ -346,7 +348,7 @@
     "hide_media_previews": "Hide media previews",
     "hide_muted_posts": "Hide posts of muted users",
     "hide_all_muted_posts": "Hide muted posts",
-    "max_thumbnails": "Maximum amount of thumbnails per post",
+    "max_thumbnails": "Maximum amount of thumbnails per post (empty = no limit)",
     "hide_isp": "Hide instance-specific panel",
     "right_sidebar": "Show sidebar on the right side",
     "hide_wallpaper": "Hide instance wallpaper",
@@ -354,7 +356,9 @@
     "use_one_click_nsfw": "Open NSFW attachments with just one click",
     "hide_post_stats": "Hide post statistics (e.g. the number of favorites)",
     "hide_user_stats": "Hide user statistics (e.g. the number of followers)",
-    "hide_filtered_statuses": "Hide filtered statuses",
+    "hide_filtered_statuses": "Hide all filtered posts",
+    "hide_wordfiltered_statuses": "Hide word-filtered statuses",
+    "hide_muted_threads": "Hide muted threads",
     "import_blocks_from_a_csv_file": "Import blocks from a csv file",
     "import_followers_from_a_csv_file": "Import follows from a csv file",
     "import_theme": "Load preset",
@@ -395,6 +399,8 @@
     "name_bio": "Name & bio",
     "new_email": "New email",
     "new_password": "New password",
+    "posts": "Posts",
+    "user_profiles": "User Profiles",
     "notification_visibility": "Types of notifications to show",
     "notification_visibility_follows": "Follows",
     "notification_visibility_likes": "Favorites",
@@ -411,7 +417,7 @@
     "hide_followers_count_description": "Don't show follower count",
     "show_admin_badge": "Show \"Admin\" badge in my profile",
     "show_moderator_badge": "Show \"Moderator\" badge in my profile",
-    "nsfw_clickthrough": "Enable clickthrough attachment and link preview image hiding for NSFW statuses",
+    "nsfw_clickthrough": "Censor NSFW content",
     "oauth_tokens": "OAuth tokens",
     "token": "Token",
     "refresh_token": "Refresh token",
@@ -455,7 +461,7 @@
     "subject_line_noop": "Do not copy",
     "post_status_content_type": "Post status content type",
     "sensitive_by_default": "Mark posts as sensitive by default",
-    "stop_gifs": "Play-on-hover GIFs",
+    "stop_gifs": "Pause animated images until you hover on them",
     "streaming": "Enable automatic streaming of new posts when scrolled to the top",
     "user_mutes": "Users",
     "useStreamingApi": "Receive posts and notifications real-time",
diff --git a/src/modules/config.js b/src/modules/config.js
index 0f596750..df66bfe6 100644
--- a/src/modules/config.js
+++ b/src/modules/config.js
@@ -23,6 +23,8 @@ export const defaultState = {
   hideInstanceWallpaper: false,
   // bad name: actually hides posts of muted USERS
   hideMutedPosts: undefined, // instance default
+  hideMutedThreads: undefined, // instance default
+  hideWordFilteredPosts: undefined, // instance default
   collapseMessageWithSubject: undefined, // instance default
   padEmoji: true,
   hideAttachments: false,
diff --git a/src/modules/instance.js b/src/modules/instance.js
index 539b9c66..60038f08 100644
--- a/src/modules/instance.js
+++ b/src/modules/instance.js
@@ -21,7 +21,10 @@ const defaultState = {
   collapseMessageWithSubject: false,
   greentext: false,
   hideFilteredStatuses: false,
+  // bad name: actually hides posts of muted USERS
   hideMutedPosts: false,
+  hideMutedThreads: true,
+  hideWordFilteredPosts: false,
   hidePostStats: false,
   hideSitename: false,
   hideUserStats: false,
-- 
cgit v1.2.3-70-g09d2


From a3c703bd37fc55c2377cb0bf099af6a21ea07e8e Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Mon, 14 Jun 2021 02:52:41 +0300
Subject: compact notifs

---
 src/components/gallery/gallery.vue               |  5 ++-
 src/components/notification/notification.vue     |  3 +-
 src/components/status_body/status_body.js        |  1 +
 src/components/status_body/status_body.scss      | 56 ++++++++++++++++++++++++
 src/components/status_body/status_body.vue       |  7 ++-
 src/components/status_content/status_content.js  |  1 +
 src/components/status_content/status_content.vue | 13 +++++-
 7 files changed, 81 insertions(+), 5 deletions(-)

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

diff --git a/src/components/gallery/gallery.vue b/src/components/gallery/gallery.vue
index ca91c9c1..3e967e9c 100644
--- a/src/components/gallery/gallery.vue
+++ b/src/components/gallery/gallery.vue
@@ -36,7 +36,10 @@
   height: 0;
   width: 100%;
   flex-grow: 1;
-  margin-top: 0.5em;
+
+  &:not(:first-child) {
+    margin-top: 0.5em;
+  }
 
   .gallery-row-inner {
     position: absolute;
diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue
index 0081dee4..396ae0e1 100644
--- a/src/components/notification/notification.vue
+++ b/src/components/notification/notification.vue
@@ -181,8 +181,9 @@
           </router-link>
         </div>
         <template v-else>
-          <status-content
+          <StatusContent
             class="faint"
+            :compact="true"
             :status="notification.action"
           />
         </template>
diff --git a/src/components/status_body/status_body.js b/src/components/status_body/status_body.js
index 26491e1b..6dc028a6 100644
--- a/src/components/status_body/status_body.js
+++ b/src/components/status_body/status_body.js
@@ -23,6 +23,7 @@ library.add(
 const StatusContent = {
   name: 'StatusContent',
   props: [
+    'compact',
     'status',
     'focused',
     'noHeading',
diff --git a/src/components/status_body/status_body.scss b/src/components/status_body/status_body.scss
index 81a687f1..a93c92e0 100644
--- a/src/components/status_body/status_body.scss
+++ b/src/components/status_body/status_body.scss
@@ -1,11 +1,17 @@
 @import '../../_variables.scss';
 
 .StatusBody {
+  display: flex;
+  flex-direction: column;
 
   .emoji {
     --_still_image-label-scale: 0.5;
   }
 
+  .attachments {
+    margin-top: 0.5em;
+  }
+
   & .text,
   & .summary {
     font-family: var(--postFont, sans-serif);
@@ -115,4 +121,54 @@
   .cyantext {
     color: var(--postCyantext, $fallback--cBlue);
   }
+
+  &.-compact {
+    flex-direction: row;
+
+    --emoji-size: 16px;
+
+    & .body,
+    & .attachments {
+      max-height: 3.25em;
+    }
+
+    .body {
+      overflow: hidden;
+      white-space: normal;
+      min-width: 5em;
+      flex: 5 1 auto;
+      mask-size: auto 3.5em, auto auto;
+      mask-position: 0 0, 0 0;
+      mask-repeat: repeat-x, repeat;
+      mask-image:
+        linear-gradient(to top, white 0.5em, transparent 2.5em),
+        linear-gradient(to top, white, white);
+
+      /* Autoprefixed seem to ignore this one, and also syntax is different */
+      -webkit-mask-composite: xor;
+      mask-composite: exclude;
+    }
+
+    .attachments {
+      margin-top: 0;
+      flex: 1 1 auto;
+      min-width: 5em;
+      height: 100%;
+    }
+
+    .summary-wrapper {
+      .summary::after {
+        content: ': ';
+      }
+
+      line-height: inherit;
+      margin: 0;
+      border: none;
+      display: inline-block;
+    }
+
+    .text-wrapper {
+      display: inline-block;
+    }
+  }
 }
diff --git a/src/components/status_body/status_body.vue b/src/components/status_body/status_body.vue
index 3dc4916c..6609d989 100644
--- a/src/components/status_body/status_body.vue
+++ b/src/components/status_body/status_body.vue
@@ -1,5 +1,8 @@
 <template>
-  <div class="StatusBody">
+<div
+  class="StatusBody"
+  :class="{ '-compact': compact }"
+>
     <div class="body">
       <div
         v-if="status.summary_raw_html"
@@ -8,6 +11,7 @@
       >
         <RichContent
           class="media-body summary"
+          :single-line="compact"
           :html="status.summary_raw_html"
           :emoji="status.emojis"
         />
@@ -52,6 +56,7 @@
             :html="status.raw_html"
             :emoji="status.emojis"
             :handle-links="true"
+            :single-line="compact"
             :greentext="mergedConfig.greentext"
             @parseReady="setHeadTailLinks"
           />
diff --git a/src/components/status_content/status_content.js b/src/components/status_content/status_content.js
index 11a4974b..4d6f0a14 100644
--- a/src/components/status_content/status_content.js
+++ b/src/components/status_content/status_content.js
@@ -28,6 +28,7 @@ const StatusContent = {
   name: 'StatusContent',
   props: [
     'status',
+    'compact',
     'focused',
     'noHeading',
     'fullContent',
diff --git a/src/components/status_content/status_content.vue b/src/components/status_content/status_content.vue
index feb34d2c..06edd780 100644
--- a/src/components/status_content/status_content.vue
+++ b/src/components/status_content/status_content.vue
@@ -1,8 +1,12 @@
 <template>
-  <div class="StatusContent">
+<div
+  class="StatusContent"
+  :class="{ '-compact': compact }"
+>
     <slot name="header" />
     <StatusBody
       :status="status"
+      :compact="compact"
       :single-line="singleLine"
       :hide-mentions="hideMentions"
       @parseReady="setHeadTailLinks"
@@ -36,7 +40,7 @@
       </div>
 
       <div
-        v-if="status.card && !noHeading"
+        v-if="status.card && !noHeading && !compact"
         class="link-preview media-body"
       >
         <link-preview
@@ -59,5 +63,10 @@ $status-margin: 0.75em;
 .StatusContent {
   flex: 1;
   min-width: 0;
+  &.-compact {
+    flex {
+      display: flex;
+    }
+  }
 }
 </style>
-- 
cgit v1.2.3-70-g09d2


From b817e09ee8ed4e02a6757b2c4e5577c5f82bec45 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Tue, 22 Mar 2022 19:43:11 +0200
Subject: fix avatars not opening inline card

---
 src/components/notification/notification.vue | 2 +-
 src/components/status/status.vue             | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

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

diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue
index c03ebc89..2af4af22 100644
--- a/src/components/notification/notification.vue
+++ b/src/components/notification/notification.vue
@@ -33,7 +33,7 @@
     >
       <a
         class="avatar-container"
-        :href="notification.from_profile.statusnet_profile_url"
+        :href="$router.resolve(userProfileLink).href"
         @click.stop.prevent.capture="toggleUserExpanded"
       >
         <UserAvatar
diff --git a/src/components/status/status.vue b/src/components/status/status.vue
index eb30f28b..3f352f03 100644
--- a/src/components/status/status.vue
+++ b/src/components/status/status.vue
@@ -121,8 +121,8 @@
           v-if="!noHeading"
           class="left-side"
         >
-          <router-link
-            :to="userProfileLink"
+          <a
+            :href="$router.resolve(userProfileLink).href"
             @click.stop.prevent.capture="toggleUserExpanded"
           >
             <UserAvatar
@@ -132,7 +132,7 @@
               :better-shadow="betterShadow"
               :user="status.user"
             />
-          </router-link>
+          </a>
         </div>
         <div class="right-side">
           <UserCard
-- 
cgit v1.2.3-70-g09d2


From 08811e5a27548f18c1107170b892a4f614658dc5 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Wed, 23 Mar 2022 16:08:45 +0200
Subject: fix spacings in notifications

---
 src/components/notification/notification.vue | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

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

diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue
index 2af4af22..23157a51 100644
--- a/src/components/notification/notification.vue
+++ b/src/components/notification/notification.vue
@@ -65,12 +65,16 @@
               v-else
               class="username"
               :title="'@'+notification.from_profile.screen_name_ui"
-            >{{ notification.from_profile.name }}</span>
+            >
+              {{ notification.from_profile.name }}
+            </span>
+            {{ ' ' }}
             <span v-if="notification.type === 'like'">
               <FAIcon
                 class="type-icon"
                 icon="star"
               />
+              {{ ' ' }}
               <small>{{ $t('notifications.favorited_you') }}</small>
             </span>
             <span v-if="notification.type === 'repeat'">
@@ -79,6 +83,7 @@
                 icon="retweet"
                 :title="$t('tool_tip.repeat')"
               />
+              {{ ' ' }}
               <small>{{ $t('notifications.repeated_you') }}</small>
             </span>
             <span v-if="notification.type === 'follow'">
@@ -86,6 +91,7 @@
                 class="type-icon"
                 icon="user-plus"
               />
+              {{ ' ' }}
               <small>{{ $t('notifications.followed_you') }}</small>
             </span>
             <span v-if="notification.type === 'follow_request'">
@@ -93,6 +99,7 @@
                 class="type-icon"
                 icon="user"
               />
+              {{ ' ' }}
               <small>{{ $t('notifications.follow_request') }}</small>
             </span>
             <span v-if="notification.type === 'move'">
@@ -100,6 +107,7 @@
                 class="type-icon"
                 icon="suitcase-rolling"
               />
+              {{ ' ' }}
               <small>{{ $t('notifications.migrated_to') }}</small>
             </span>
             <span v-if="notification.type === 'pleroma:emoji_reaction'">
-- 
cgit v1.2.3-70-g09d2


From 650e69c33683b34e002f5fdc698ceb384baf059b Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Tue, 29 Mar 2022 00:02:02 +0300
Subject: fix misc warnings

---
 src/components/notification/notification.vue               | 2 +-
 src/components/poll/poll.vue                               | 2 +-
 src/components/settings_modal/helpers/integer_setting.js   | 2 +-
 src/components/settings_modal/tabs/theme_tab/theme_tab.vue | 6 +++---
 src/components/shadow_control/shadow_control.vue           | 2 +-
 src/components/thread_tree/thread_tree.vue                 | 4 ++--
 6 files changed, 9 insertions(+), 9 deletions(-)

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

diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue
index 23157a51..d77b2f57 100644
--- a/src/components/notification/notification.vue
+++ b/src/components/notification/notification.vue
@@ -112,7 +112,7 @@
             </span>
             <span v-if="notification.type === 'pleroma:emoji_reaction'">
               <small>
-                <i18n-t keypath="notifications.reacted_with">
+                <i18n-t scope="global" keypath="notifications.reacted_with">
                   <span class="emoji-reaction-emoji">{{ notification.emoji }}</span>
                 </i18n-t>
               </small>
diff --git a/src/components/poll/poll.vue b/src/components/poll/poll.vue
index e949c653..c3880096 100644
--- a/src/components/poll/poll.vue
+++ b/src/components/poll/poll.vue
@@ -71,7 +71,7 @@
           {{ $tc("polls.votes_count", poll.votes_count, { count: poll.votes_count }) }}&nbsp;·&nbsp;
         </template>
       </div>
-      <i18n-t :keypath="expired ? 'polls.expired' : 'polls.expires_in'">
+      <i18n-t scope="global" :keypath="expired ? 'polls.expired' : 'polls.expires_in'">
         <Timeago
           :time="expiresAt"
           :auto-update="60"
diff --git a/src/components/settings_modal/helpers/integer_setting.js b/src/components/settings_modal/helpers/integer_setting.js
index 4a19bd7c..17dc0e7b 100644
--- a/src/components/settings_modal/helpers/integer_setting.js
+++ b/src/components/settings_modal/helpers/integer_setting.js
@@ -8,7 +8,7 @@ export default {
     path: String,
     disabled: Boolean,
     min: Number,
-    expert: Number
+    expert: [Number, String]
   },
   computed: {
     pathDefault () {
diff --git a/src/components/settings_modal/tabs/theme_tab/theme_tab.vue b/src/components/settings_modal/tabs/theme_tab/theme_tab.vue
index cf049a70..dfa9a735 100644
--- a/src/components/settings_modal/tabs/theme_tab/theme_tab.vue
+++ b/src/components/settings_modal/tabs/theme_tab/theme_tab.vue
@@ -951,14 +951,14 @@
             :fallback="currentShadowFallback"
           />
           <div v-if="shadowSelected === 'avatar' || shadowSelected === 'avatarStatus'">
-            <i18n-t
+            <i18n-t scope="global"
               keypath="settings.style.shadows.filter_hint.always_drop_shadow"
               tag="p"
             >
               <code>filter: drop-shadow()</code>
             </i18n-t>
             <p>{{ $t('settings.style.shadows.filter_hint.avatar_inset') }}</p>
-            <i18n-t
+            <i18n-t scope="global"
               keypath="settings.style.shadows.filter_hint.drop_shadow_syntax"
               tag="p"
             >
@@ -966,7 +966,7 @@
               <code>spread-radius</code>
               <code>inset</code>
             </i18n-t>
-            <i18n-t
+            <i18n-t scope="global"
               keypath="settings.style.shadows.filter_hint.inset_classic"
               tag="p"
             >
diff --git a/src/components/shadow_control/shadow_control.vue b/src/components/shadow_control/shadow_control.vue
index b59ac3bc..d1e5fc22 100644
--- a/src/components/shadow_control/shadow_control.vue
+++ b/src/components/shadow_control/shadow_control.vue
@@ -204,7 +204,7 @@
         v-model="selected.alpha"
         :disabled="!present"
       />
-      <i18n-t
+      <i18n-t scope="global"
         keypath="settings.style.shadows.hintV3"
         tag="p"
       >
diff --git a/src/components/thread_tree/thread_tree.vue b/src/components/thread_tree/thread_tree.vue
index 48942005..f81653eb 100644
--- a/src/components/thread_tree/thread_tree.vue
+++ b/src/components/thread_tree/thread_tree.vue
@@ -74,7 +74,7 @@
       v-if="currentReplies.length && !threadShowing"
       class="thread-tree-replies thread-tree-replies-hidden"
     >
-      <i18n-t
+      <i18n-t scope="global"
         v-if="simple"
         tag="button"
         keypath="status.thread_follow_with_icon"
@@ -92,7 +92,7 @@
           </span>
         </template>
       </i18n-t>
-      <i18n-t
+      <i18n-t scope="global"
         v-else
         tag="button"
         keypath="status.thread_show_full_with_icon"
-- 
cgit v1.2.3-70-g09d2


From f20ae34400b35c230d3e7824f98d9b3f4e977f82 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Tue, 29 Mar 2022 01:04:37 +0300
Subject: lint

---
 src/components/color_input/color_input.vue                   | 2 +-
 src/components/notification/notification.vue                 | 5 ++++-
 src/components/opacity_input/opacity_input.vue               | 2 +-
 src/components/poll/poll.vue                                 | 5 ++++-
 src/components/selectable_list/selectable_list.vue           | 4 ++--
 src/components/settings_modal/helpers/boolean_setting.vue    | 2 +-
 src/components/settings_modal/helpers/choice_setting.vue     | 2 +-
 src/components/settings_modal/settings_modal.vue             | 7 +++++--
 src/components/settings_modal/tabs/profile_tab.vue           | 2 +-
 src/components/settings_modal/tabs/theme_tab/theme_tab.vue   | 9 ++++++---
 src/components/shadow_control/shadow_control.vue             | 3 ++-
 src/components/thread_tree/thread_tree.vue                   | 6 ++++--
 src/components/user_avatar/user_avatar.vue                   | 2 +-
 src/components/user_reporting_modal/user_reporting_modal.vue | 2 +-
 14 files changed, 34 insertions(+), 19 deletions(-)

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

diff --git a/src/components/color_input/color_input.vue b/src/components/color_input/color_input.vue
index bb25f5a8..e84603c3 100644
--- a/src/components/color_input/color_input.vue
+++ b/src/components/color_input/color_input.vue
@@ -11,7 +11,7 @@
     </label>
     <Checkbox
       v-if="typeof fallback !== 'undefined' && showOptionalTickbox"
-      :modelValue="present"
+      :model-value="present"
       :disabled="disabled"
       class="opt"
       @update:modelValue="$emit('update:modelValue', typeof modelValue === 'undefined' ? fallback : undefined)"
diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue
index d77b2f57..ff7a21f1 100644
--- a/src/components/notification/notification.vue
+++ b/src/components/notification/notification.vue
@@ -112,7 +112,10 @@
             </span>
             <span v-if="notification.type === 'pleroma:emoji_reaction'">
               <small>
-                <i18n-t scope="global" keypath="notifications.reacted_with">
+                <i18n-t
+                  scope="global"
+                  keypath="notifications.reacted_with"
+                >
                   <span class="emoji-reaction-emoji">{{ notification.emoji }}</span>
                 </i18n-t>
               </small>
diff --git a/src/components/opacity_input/opacity_input.vue b/src/components/opacity_input/opacity_input.vue
index 83bc917d..15d08e04 100644
--- a/src/components/opacity_input/opacity_input.vue
+++ b/src/components/opacity_input/opacity_input.vue
@@ -11,7 +11,7 @@
     </label>
     <Checkbox
       v-if="typeof fallback !== 'undefined'"
-      :modelValue="present"
+      :model-value="present"
       :disabled="disabled"
       class="opt"
       @update:modelValue="$emit('update:modelValue', !present ? fallback : undefined)"
diff --git a/src/components/poll/poll.vue b/src/components/poll/poll.vue
index c3880096..9e37a9d7 100644
--- a/src/components/poll/poll.vue
+++ b/src/components/poll/poll.vue
@@ -71,7 +71,10 @@
           {{ $tc("polls.votes_count", poll.votes_count, { count: poll.votes_count }) }}&nbsp;·&nbsp;
         </template>
       </div>
-      <i18n-t scope="global" :keypath="expired ? 'polls.expired' : 'polls.expires_in'">
+      <i18n-t
+        scope="global"
+        :keypath="expired ? 'polls.expired' : 'polls.expires_in'"
+      >
         <Timeago
           :time="expiresAt"
           :auto-update="60"
diff --git a/src/components/selectable_list/selectable_list.vue b/src/components/selectable_list/selectable_list.vue
index cf7cec27..6d4d0629 100644
--- a/src/components/selectable_list/selectable_list.vue
+++ b/src/components/selectable_list/selectable_list.vue
@@ -6,7 +6,7 @@
     >
       <div class="selectable-list-checkbox-wrapper">
         <Checkbox
-          :modelValue="allSelected"
+          :model-value="allSelected"
           :indeterminate="someSelected"
           @change="toggleAll"
         >
@@ -31,7 +31,7 @@
         >
           <div class="selectable-list-checkbox-wrapper">
             <Checkbox
-              :modelValue="isSelected(item)"
+              :model-value="isSelected(item)"
               @change="checked => toggle(checked, item)"
             />
           </div>
diff --git a/src/components/settings_modal/helpers/boolean_setting.vue b/src/components/settings_modal/helpers/boolean_setting.vue
index 3808bc74..69584808 100644
--- a/src/components/settings_modal/helpers/boolean_setting.vue
+++ b/src/components/settings_modal/helpers/boolean_setting.vue
@@ -4,7 +4,7 @@
     class="BooleanSetting"
   >
     <Checkbox
-      :modelValue="state"
+      :model-value="state"
       :disabled="disabled"
       @update:modelValue="update"
     >
diff --git a/src/components/settings_modal/helpers/choice_setting.vue b/src/components/settings_modal/helpers/choice_setting.vue
index b6aa853a..258c7422 100644
--- a/src/components/settings_modal/helpers/choice_setting.vue
+++ b/src/components/settings_modal/helpers/choice_setting.vue
@@ -6,7 +6,7 @@
     <slot />
     {{ ' ' }}
     <Select
-      :modelValue="state"
+      :model-value="state"
       :disabled="disabled"
       @update:modelValue="update"
     >
diff --git a/src/components/settings_modal/settings_modal.vue b/src/components/settings_modal/settings_modal.vue
index 18dd3d7a..e0e8304d 100644
--- a/src/components/settings_modal/settings_modal.vue
+++ b/src/components/settings_modal/settings_modal.vue
@@ -110,12 +110,15 @@
           </template>
         </Popover>
 
-        <Checkbox :modelValue="!!expertLevel" @update:modelValue="expertLevel = Number($event)">
+        <Checkbox
+          :model-value="!!expertLevel"
+          @update:modelValue="expertLevel = Number($event)"
+        >
           {{ $t("settings.expert_mode") }}
         </Checkbox>
         <span
-          class="extra-content"
           id="unscrolled-content"
+          class="extra-content"
         />
       </div>
     </div>
diff --git a/src/components/settings_modal/tabs/profile_tab.vue b/src/components/settings_modal/tabs/profile_tab.vue
index b78581bd..d3f6727f 100644
--- a/src/components/settings_modal/tabs/profile_tab.vue
+++ b/src/components/settings_modal/tabs/profile_tab.vue
@@ -184,8 +184,8 @@
         <button
           v-if="!isDefaultBackground"
           class="button-unstyled"
-          @click="resetBackground"
           :title="$t('settings.reset_profile_background')"
+          @click="resetBackground"
         >
           <FAIcon
             class="reset-button"
diff --git a/src/components/settings_modal/tabs/theme_tab/theme_tab.vue b/src/components/settings_modal/tabs/theme_tab/theme_tab.vue
index dfa9a735..ff2fece9 100644
--- a/src/components/settings_modal/tabs/theme_tab/theme_tab.vue
+++ b/src/components/settings_modal/tabs/theme_tab/theme_tab.vue
@@ -951,14 +951,16 @@
             :fallback="currentShadowFallback"
           />
           <div v-if="shadowSelected === 'avatar' || shadowSelected === 'avatarStatus'">
-            <i18n-t scope="global"
+            <i18n-t
+              scope="global"
               keypath="settings.style.shadows.filter_hint.always_drop_shadow"
               tag="p"
             >
               <code>filter: drop-shadow()</code>
             </i18n-t>
             <p>{{ $t('settings.style.shadows.filter_hint.avatar_inset') }}</p>
-            <i18n-t scope="global"
+            <i18n-t
+              scope="global"
               keypath="settings.style.shadows.filter_hint.drop_shadow_syntax"
               tag="p"
             >
@@ -966,7 +968,8 @@
               <code>spread-radius</code>
               <code>inset</code>
             </i18n-t>
-            <i18n-t scope="global"
+            <i18n-t
+              scope="global"
               keypath="settings.style.shadows.filter_hint.inset_classic"
               tag="p"
             >
diff --git a/src/components/shadow_control/shadow_control.vue b/src/components/shadow_control/shadow_control.vue
index d1e5fc22..f2fc7b99 100644
--- a/src/components/shadow_control/shadow_control.vue
+++ b/src/components/shadow_control/shadow_control.vue
@@ -204,7 +204,8 @@
         v-model="selected.alpha"
         :disabled="!present"
       />
-      <i18n-t scope="global"
+      <i18n-t
+        scope="global"
         keypath="settings.style.shadows.hintV3"
         tag="p"
       >
diff --git a/src/components/thread_tree/thread_tree.vue b/src/components/thread_tree/thread_tree.vue
index f81653eb..74577583 100644
--- a/src/components/thread_tree/thread_tree.vue
+++ b/src/components/thread_tree/thread_tree.vue
@@ -74,8 +74,9 @@
       v-if="currentReplies.length && !threadShowing"
       class="thread-tree-replies thread-tree-replies-hidden"
     >
-      <i18n-t scope="global"
+      <i18n-t
         v-if="simple"
+        scope="global"
         tag="button"
         keypath="status.thread_follow_with_icon"
         class="button-unstyled -link thread-tree-show-replies-button"
@@ -92,8 +93,9 @@
           </span>
         </template>
       </i18n-t>
-      <i18n-t scope="global"
+      <i18n-t
         v-else
+        scope="global"
         tag="button"
         keypath="status.thread_show_full_with_icon"
         class="button-unstyled -link thread-tree-show-replies-button"
diff --git a/src/components/user_avatar/user_avatar.vue b/src/components/user_avatar/user_avatar.vue
index b19ce89b..f4d294df 100644
--- a/src/components/user_avatar/user_avatar.vue
+++ b/src/components/user_avatar/user_avatar.vue
@@ -2,7 +2,7 @@
   <span
     class="Avatar"
     :class="{ '-compact': compact }"
-    >
+  >
     <StillImage
       v-if="user"
       class="avatar"
diff --git a/src/components/user_reporting_modal/user_reporting_modal.vue b/src/components/user_reporting_modal/user_reporting_modal.vue
index 2993e4ec..cd7b52c4 100644
--- a/src/components/user_reporting_modal/user_reporting_modal.vue
+++ b/src/components/user_reporting_modal/user_reporting_modal.vue
@@ -53,7 +53,7 @@
                   :statusoid="item"
                 />
                 <Checkbox
-                  :modelValue="isChecked(item.id)"
+                  :model-value="isChecked(item.id)"
                   @change="checked => toggleStatus(checked, item.id)"
                 />
               </div>
-- 
cgit v1.2.3-70-g09d2


From d9d4d8954e8dc7a10b5c36840437516f6e56b436 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Tue, 29 Mar 2022 11:57:54 +0300
Subject: Revert "lint"

This reverts commit f20ae34400b35c230d3e7824f98d9b3f4e977f82.
---
 src/components/color_input/color_input.vue                   | 2 +-
 src/components/notification/notification.vue                 | 5 +----
 src/components/opacity_input/opacity_input.vue               | 2 +-
 src/components/poll/poll.vue                                 | 5 +----
 src/components/selectable_list/selectable_list.vue           | 4 ++--
 src/components/settings_modal/helpers/boolean_setting.vue    | 2 +-
 src/components/settings_modal/helpers/choice_setting.vue     | 2 +-
 src/components/settings_modal/settings_modal.vue             | 7 ++-----
 src/components/settings_modal/tabs/profile_tab.vue           | 2 +-
 src/components/settings_modal/tabs/theme_tab/theme_tab.vue   | 9 +++------
 src/components/shadow_control/shadow_control.vue             | 3 +--
 src/components/thread_tree/thread_tree.vue                   | 6 ++----
 src/components/user_avatar/user_avatar.vue                   | 2 +-
 src/components/user_reporting_modal/user_reporting_modal.vue | 2 +-
 14 files changed, 19 insertions(+), 34 deletions(-)

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

diff --git a/src/components/color_input/color_input.vue b/src/components/color_input/color_input.vue
index e84603c3..bb25f5a8 100644
--- a/src/components/color_input/color_input.vue
+++ b/src/components/color_input/color_input.vue
@@ -11,7 +11,7 @@
     </label>
     <Checkbox
       v-if="typeof fallback !== 'undefined' && showOptionalTickbox"
-      :model-value="present"
+      :modelValue="present"
       :disabled="disabled"
       class="opt"
       @update:modelValue="$emit('update:modelValue', typeof modelValue === 'undefined' ? fallback : undefined)"
diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue
index ff7a21f1..d77b2f57 100644
--- a/src/components/notification/notification.vue
+++ b/src/components/notification/notification.vue
@@ -112,10 +112,7 @@
             </span>
             <span v-if="notification.type === 'pleroma:emoji_reaction'">
               <small>
-                <i18n-t
-                  scope="global"
-                  keypath="notifications.reacted_with"
-                >
+                <i18n-t scope="global" keypath="notifications.reacted_with">
                   <span class="emoji-reaction-emoji">{{ notification.emoji }}</span>
                 </i18n-t>
               </small>
diff --git a/src/components/opacity_input/opacity_input.vue b/src/components/opacity_input/opacity_input.vue
index 15d08e04..83bc917d 100644
--- a/src/components/opacity_input/opacity_input.vue
+++ b/src/components/opacity_input/opacity_input.vue
@@ -11,7 +11,7 @@
     </label>
     <Checkbox
       v-if="typeof fallback !== 'undefined'"
-      :model-value="present"
+      :modelValue="present"
       :disabled="disabled"
       class="opt"
       @update:modelValue="$emit('update:modelValue', !present ? fallback : undefined)"
diff --git a/src/components/poll/poll.vue b/src/components/poll/poll.vue
index 9e37a9d7..c3880096 100644
--- a/src/components/poll/poll.vue
+++ b/src/components/poll/poll.vue
@@ -71,10 +71,7 @@
           {{ $tc("polls.votes_count", poll.votes_count, { count: poll.votes_count }) }}&nbsp;·&nbsp;
         </template>
       </div>
-      <i18n-t
-        scope="global"
-        :keypath="expired ? 'polls.expired' : 'polls.expires_in'"
-      >
+      <i18n-t scope="global" :keypath="expired ? 'polls.expired' : 'polls.expires_in'">
         <Timeago
           :time="expiresAt"
           :auto-update="60"
diff --git a/src/components/selectable_list/selectable_list.vue b/src/components/selectable_list/selectable_list.vue
index 6d4d0629..cf7cec27 100644
--- a/src/components/selectable_list/selectable_list.vue
+++ b/src/components/selectable_list/selectable_list.vue
@@ -6,7 +6,7 @@
     >
       <div class="selectable-list-checkbox-wrapper">
         <Checkbox
-          :model-value="allSelected"
+          :modelValue="allSelected"
           :indeterminate="someSelected"
           @change="toggleAll"
         >
@@ -31,7 +31,7 @@
         >
           <div class="selectable-list-checkbox-wrapper">
             <Checkbox
-              :model-value="isSelected(item)"
+              :modelValue="isSelected(item)"
               @change="checked => toggle(checked, item)"
             />
           </div>
diff --git a/src/components/settings_modal/helpers/boolean_setting.vue b/src/components/settings_modal/helpers/boolean_setting.vue
index 69584808..3808bc74 100644
--- a/src/components/settings_modal/helpers/boolean_setting.vue
+++ b/src/components/settings_modal/helpers/boolean_setting.vue
@@ -4,7 +4,7 @@
     class="BooleanSetting"
   >
     <Checkbox
-      :model-value="state"
+      :modelValue="state"
       :disabled="disabled"
       @update:modelValue="update"
     >
diff --git a/src/components/settings_modal/helpers/choice_setting.vue b/src/components/settings_modal/helpers/choice_setting.vue
index 258c7422..b6aa853a 100644
--- a/src/components/settings_modal/helpers/choice_setting.vue
+++ b/src/components/settings_modal/helpers/choice_setting.vue
@@ -6,7 +6,7 @@
     <slot />
     {{ ' ' }}
     <Select
-      :model-value="state"
+      :modelValue="state"
       :disabled="disabled"
       @update:modelValue="update"
     >
diff --git a/src/components/settings_modal/settings_modal.vue b/src/components/settings_modal/settings_modal.vue
index e0e8304d..18dd3d7a 100644
--- a/src/components/settings_modal/settings_modal.vue
+++ b/src/components/settings_modal/settings_modal.vue
@@ -110,15 +110,12 @@
           </template>
         </Popover>
 
-        <Checkbox
-          :model-value="!!expertLevel"
-          @update:modelValue="expertLevel = Number($event)"
-        >
+        <Checkbox :modelValue="!!expertLevel" @update:modelValue="expertLevel = Number($event)">
           {{ $t("settings.expert_mode") }}
         </Checkbox>
         <span
-          id="unscrolled-content"
           class="extra-content"
+          id="unscrolled-content"
         />
       </div>
     </div>
diff --git a/src/components/settings_modal/tabs/profile_tab.vue b/src/components/settings_modal/tabs/profile_tab.vue
index d3f6727f..b78581bd 100644
--- a/src/components/settings_modal/tabs/profile_tab.vue
+++ b/src/components/settings_modal/tabs/profile_tab.vue
@@ -184,8 +184,8 @@
         <button
           v-if="!isDefaultBackground"
           class="button-unstyled"
-          :title="$t('settings.reset_profile_background')"
           @click="resetBackground"
+          :title="$t('settings.reset_profile_background')"
         >
           <FAIcon
             class="reset-button"
diff --git a/src/components/settings_modal/tabs/theme_tab/theme_tab.vue b/src/components/settings_modal/tabs/theme_tab/theme_tab.vue
index ff2fece9..dfa9a735 100644
--- a/src/components/settings_modal/tabs/theme_tab/theme_tab.vue
+++ b/src/components/settings_modal/tabs/theme_tab/theme_tab.vue
@@ -951,16 +951,14 @@
             :fallback="currentShadowFallback"
           />
           <div v-if="shadowSelected === 'avatar' || shadowSelected === 'avatarStatus'">
-            <i18n-t
-              scope="global"
+            <i18n-t scope="global"
               keypath="settings.style.shadows.filter_hint.always_drop_shadow"
               tag="p"
             >
               <code>filter: drop-shadow()</code>
             </i18n-t>
             <p>{{ $t('settings.style.shadows.filter_hint.avatar_inset') }}</p>
-            <i18n-t
-              scope="global"
+            <i18n-t scope="global"
               keypath="settings.style.shadows.filter_hint.drop_shadow_syntax"
               tag="p"
             >
@@ -968,8 +966,7 @@
               <code>spread-radius</code>
               <code>inset</code>
             </i18n-t>
-            <i18n-t
-              scope="global"
+            <i18n-t scope="global"
               keypath="settings.style.shadows.filter_hint.inset_classic"
               tag="p"
             >
diff --git a/src/components/shadow_control/shadow_control.vue b/src/components/shadow_control/shadow_control.vue
index f2fc7b99..d1e5fc22 100644
--- a/src/components/shadow_control/shadow_control.vue
+++ b/src/components/shadow_control/shadow_control.vue
@@ -204,8 +204,7 @@
         v-model="selected.alpha"
         :disabled="!present"
       />
-      <i18n-t
-        scope="global"
+      <i18n-t scope="global"
         keypath="settings.style.shadows.hintV3"
         tag="p"
       >
diff --git a/src/components/thread_tree/thread_tree.vue b/src/components/thread_tree/thread_tree.vue
index 74577583..f81653eb 100644
--- a/src/components/thread_tree/thread_tree.vue
+++ b/src/components/thread_tree/thread_tree.vue
@@ -74,9 +74,8 @@
       v-if="currentReplies.length && !threadShowing"
       class="thread-tree-replies thread-tree-replies-hidden"
     >
-      <i18n-t
+      <i18n-t scope="global"
         v-if="simple"
-        scope="global"
         tag="button"
         keypath="status.thread_follow_with_icon"
         class="button-unstyled -link thread-tree-show-replies-button"
@@ -93,9 +92,8 @@
           </span>
         </template>
       </i18n-t>
-      <i18n-t
+      <i18n-t scope="global"
         v-else
-        scope="global"
         tag="button"
         keypath="status.thread_show_full_with_icon"
         class="button-unstyled -link thread-tree-show-replies-button"
diff --git a/src/components/user_avatar/user_avatar.vue b/src/components/user_avatar/user_avatar.vue
index f4d294df..b19ce89b 100644
--- a/src/components/user_avatar/user_avatar.vue
+++ b/src/components/user_avatar/user_avatar.vue
@@ -2,7 +2,7 @@
   <span
     class="Avatar"
     :class="{ '-compact': compact }"
-  >
+    >
     <StillImage
       v-if="user"
       class="avatar"
diff --git a/src/components/user_reporting_modal/user_reporting_modal.vue b/src/components/user_reporting_modal/user_reporting_modal.vue
index cd7b52c4..2993e4ec 100644
--- a/src/components/user_reporting_modal/user_reporting_modal.vue
+++ b/src/components/user_reporting_modal/user_reporting_modal.vue
@@ -53,7 +53,7 @@
                   :statusoid="item"
                 />
                 <Checkbox
-                  :model-value="isChecked(item.id)"
+                  :modelValue="isChecked(item.id)"
                   @change="checked => toggleStatus(checked, item.id)"
                 />
               </div>
-- 
cgit v1.2.3-70-g09d2


From 5bbc0e0bb5f4a0c95674e6879975e6b5121b421e Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Tue, 29 Mar 2022 15:35:18 +0300
Subject: lint + fixes for registration

---
 src/components/color_input/color_input.vue         |  2 +-
 src/components/notification/notification.vue       |  5 ++-
 src/components/opacity_input/opacity_input.vue     |  2 +-
 src/components/poll/poll.vue                       |  5 ++-
 src/components/registration/registration.js        |  2 +-
 src/components/registration/registration.vue       | 38 +++++++++++-----------
 src/components/selectable_list/selectable_list.vue |  4 +--
 .../settings_modal/helpers/boolean_setting.vue     |  2 +-
 .../settings_modal/helpers/choice_setting.vue      |  2 +-
 src/components/settings_modal/settings_modal.vue   |  7 ++--
 src/components/settings_modal/tabs/profile_tab.vue |  2 +-
 src/components/thread_tree/thread_tree.vue         |  2 +-
 src/components/user_avatar/user_avatar.vue         |  2 +-
 .../user_reporting_modal/user_reporting_modal.vue  |  2 +-
 14 files changed, 43 insertions(+), 34 deletions(-)

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

diff --git a/src/components/color_input/color_input.vue b/src/components/color_input/color_input.vue
index bb25f5a8..e84603c3 100644
--- a/src/components/color_input/color_input.vue
+++ b/src/components/color_input/color_input.vue
@@ -11,7 +11,7 @@
     </label>
     <Checkbox
       v-if="typeof fallback !== 'undefined' && showOptionalTickbox"
-      :modelValue="present"
+      :model-value="present"
       :disabled="disabled"
       class="opt"
       @update:modelValue="$emit('update:modelValue', typeof modelValue === 'undefined' ? fallback : undefined)"
diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue
index d77b2f57..ff7a21f1 100644
--- a/src/components/notification/notification.vue
+++ b/src/components/notification/notification.vue
@@ -112,7 +112,10 @@
             </span>
             <span v-if="notification.type === 'pleroma:emoji_reaction'">
               <small>
-                <i18n-t scope="global" keypath="notifications.reacted_with">
+                <i18n-t
+                  scope="global"
+                  keypath="notifications.reacted_with"
+                >
                   <span class="emoji-reaction-emoji">{{ notification.emoji }}</span>
                 </i18n-t>
               </small>
diff --git a/src/components/opacity_input/opacity_input.vue b/src/components/opacity_input/opacity_input.vue
index 83bc917d..15d08e04 100644
--- a/src/components/opacity_input/opacity_input.vue
+++ b/src/components/opacity_input/opacity_input.vue
@@ -11,7 +11,7 @@
     </label>
     <Checkbox
       v-if="typeof fallback !== 'undefined'"
-      :modelValue="present"
+      :model-value="present"
       :disabled="disabled"
       class="opt"
       @update:modelValue="$emit('update:modelValue', !present ? fallback : undefined)"
diff --git a/src/components/poll/poll.vue b/src/components/poll/poll.vue
index c3880096..9e37a9d7 100644
--- a/src/components/poll/poll.vue
+++ b/src/components/poll/poll.vue
@@ -71,7 +71,10 @@
           {{ $tc("polls.votes_count", poll.votes_count, { count: poll.votes_count }) }}&nbsp;·&nbsp;
         </template>
       </div>
-      <i18n-t scope="global" :keypath="expired ? 'polls.expired' : 'polls.expires_in'">
+      <i18n-t
+        scope="global"
+        :keypath="expired ? 'polls.expired' : 'polls.expires_in'"
+      >
         <Timeago
           :time="expiresAt"
           :auto-update="60"
diff --git a/src/components/registration/registration.js b/src/components/registration/registration.js
index 531cc480..a792fb7b 100644
--- a/src/components/registration/registration.js
+++ b/src/components/registration/registration.js
@@ -24,7 +24,7 @@ const registration = {
         password: { required },
         confirm: {
           required,
-          sameAsPassword: sameAs('password')
+          sameAs: sameAs(this.password)
         },
         reason: { required: requiredIf(() => this.accountApprovalRequired) }
       }
diff --git a/src/components/registration/registration.vue b/src/components/registration/registration.vue
index 65b4bb33..3d409109 100644
--- a/src/components/registration/registration.vue
+++ b/src/components/registration/registration.vue
@@ -12,7 +12,7 @@
           <div class="text-fields">
             <div
               class="form-group"
-              :class="{ 'form-group--error': $v.user.username.$error }"
+              :class="{ 'form-group--error': v$.user.username.$error }"
             >
               <label
                 class="form--label"
@@ -20,18 +20,18 @@
               >{{ $t('login.username') }}</label>
               <input
                 id="sign-up-username"
-                v-model.trim="$v.user.username.$model"
+                v-model.trim="v$.user.username.$model"
                 :disabled="isPending"
                 class="form-control"
                 :placeholder="$t('registration.username_placeholder')"
               >
             </div>
             <div
-              v-if="$v.user.username.$dirty"
+              v-if="v$.user.username.$dirty"
               class="form-error"
             >
               <ul>
-                <li v-if="!$v.user.username.required">
+                <li v-if="!v$.user.username.required">
                   <span>{{ $t('registration.validations.username_required') }}</span>
                 </li>
               </ul>
@@ -39,7 +39,7 @@
 
             <div
               class="form-group"
-              :class="{ 'form-group--error': $v.user.fullname.$error }"
+              :class="{ 'form-group--error': v$.user.fullname.$error }"
             >
               <label
                 class="form--label"
@@ -47,18 +47,18 @@
               >{{ $t('registration.fullname') }}</label>
               <input
                 id="sign-up-fullname"
-                v-model.trim="$v.user.fullname.$model"
+                v-model.trim="v$.user.fullname.$model"
                 :disabled="isPending"
                 class="form-control"
                 :placeholder="$t('registration.fullname_placeholder')"
               >
             </div>
             <div
-              v-if="$v.user.fullname.$dirty"
+              v-if="v$.user.fullname.$dirty"
               class="form-error"
             >
               <ul>
-                <li v-if="!$v.user.fullname.required">
+                <li v-if="!v$.user.fullname.required">
                   <span>{{ $t('registration.validations.fullname_required') }}</span>
                 </li>
               </ul>
@@ -66,7 +66,7 @@
 
             <div
               class="form-group"
-              :class="{ 'form-group--error': $v.user.email.$error }"
+              :class="{ 'form-group--error': v$.user.email.$error }"
             >
               <label
                 class="form--label"
@@ -74,18 +74,18 @@
               >{{ $t('registration.email') }}</label>
               <input
                 id="email"
-                v-model="$v.user.email.$model"
+                v-model="v$.user.email.$model"
                 :disabled="isPending"
                 class="form-control"
                 type="email"
               >
             </div>
             <div
-              v-if="$v.user.email.$dirty"
+              v-if="v$.user.email.$dirty"
               class="form-error"
             >
               <ul>
-                <li v-if="!$v.user.email.required">
+                <li v-if="!v$.user.email.required">
                   <span>{{ $t('registration.validations.email_required') }}</span>
                 </li>
               </ul>
@@ -107,7 +107,7 @@
 
             <div
               class="form-group"
-              :class="{ 'form-group--error': $v.user.password.$error }"
+              :class="{ 'form-group--error': v$.user.password.$error }"
             >
               <label
                 class="form--label"
@@ -122,11 +122,11 @@
               >
             </div>
             <div
-              v-if="$v.user.password.$dirty"
+              v-if="v$.user.password.$dirty"
               class="form-error"
             >
               <ul>
-                <li v-if="!$v.user.password.required">
+                <li v-if="!v$.user.password.required">
                   <span>{{ $t('registration.validations.password_required') }}</span>
                 </li>
               </ul>
@@ -134,7 +134,7 @@
 
             <div
               class="form-group"
-              :class="{ 'form-group--error': $v.user.confirm.$error }"
+              :class="{ 'form-group--error': v$.user.confirm.$error }"
             >
               <label
                 class="form--label"
@@ -149,14 +149,14 @@
               >
             </div>
             <div
-              v-if="$v.user.confirm.$dirty"
+              v-if="v$.user.confirm.$dirty"
               class="form-error"
             >
               <ul>
-                <li v-if="!$v.user.confirm.required">
+                <li v-if="!v$.user.confirm.required">
                   <span>{{ $t('registration.validations.password_confirmation_required') }}</span>
                 </li>
-                <li v-if="!$v.user.confirm.sameAsPassword">
+                <li v-if="!v$.user.confirm.sameAsPassword">
                   <span>{{ $t('registration.validations.password_confirmation_match') }}</span>
                 </li>
               </ul>
diff --git a/src/components/selectable_list/selectable_list.vue b/src/components/selectable_list/selectable_list.vue
index cf7cec27..6d4d0629 100644
--- a/src/components/selectable_list/selectable_list.vue
+++ b/src/components/selectable_list/selectable_list.vue
@@ -6,7 +6,7 @@
     >
       <div class="selectable-list-checkbox-wrapper">
         <Checkbox
-          :modelValue="allSelected"
+          :model-value="allSelected"
           :indeterminate="someSelected"
           @change="toggleAll"
         >
@@ -31,7 +31,7 @@
         >
           <div class="selectable-list-checkbox-wrapper">
             <Checkbox
-              :modelValue="isSelected(item)"
+              :model-value="isSelected(item)"
               @change="checked => toggle(checked, item)"
             />
           </div>
diff --git a/src/components/settings_modal/helpers/boolean_setting.vue b/src/components/settings_modal/helpers/boolean_setting.vue
index 3808bc74..69584808 100644
--- a/src/components/settings_modal/helpers/boolean_setting.vue
+++ b/src/components/settings_modal/helpers/boolean_setting.vue
@@ -4,7 +4,7 @@
     class="BooleanSetting"
   >
     <Checkbox
-      :modelValue="state"
+      :model-value="state"
       :disabled="disabled"
       @update:modelValue="update"
     >
diff --git a/src/components/settings_modal/helpers/choice_setting.vue b/src/components/settings_modal/helpers/choice_setting.vue
index b6aa853a..258c7422 100644
--- a/src/components/settings_modal/helpers/choice_setting.vue
+++ b/src/components/settings_modal/helpers/choice_setting.vue
@@ -6,7 +6,7 @@
     <slot />
     {{ ' ' }}
     <Select
-      :modelValue="state"
+      :model-value="state"
       :disabled="disabled"
       @update:modelValue="update"
     >
diff --git a/src/components/settings_modal/settings_modal.vue b/src/components/settings_modal/settings_modal.vue
index 18dd3d7a..e0e8304d 100644
--- a/src/components/settings_modal/settings_modal.vue
+++ b/src/components/settings_modal/settings_modal.vue
@@ -110,12 +110,15 @@
           </template>
         </Popover>
 
-        <Checkbox :modelValue="!!expertLevel" @update:modelValue="expertLevel = Number($event)">
+        <Checkbox
+          :model-value="!!expertLevel"
+          @update:modelValue="expertLevel = Number($event)"
+        >
           {{ $t("settings.expert_mode") }}
         </Checkbox>
         <span
-          class="extra-content"
           id="unscrolled-content"
+          class="extra-content"
         />
       </div>
     </div>
diff --git a/src/components/settings_modal/tabs/profile_tab.vue b/src/components/settings_modal/tabs/profile_tab.vue
index b78581bd..d3f6727f 100644
--- a/src/components/settings_modal/tabs/profile_tab.vue
+++ b/src/components/settings_modal/tabs/profile_tab.vue
@@ -184,8 +184,8 @@
         <button
           v-if="!isDefaultBackground"
           class="button-unstyled"
-          @click="resetBackground"
           :title="$t('settings.reset_profile_background')"
+          @click="resetBackground"
         >
           <FAIcon
             class="reset-button"
diff --git a/src/components/thread_tree/thread_tree.vue b/src/components/thread_tree/thread_tree.vue
index 4cae2726..74577583 100644
--- a/src/components/thread_tree/thread_tree.vue
+++ b/src/components/thread_tree/thread_tree.vue
@@ -75,8 +75,8 @@
       class="thread-tree-replies thread-tree-replies-hidden"
     >
       <i18n-t
-        scope="global"
         v-if="simple"
+        scope="global"
         tag="button"
         keypath="status.thread_follow_with_icon"
         class="button-unstyled -link thread-tree-show-replies-button"
diff --git a/src/components/user_avatar/user_avatar.vue b/src/components/user_avatar/user_avatar.vue
index b19ce89b..f4d294df 100644
--- a/src/components/user_avatar/user_avatar.vue
+++ b/src/components/user_avatar/user_avatar.vue
@@ -2,7 +2,7 @@
   <span
     class="Avatar"
     :class="{ '-compact': compact }"
-    >
+  >
     <StillImage
       v-if="user"
       class="avatar"
diff --git a/src/components/user_reporting_modal/user_reporting_modal.vue b/src/components/user_reporting_modal/user_reporting_modal.vue
index 2993e4ec..cd7b52c4 100644
--- a/src/components/user_reporting_modal/user_reporting_modal.vue
+++ b/src/components/user_reporting_modal/user_reporting_modal.vue
@@ -53,7 +53,7 @@
                   :statusoid="item"
                 />
                 <Checkbox
-                  :modelValue="isChecked(item.id)"
+                  :model-value="isChecked(item.id)"
                   @change="checked => toggleStatus(checked, item.id)"
                 />
               </div>
-- 
cgit v1.2.3-70-g09d2


From 19439910772ed5205edbb258b3d8a97315dde9b5 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Wed, 30 Mar 2022 12:33:56 +0300
Subject: make all clickable icons into actual buttons

---
 src/components/importer/importer.vue            | 18 ++++++++++++------
 src/components/login_form/login_form.vue        | 12 ++++++++----
 src/components/mfa_form/recovery_form.vue       | 12 ++++++++----
 src/components/mfa_form/totp_form.vue           | 14 +++++++++-----
 src/components/notification/notification.vue    | 24 ++++++++++++++++--------
 src/components/notifications/notifications.scss |  4 ----
 6 files changed, 53 insertions(+), 31 deletions(-)

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

diff --git a/src/components/importer/importer.vue b/src/components/importer/importer.vue
index ddc3010e..5df238e2 100644
--- a/src/components/importer/importer.vue
+++ b/src/components/importer/importer.vue
@@ -20,20 +20,26 @@
     >
       {{ submitButtonLabel || $t('importer.submit') }}
     </button>
-    <div v-if="success">
+    <button
+      v-if="success"
+      class="button-unstyled"
+      @click="dismiss"
+    >
       <FAIcon
         icon="times"
-        @click="dismiss"
       />
       <p>{{ successMessage || $t('importer.success') }}</p>
-    </div>
-    <div v-else-if="error">
+    </button>
+    <button
+      v-else-if="error"
+      class="button-unstyled"
+      @click="dismiss"
+    >
       <FAIcon
         icon="times"
-        @click="dismiss"
       />
       <p>{{ errorMessage || $t('importer.error') }}</p>
-    </div>
+    </button>
   </div>
 </template>
 
diff --git a/src/components/login_form/login_form.vue b/src/components/login_form/login_form.vue
index bfabb946..87fa37c6 100644
--- a/src/components/login_form/login_form.vue
+++ b/src/components/login_form/login_form.vue
@@ -76,11 +76,15 @@
     >
       <div class="alert error">
         {{ error }}
-        <FAIcon
-          class="fa-scale-110 fa-old-padding"
-          icon="times"
+        <button
+          class="button-unstyled"
           @click="clearError"
-        />
+        >
+          <FAIcon
+            class="fa-scale-110 fa-old-padding"
+            icon="times"
+          />
+        </button>
       </div>
     </div>
   </div>
diff --git a/src/components/mfa_form/recovery_form.vue b/src/components/mfa_form/recovery_form.vue
index 7c594228..a9cf39aa 100644
--- a/src/components/mfa_form/recovery_form.vue
+++ b/src/components/mfa_form/recovery_form.vue
@@ -56,11 +56,15 @@
     >
       <div class="alert error">
         {{ error }}
-        <FAIcon
-          class="fa-scale-110 fa-old-padding"
-          icon="times"
+        <button
+          class="button-unstyled"
           @click="clearError"
-        />
+        >
+          <FAIcon
+            class="fa-scale-110 fa-old-padding"
+            icon="times"
+          />
+        </button>
       </div>
     </div>
   </div>
diff --git a/src/components/mfa_form/totp_form.vue b/src/components/mfa_form/totp_form.vue
index 4ee13992..709eb9b8 100644
--- a/src/components/mfa_form/totp_form.vue
+++ b/src/components/mfa_form/totp_form.vue
@@ -58,12 +58,16 @@
     >
       <div class="alert error">
         {{ error }}
-        <FAIcon
-          size="lg"
-          class="fa-scale-110 fa-old-padding"
-          icon="times"
+        <button
+          class="button-unstyled"
           @click="clearError"
-        />
+        >
+          <FAIcon
+            size="lg"
+            class="fa-scale-110 fa-old-padding"
+            icon="times"
+          />
+        </button>
       </div>
     </div>
   </div>
diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue
index ff7a21f1..9ecb034f 100644
--- a/src/components/notification/notification.vue
+++ b/src/components/notification/notification.vue
@@ -172,18 +172,26 @@
             v-if="notification.type === 'follow_request'"
             style="white-space: nowrap;"
           >
-            <FAIcon
-              icon="check"
-              class="fa-scale-110 fa-old-padding follow-request-accept"
+            <button
+              class="button-unstyled"
               :title="$t('tool_tip.accept_follow_request')"
               @click="approveUser()"
-            />
-            <FAIcon
-              icon="times"
-              class="fa-scale-110 fa-old-padding follow-request-reject"
+            >
+              <FAIcon
+                icon="check"
+                class="fa-scale-110 fa-old-padding follow-request-accept"
+              />
+            </button>
+            <button
+              class="button-unstyled"
               :title="$t('tool_tip.reject_follow_request')"
               @click="denyUser()"
-            />
+            >
+              <FAIcon
+                icon="times"
+                class="fa-scale-110 fa-old-padding follow-request-reject"
+              />
+            </button>
           </div>
         </div>
         <div
diff --git a/src/components/notifications/notifications.scss b/src/components/notifications/notifications.scss
index 9e5663ed..a285027d 100644
--- a/src/components/notifications/notifications.scss
+++ b/src/components/notifications/notifications.scss
@@ -64,8 +64,6 @@
   }
 
   .follow-request-accept {
-    cursor: pointer;
-
     &:hover {
       color: $fallback--text;
       color: var(--text, $fallback--text);
@@ -73,8 +71,6 @@
   }
 
   .follow-request-reject {
-    cursor: pointer;
-
     &:hover {
       color: $fallback--cRed;
       color: var(--cRed, $fallback--cRed);
-- 
cgit v1.2.3-70-g09d2


From df487e3980f7128fa366ea25e99bed17af114d52 Mon Sep 17 00:00:00 2001
From: Tusooa Zhu <tusooa@kazv.moe>
Date: Fri, 20 May 2022 12:39:46 -0400
Subject: Show poll-end notifications

Ref: poll-notif
---
 src/components/notification/notification.vue          | 8 ++++++++
 src/services/notification_utils/notification_utils.js | 8 ++++++--
 2 files changed, 14 insertions(+), 2 deletions(-)

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

diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue
index 9ecb034f..7d3d0c69 100644
--- a/src/components/notification/notification.vue
+++ b/src/components/notification/notification.vue
@@ -120,6 +120,14 @@
                 </i18n-t>
               </small>
             </span>
+            <span v-if="notification.type === 'poll'">
+              <FAIcon
+                class="type-icon"
+                icon="poll-h"
+              />
+              {{ ' ' }}
+              <small>{{ $t('notifications.poll_ended') }}</small>
+            </span>
           </div>
           <div
             v-if="isStatusNotification"
diff --git a/src/services/notification_utils/notification_utils.js b/src/services/notification_utils/notification_utils.js
index 6fef1022..8a05f77b 100644
--- a/src/services/notification_utils/notification_utils.js
+++ b/src/services/notification_utils/notification_utils.js
@@ -14,11 +14,12 @@ export const visibleTypes = store => {
     rootState.config.notificationVisibility.follows && 'follow',
     rootState.config.notificationVisibility.followRequest && 'follow_request',
     rootState.config.notificationVisibility.moves && 'move',
-    rootState.config.notificationVisibility.emojiReactions && 'pleroma:emoji_reaction'
+    rootState.config.notificationVisibility.emojiReactions && 'pleroma:emoji_reaction',
+    'poll'
   ].filter(_ => _))
 }
 
-const statusNotifications = ['like', 'mention', 'repeat', 'pleroma:emoji_reaction']
+const statusNotifications = ['like', 'mention', 'repeat', 'pleroma:emoji_reaction', 'poll']
 
 export const isStatusNotification = (type) => includes(statusNotifications, type)
 
@@ -98,6 +99,9 @@ export const prepareNotificationObject = (notification, i18n) => {
     case 'follow_request':
       i18nString = 'follow_request'
       break
+    case 'poll':
+      i18nString = 'poll_ended'
+      break
   }
 
   if (notification.type === 'pleroma:emoji_reaction') {
-- 
cgit v1.2.3-70-g09d2


From 30c4a66518329b307d06f1fcfc39a7bf0c453f28 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Wed, 15 Jun 2022 04:01:46 +0300
Subject: use user popovers in notifications as well

---
 src/components/notification/notification.js  |  4 ++-
 src/components/notification/notification.vue | 39 +++++++++++++++++++---------
 2 files changed, 30 insertions(+), 13 deletions(-)

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

diff --git a/src/components/notification/notification.js b/src/components/notification/notification.js
index 398bb7a9..9408b217 100644
--- a/src/components/notification/notification.js
+++ b/src/components/notification/notification.js
@@ -5,6 +5,7 @@ import UserAvatar from '../user_avatar/user_avatar.vue'
 import UserCard from '../user_card/user_card.vue'
 import Timeago from '../timeago/timeago.vue'
 import RichContent from 'src/components/rich_content/rich_content.jsx'
+import Popover from '../popover/popover.vue'
 import { isStatusNotification } from '../../services/notification_utils/notification_utils.js'
 import { highlightClass, highlightStyle } from '../../services/user_highlighter/user_highlighter.js'
 import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
@@ -46,7 +47,8 @@ const Notification = {
     UserCard,
     Timeago,
     Status,
-    RichContent
+    RichContent,
+    Popover
   },
   methods: {
     toggleUserExpanded () {
diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue
index 7d3d0c69..a44481c9 100644
--- a/src/components/notification/notification.vue
+++ b/src/components/notification/notification.vue
@@ -34,21 +34,36 @@
       <a
         class="avatar-container"
         :href="$router.resolve(userProfileLink).href"
-        @click.stop.prevent.capture="toggleUserExpanded"
+        @click.prevent
       >
-        <UserAvatar
-          :compact="true"
-          :better-shadow="betterShadow"
-          :user="notification.from_profile"
-        />
+        <Popover
+          trigger="click"
+          popover-class="popover-default user-popover"
+          :overlay-centers="true"
+          overlay-centers-selector=".user-info-avatar-link .Avatar"
+        >
+          <template v-slot:trigger>
+            <UserAvatar
+              class="post-avatar"
+              :bot="botIndicator"
+              :compact="true"
+              :better-shadow="betterShadow"
+              :user="notification.from_profile"
+            />
+          </template>
+          <template v-slot:content>
+            <UserCard
+              class="mention-link-popover"
+              :user-id="getUser(notification).id"
+              :hide-bio="true"
+              :bordered="false"
+              :allow-zooming-avatar="true"
+              :rounded="true"
+            />
+          </template>
+        </Popover>
       </a>
       <div class="notification-right">
-        <UserCard
-          v-if="userExpanded"
-          :user-id="getUser(notification).id"
-          :rounded="true"
-          :bordered="true"
-        />
         <span class="notification-details">
           <div class="name-and-action">
             <!-- eslint-disable vue/no-v-html -->
-- 
cgit v1.2.3-70-g09d2


From d84cda7009d486a047953b1ca2d27acf35b8ddc1 Mon Sep 17 00:00:00 2001
From: Henry Jameson <spam@hjkos.com>
Date: Thu, 16 Jun 2022 16:30:05 +0300
Subject: unify user popovers into a separate component

---
 src/components/mention_link/mention_link.js  |   3 +-
 src/components/mention_link/mention_link.vue | 115 ++++++++++++---------------
 src/components/notification/notification.js  |   4 +-
 src/components/notification/notification.vue |  36 +++------
 src/components/popover/popover.js            |   2 +-
 src/components/status/status.js              |   6 +-
 src/components/status/status.vue             |  43 +++-------
 src/components/user_popover/user_popover.js  |  14 ++++
 src/components/user_popover/user_popover.vue |  34 ++++++++
 9 files changed, 127 insertions(+), 130 deletions(-)
 create mode 100644 src/components/user_popover/user_popover.js
 create mode 100644 src/components/user_popover/user_popover.vue

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

diff --git a/src/components/mention_link/mention_link.js b/src/components/mention_link/mention_link.js
index 4b088f88..7e47625a 100644
--- a/src/components/mention_link/mention_link.js
+++ b/src/components/mention_link/mention_link.js
@@ -16,8 +16,7 @@ const MentionLink = {
   name: 'MentionLink',
   components: {
     UserAvatar,
-    Popover: defineAsyncComponent(() => import('../popover/popover.vue')),
-    UserCard: defineAsyncComponent(() => import('../user_card/user_card.vue'))
+    UserPopover: defineAsyncComponent(() => import('../user_popover/user_popover.vue'))
   },
   props: {
     url: {
diff --git a/src/components/mention_link/mention_link.vue b/src/components/mention_link/mention_link.vue
index 686ad27f..0cff50ab 100644
--- a/src/components/mention_link/mention_link.vue
+++ b/src/components/mention_link/mention_link.vue
@@ -10,84 +10,71 @@
       target="_blank"
       v-html="content"
     /><!-- eslint-enable vue/no-v-html -->
-    <Popover
-      trigger="click"
-      :bound-to="{ x: 'container'}"
-      bound-to-selector=".column"
-      popover-class="popover-default mention-popover"
+    <UserPopover
+      v-else
+      :userId="user.id"
       :disabled="!shouldShowTooltip"
     >
-      <template v-slot:trigger>
-        <span
-          v-if="user"
-          class="new"
-          :style="style"
-          :class="classnames"
+      <span
+        v-if="user"
+        class="new"
+        :style="style"
+        :class="classnames"
+      >
+        <a
+          class="short button-unstyled"
+          :class="{ '-with-tooltip': shouldShowTooltip }"
+          :href="url"
+          @click.prevent="onClick"
         >
-          <a
-            class="short button-unstyled"
-            :class="{ '-with-tooltip': shouldShowTooltip }"
-            :href="url"
-            @click.prevent="onClick"
+          <!-- eslint-disable vue/no-v-html -->
+          <UserAvatar
+            v-if="shouldShowAvatar"
+            class="mention-avatar"
+            :user="user"
+          /><span
+            class="shortName"
+          ><FAIcon
+            v-if="useAtIcon"
+            size="sm"
+            icon="at"
+            class="at"
+          />{{ !useAtIcon ? '@' : '' }}<span
+            class="userName"
+            v-html="userName"
+          /><span
+            v-if="shouldShowFullUserName"
+            class="serverName"
+            :class="{ '-faded': shouldFadeDomain }"
+            v-html="'@' + serverName"
+          />
+          </span>
+          <span
+            v-if="isYou && shouldShowYous"
+            :class="{ '-you': shouldBoldenYou }"
+          > {{ ' ' + $t('status.you') }}</span>
+          <!-- eslint-enable vue/no-v-html -->
+        </a><span
+          v-if="shouldShowTooltip"
+          class="full"
+        >
+          <span
+            class="userNameFull"
           >
             <!-- eslint-disable vue/no-v-html -->
-            <UserAvatar
-              v-if="shouldShowAvatar"
-              class="mention-avatar"
-              :user="user"
-            /><span
-              class="shortName"
-            ><FAIcon
-              v-if="useAtIcon"
-              size="sm"
-              icon="at"
-              class="at"
-            />{{ !useAtIcon ? '@' : '' }}<span
+            @<span
               class="userName"
               v-html="userName"
             /><span
-              v-if="shouldShowFullUserName"
               class="serverName"
               :class="{ '-faded': shouldFadeDomain }"
               v-html="'@' + serverName"
             />
-            </span>
-            <span
-              v-if="isYou && shouldShowYous"
-              :class="{ '-you': shouldBoldenYou }"
-            > {{ ' ' + $t('status.you') }}</span>
             <!-- eslint-enable vue/no-v-html -->
-          </a><span
-            v-if="shouldShowTooltip"
-            class="full"
-          >
-            <span
-              class="userNameFull"
-            >
-              <!-- eslint-disable vue/no-v-html -->
-              @<span
-                class="userName"
-                v-html="userName"
-              /><span
-                class="serverName"
-                :class="{ '-faded': shouldFadeDomain }"
-                v-html="'@' + serverName"
-              />
-              <!-- eslint-enable vue/no-v-html -->
-            </span>
           </span>
-        </span></template>
-      <template v-slot:content>
-        <UserCard
-          class="mention-link-popover"
-          :user-id="user.id"
-          :hide-bio="true"
-          :bordered="false"
-          :allow-zooming-avatar="true"
-          :rounded="true"
-        />
-      </template>
-    </Popover>
+        </span>
+      </span>
+    </UserPopover>
   </span>
 </template>
 
diff --git a/src/components/notification/notification.js b/src/components/notification/notification.js
index 9408b217..77cdfa73 100644
--- a/src/components/notification/notification.js
+++ b/src/components/notification/notification.js
@@ -5,7 +5,7 @@ import UserAvatar from '../user_avatar/user_avatar.vue'
 import UserCard from '../user_card/user_card.vue'
 import Timeago from '../timeago/timeago.vue'
 import RichContent from 'src/components/rich_content/rich_content.jsx'
-import Popover from '../popover/popover.vue'
+import UserPopover from '../user_popover/user_popover.vue'
 import { isStatusNotification } from '../../services/notification_utils/notification_utils.js'
 import { highlightClass, highlightStyle } from '../../services/user_highlighter/user_highlighter.js'
 import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
@@ -48,7 +48,7 @@ const Notification = {
     Timeago,
     Status,
     RichContent,
-    Popover
+    UserPopover
   },
   methods: {
     toggleUserExpanded () {
diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue
index a44481c9..6427d117 100644
--- a/src/components/notification/notification.vue
+++ b/src/components/notification/notification.vue
@@ -36,32 +36,18 @@
         :href="$router.resolve(userProfileLink).href"
         @click.prevent
       >
-        <Popover
-          trigger="click"
-          popover-class="popover-default user-popover"
-          :overlay-centers="true"
-          overlay-centers-selector=".user-info-avatar-link .Avatar"
+        <UserPopover
+          :userId="notification.from_profile.id"
+          :overlayCenters="true"
         >
-          <template v-slot:trigger>
-            <UserAvatar
-              class="post-avatar"
-              :bot="botIndicator"
-              :compact="true"
-              :better-shadow="betterShadow"
-              :user="notification.from_profile"
-            />
-          </template>
-          <template v-slot:content>
-            <UserCard
-              class="mention-link-popover"
-              :user-id="getUser(notification).id"
-              :hide-bio="true"
-              :bordered="false"
-              :allow-zooming-avatar="true"
-              :rounded="true"
-            />
-          </template>
-        </Popover>
+          <UserAvatar
+            class="post-avatar"
+            :bot="botIndicator"
+            :compact="true"
+            :better-shadow="betterShadow"
+            :user="notification.from_profile"
+          />
+        </UserPopover>
       </a>
       <div class="notification-right">
         <span class="notification-details">
diff --git a/src/components/popover/popover.js b/src/components/popover/popover.js
index 7f4c1cac..f6527624 100644
--- a/src/components/popover/popover.js
+++ b/src/components/popover/popover.js
@@ -80,7 +80,7 @@ const Popover = {
         y: anchorScreenBox.top + anchorHeight * 0.5
       }
       const content = this.$refs.content
-      const overlayCenter = this.overlayCentersSelector
+      const overlayCenter = this.overlayCenters
         ? this.$refs.content.querySelector(this.overlayCentersSelector)
         : null
 
diff --git a/src/components/status/status.js b/src/components/status/status.js
index 06496258..053c9441 100644
--- a/src/components/status/status.js
+++ b/src/components/status/status.js
@@ -4,14 +4,13 @@ import ReactButton from '../react_button/react_button.vue'
 import RetweetButton from '../retweet_button/retweet_button.vue'
 import ExtraButtons from '../extra_buttons/extra_buttons.vue'
 import PostStatusForm from '../post_status_form/post_status_form.vue'
-import UserCard from '../user_card/user_card.vue'
 import UserAvatar from '../user_avatar/user_avatar.vue'
 import AvatarList from '../avatar_list/avatar_list.vue'
 import Timeago from '../timeago/timeago.vue'
 import StatusContent from '../status_content/status_content.vue'
 import RichContent from 'src/components/rich_content/rich_content.jsx'
 import StatusPopover from '../status_popover/status_popover.vue'
-import Popover from '../popover/popover.vue'
+import UserPopover from '../user_popover/user_popover.vue'
 import UserListPopover from '../user_list_popover/user_list_popover.vue'
 import EmojiReactions from '../emoji_reactions/emoji_reactions.vue'
 import MentionsLine from 'src/components/mentions_line/mentions_line.vue'
@@ -106,7 +105,6 @@ const Status = {
     RetweetButton,
     ExtraButtons,
     PostStatusForm,
-    UserCard,
     UserAvatar,
     AvatarList,
     Timeago,
@@ -117,7 +115,7 @@ const Status = {
     RichContent,
     MentionLink,
     MentionsLine,
-    Popover
+    UserPopover
   },
   props: [
     'statusoid',
diff --git a/src/components/status/status.vue b/src/components/status/status.vue
index 624960fe..771d336a 100644
--- a/src/components/status/status.vue
+++ b/src/components/status/status.vue
@@ -123,42 +123,21 @@
           class="left-side"
         >
           <a :href="$router.resolve(userProfileLink).href" @click.prevent>
-            <Popover
-              trigger="click"
-              popover-class="popover-default user-popover"
-              :overlay-centers="true"
-              overlay-centers-selector=".user-info-avatar-link .Avatar"
+            <UserPopover
+              :userId="status.user.id"
+              :overlayCenters="true"
             >
-              <template v-slot:trigger>
-                <UserAvatar
-                  class="post-avatar"
-                  :bot="botIndicator"
-                  :compact="compact"
-                  :better-shadow="betterShadow"
-                  :user="status.user"
-                />
-              </template>
-              <template v-slot:content>
-                <UserCard
-                  class="mention-link-popover"
-                  :user-id="status.user.id"
-                  :hide-bio="true"
-                  :bordered="false"
-                  :allow-zooming-avatar="true"
-                  :rounded="true"
-                />
-              </template>
-            </Popover>
+              <UserAvatar
+                class="post-avatar"
+                :bot="botIndicator"
+                :compact="compact"
+                :better-shadow="betterShadow"
+                :user="status.user"
+              />
+            </UserPopover>
           </a>
         </div>
         <div class="right-side">
-          <UserCard
-            v-if="userExpanded"
-            :user-id="status.user.id"
-            :rounded="true"
-            :bordered="true"
-            class="usercard"
-          />
           <div
             v-if="!noHeading"
             class="status-heading"
diff --git a/src/components/user_popover/user_popover.js b/src/components/user_popover/user_popover.js
new file mode 100644
index 00000000..bffd5962
--- /dev/null
+++ b/src/components/user_popover/user_popover.js
@@ -0,0 +1,14 @@
+import { defineAsyncComponent } from 'vue'
+
+const UserPopover = {
+  name: 'UserPopover',
+  props: [
+    'userId', 'overlayCenters', 'disabled'
+  ],
+  components: {
+    UserCard: defineAsyncComponent(() => import('../user_card/user_card.vue')),
+    Popover: defineAsyncComponent(() => import('../popover/popover.vue'))
+  }
+}
+
+export default UserPopover
diff --git a/src/components/user_popover/user_popover.vue b/src/components/user_popover/user_popover.vue
new file mode 100644
index 00000000..7ad5c234
--- /dev/null
+++ b/src/components/user_popover/user_popover.vue
@@ -0,0 +1,34 @@
+<template>
+<Popover
+  trigger="click"
+  popover-class="popover-default user-popover"
+  overlay-centers-selector=".user-info-avatar-link .Avatar"
+  :overlay-centers="overlayCenters"
+  :disabled="disabled"
+>
+  <template v-slot:trigger>
+    <slot />
+  </template>
+  <template v-slot:content>
+    <UserCard
+      class="user-popover"
+      :user-id="userId"
+      :hide-bio="true"
+      :bordered="false"
+      :allow-zooming-avatar="true"
+      :rounded="true"
+    />
+  </template>
+</Popover>
+</template>
+
+<script src="./user_popover.js" ></script>
+
+<style lang="scss">
+@import '../../_variables.scss';
+
+/* popover styles load on-demand, so we need to override */
+.user-popover.popover {
+}
+
+</style>
-- 
cgit v1.2.3-70-g09d2


From fddb531ed20b31c44e6911418e7bbb884836c40a Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Sun, 31 Jul 2022 12:35:48 +0300
Subject: --fix

---
 src/App.vue                                        | 20 ++++--
 src/boot/after_store.js                            |  4 +-
 src/boot/routes.js                                 |  9 ++-
 src/components/about/about.vue                     |  2 +-
 src/components/account_actions/account_actions.vue |  4 +-
 src/components/avatar_list/avatar_list.vue         |  2 +-
 src/components/basic_user_card/basic_user_card.vue | 11 ++--
 src/components/chat/chat.js                        |  2 +-
 src/components/chat_list/chat_list.vue             |  2 +-
 src/components/chat_message/chat_message.vue       | 10 +--
 src/components/chat_title/chat_title.vue           |  4 +-
 src/components/checkbox/checkbox.vue               |  4 +-
 src/components/color_input/color_input.vue         |  2 +-
 src/components/conversation/conversation.js        |  2 +-
 src/components/conversation/conversation.vue       |  2 +-
 src/components/desktop_nav/desktop_nav.js          | 24 +++++---
 .../domain_mute_card/domain_mute_card.vue          |  4 +-
 src/components/emoji_input/emoji_input.js          |  2 +-
 src/components/emoji_picker/emoji_picker.js        |  2 +-
 src/components/emoji_reactions/emoji_reactions.vue |  2 +-
 src/components/extra_buttons/extra_buttons.js      |  2 +-
 src/components/extra_buttons/extra_buttons.vue     |  6 +-
 src/components/favorite_button/favorite_button.vue |  2 +-
 src/components/features_panel/features_panel.vue   |  2 +-
 src/components/flash/flash.js                      |  2 +-
 src/components/font_control/font_control.vue       |  2 +-
 src/components/hashtag_link/hashtag_link.vue       |  4 +-
 src/components/image_cropper/image_cropper.js      |  2 +-
 .../instance_specific_panel.vue                    |  2 +-
 src/components/interactions/interactions.js        |  2 +-
 .../interface_language_switcher.vue                |  1 +
 src/components/login_form/login_form.js            |  2 +-
 src/components/login_form/login_form.vue           |  2 +-
 src/components/media_upload/media_upload.js        |  5 +-
 src/components/media_upload/media_upload.vue       |  2 +-
 src/components/mention_link/mention_link.vue       | 17 ++---
 src/components/mentions_line/mentions_line.vue     | 14 ++---
 src/components/mfa_form/recovery_form.vue          |  2 +-
 src/components/mobile_nav/mobile_nav.vue           |  5 +-
 src/components/modal/modal.vue                     |  8 +--
 .../moderation_tools/moderation_tools.vue          |  8 +--
 .../mrf_transparency_panel.js                      |  6 +-
 src/components/nav_panel/nav_panel.vue             |  2 +-
 src/components/notification/notification.js        |  2 +-
 src/components/notification/notification.vue       |  4 +-
 .../notifications/notification_filters.vue         |  4 +-
 src/components/notifications/notifications.vue     |  5 +-
 src/components/popover/popover.js                  | 34 +++++-----
 .../post_status_form/post_status_form.js           | 16 ++---
 src/components/react_button/react_button.js        |  2 +-
 src/components/react_button/react_button.vue       |  8 +--
 src/components/remote_follow/remote_follow.js      |  2 +-
 src/components/retweet_button/retweet_button.vue   |  2 +-
 src/components/search_bar/search_bar.js            |  2 +-
 src/components/selectable_list/selectable_list.vue |  4 +-
 .../settings_modal/helpers/modified_indicator.vue  |  4 +-
 .../helpers/server_side_indicator.vue              |  4 +-
 src/components/settings_modal/settings_modal.vue   |  4 +-
 src/components/settings_modal/tabs/general_tab.vue | 10 ++-
 .../settings_modal/tabs/mutes_and_blocks_tab.vue   | 34 +++++-----
 src/components/settings_modal/tabs/profile_tab.js  | 10 +--
 src/components/settings_modal/tabs/profile_tab.vue |  2 +-
 .../settings_modal/tabs/security_tab/mfa.js        |  6 +-
 .../settings_modal/tabs/security_tab/mfa_totp.js   |  2 +-
 .../tabs/security_tab/security_tab.js              |  2 +-
 .../settings_modal/tabs/theme_tab/preview.vue      |  5 +-
 .../settings_modal/tabs/theme_tab/theme_tab.js     |  8 +--
 src/components/shadow_control/shadow_control.js    |  8 ++-
 src/components/shadow_control/shadow_control.vue   |  2 +-
 src/components/shout_panel/shout_panel.js          |  2 +-
 src/components/side_drawer/side_drawer.js          |  2 +-
 src/components/side_drawer/side_drawer.vue         |  2 +-
 src/components/staff_panel/staff_panel.js          |  4 +-
 src/components/staff_panel/staff_panel.vue         |  2 +-
 src/components/status/status.js                    |  6 +-
 src/components/status/status.vue                   | 11 ++--
 src/components/status_body/status_body.vue         |  2 +-
 src/components/status_content/status_content.vue   |  2 +-
 src/components/status_popover/status_popover.vue   |  8 +--
 src/components/sticker_picker/sticker_picker.js    |  4 +-
 .../terms_of_service_panel.vue                     |  2 +-
 src/components/timeline/timeline.vue               |  5 +-
 .../timeline/timeline_quick_settings.vue           |  4 +-
 src/components/timeline_menu/timeline_menu.js      |  6 +-
 src/components/timeline_menu/timeline_menu.vue     |  6 +-
 .../timeline_menu/timeline_menu_content.vue        |  2 +-
 src/components/user_card/user_card.js              |  2 +-
 src/components/user_card/user_card.vue             |  2 +-
 .../user_list_popover/user_list_popover.vue        |  6 +-
 src/components/user_popover/user_popover.vue       | 42 ++++++-------
 src/components/user_profile/user_profile.vue       | 15 +++--
 .../user_reporting_modal/user_reporting_modal.vue  |  2 +-
 src/components/who_to_follow/who_to_follow.js      |  2 +-
 .../who_to_follow_panel/who_to_follow_panel.js     | 10 +--
 .../who_to_follow_panel/who_to_follow_panel.vue    |  2 +-
 src/i18n/messages.js                               |  2 +-
 src/lib/notification-i18n-loader.js                |  4 +-
 src/lib/persisted_state.js                         | 12 ++--
 src/modules/api.js                                 |  4 +-
 src/modules/config.js                              |  2 +-
 src/modules/errors.js                              |  4 +-
 src/modules/serverSideConfig.js                    | 28 ++++-----
 src/modules/statuses.js                            | 20 +++---
 src/modules/users.js                               | 24 ++++----
 src/services/api/api.service.js                    | 72 +++++++++++-----------
 src/services/chat_service/chat_service.js          | 12 ++--
 src/services/chat_utils/chat_utils.js              |  2 +-
 src/services/color_convert/color_convert.js        | 12 ++--
 src/services/completion/completion.js              |  2 +-
 src/services/date_utils/date_utils.js              |  2 +-
 .../entity_normalizer/entity_normalizer.service.js |  4 +-
 src/services/file_size_format/file_size_format.js  |  8 +--
 .../html_converter/html_line_converter.service.js  |  4 +-
 src/services/html_converter/utility.service.js     |  2 +-
 src/services/locale/locale.service.js              | 14 ++---
 src/services/new_api/password_reset.js             |  2 +-
 .../notifications_fetcher.service.js               | 12 ++--
 src/services/push/push.js                          |  4 +-
 src/services/theme_data/theme_data.service.js      |  2 +-
 .../timeline_fetcher/timeline_fetcher.service.js   | 16 ++---
 src/services/user_highlighter/user_highlighter.js  |  2 +-
 src/sw.js                                          |  4 +-
 test/e2e/custom-assertions/elementCount.js         |  2 +-
 test/e2e/nightwatch.conf.js                        | 54 ++++++++--------
 test/e2e/runner.js                                 |  8 +--
 test/unit/karma.conf.js                            | 14 ++---
 test/unit/specs/components/emoji_input.spec.js     |  2 +-
 test/unit/specs/components/rich_content.spec.js    |  2 +-
 test/unit/specs/components/user_profile.spec.js    |  6 +-
 test/unit/specs/modules/statuses.spec.js           |  4 +-
 .../services/chat_service/chat_service.spec.js     | 24 ++++----
 .../entity_normalizer/entity_normalizer.spec.js    |  8 +--
 .../file_size_format/file_size_format.spec.js      |  4 +-
 133 files changed, 508 insertions(+), 449 deletions(-)

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

diff --git a/src/App.vue b/src/App.vue
index 7d4a8e1e..0efadaf0 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -15,8 +15,12 @@
       class="app-layout container"
       :class="classes"
     >
-      <div class="underlay"/>
-      <div id="sidebar" class="column -scrollable" :class="{ '-show-scrollbar': showScrollbars }">
+      <div class="underlay" />
+      <div
+        id="sidebar"
+        class="column -scrollable"
+        :class="{ '-show-scrollbar': showScrollbars }"
+      >
         <user-panel />
         <template v-if="layoutType !== 'mobile'">
           <nav-panel />
@@ -26,7 +30,11 @@
           <div id="notifs-sidebar" />
         </template>
       </div>
-      <div id="main-scroller" class="column main" :class="{ '-full-height': isChats }">
+      <div
+        id="main-scroller"
+        class="column main"
+        :class="{ '-full-height': isChats }"
+      >
         <div
           v-if="!currentUser"
           class="login-hint panel panel-default"
@@ -40,7 +48,11 @@
         </div>
         <router-view />
       </div>
-      <div id="notifs-column" class="column -scrollable" :class="{ '-show-scrollbar': showScrollbars }"/>
+      <div
+        id="notifs-column"
+        class="column -scrollable"
+        :class="{ '-show-scrollbar': showScrollbars }"
+      />
     </div>
     <MediaModal />
     <shout-panel
diff --git a/src/boot/after_store.js b/src/boot/after_store.js
index 894a68e1..23b68e83 100644
--- a/src/boot/after_store.js
+++ b/src/boot/after_store.js
@@ -156,7 +156,7 @@ const setSettings = async ({ apiConfig, staticConfig, store }) => {
   copyInstanceOption('hideSitename')
   copyInstanceOption('sidebarRight')
 
-  return store.dispatch('setTheme', config['theme'])
+  return store.dispatch('setTheme', config.theme)
 }
 
 const getTOS = async ({ store }) => {
@@ -197,7 +197,7 @@ const getStickers = async ({ store }) => {
       const stickers = (await Promise.all(
         Object.entries(values).map(async ([name, path]) => {
           const resPack = await window.fetch(path + 'pack.json')
-          var meta = {}
+          let meta = {}
           if (resPack.ok) {
             meta = await resPack.json()
           }
diff --git a/src/boot/routes.js b/src/boot/routes.js
index 726476a8..c8194d5f 100644
--- a/src/boot/routes.js
+++ b/src/boot/routes.js
@@ -31,7 +31,8 @@ export default (store) => {
   }
 
   let routes = [
-    { name: 'root',
+    {
+      name: 'root',
       path: '/',
       redirect: _to => {
         return (store.state.users.currentUser
@@ -45,12 +46,14 @@ export default (store) => {
     { name: 'tag-timeline', path: '/tag/:tag', component: TagTimeline },
     { name: 'bookmarks', path: '/bookmarks', component: BookmarkTimeline },
     { name: 'conversation', path: '/notice/:id', component: ConversationPage, meta: { dontScroll: true } },
-    { name: 'remote-user-profile-acct',
+    {
+      name: 'remote-user-profile-acct',
       path: '/remote-users/:_(@)?:username([^/@]+)@:hostname([^/@]+)',
       component: RemoteUserResolver,
       beforeEnter: validateAuthenticatedRoute
     },
-    { name: 'remote-user-profile',
+    {
+      name: 'remote-user-profile',
       path: '/remote-users/:hostname/:username',
       component: RemoteUserResolver,
       beforeEnter: validateAuthenticatedRoute
diff --git a/src/components/about/about.vue b/src/components/about/about.vue
index 5d5d6479..33586c97 100644
--- a/src/components/about/about.vue
+++ b/src/components/about/about.vue
@@ -8,7 +8,7 @@
   </div>
 </template>
 
-<script src="./about.js" ></script>
+<script src="./about.js"></script>
 
 <style lang="scss">
 </style>
diff --git a/src/components/account_actions/account_actions.vue b/src/components/account_actions/account_actions.vue
index c35d01af..23547f2c 100644
--- a/src/components/account_actions/account_actions.vue
+++ b/src/components/account_actions/account_actions.vue
@@ -6,7 +6,7 @@
       :bound-to="{ x: 'container' }"
       remove-padding
     >
-      <template v-slot:content>
+      <template #content>
         <div class="dropdown-menu">
           <template v-if="relationship.following">
             <button
@@ -57,7 +57,7 @@
           </button>
         </div>
       </template>
-      <template v-slot:trigger>
+      <template #trigger>
         <button class="button-unstyled ellipsis-button">
           <FAIcon
             class="icon"
diff --git a/src/components/avatar_list/avatar_list.vue b/src/components/avatar_list/avatar_list.vue
index e1b6e971..9a6ca3f6 100644
--- a/src/components/avatar_list/avatar_list.vue
+++ b/src/components/avatar_list/avatar_list.vue
@@ -14,7 +14,7 @@
   </div>
 </template>
 
-<script src="./avatar_list.js" ></script>
+<script src="./avatar_list.js"></script>
 
 <style lang="scss">
 @import '../../_variables.scss';
diff --git a/src/components/basic_user_card/basic_user_card.vue b/src/components/basic_user_card/basic_user_card.vue
index effd9268..9cca7840 100644
--- a/src/components/basic_user_card/basic_user_card.vue
+++ b/src/components/basic_user_card/basic_user_card.vue
@@ -1,10 +1,13 @@
 <template>
   <div class="basic-user-card">
-    <router-link @click.prevent :to="userProfileLink(user)">
+    <router-link
+      :to="userProfileLink(user)"
+      @click.prevent
+    >
       <UserPopover
-        :userId="user.id"
-        :overlayCenters="true"
-        overlayCentersSelector=".avatar"
+        :user-id="user.id"
+        :overlay-centers="true"
+        overlay-centers-selector=".avatar"
       >
         <UserAvatar
           class="user-avatar avatar"
diff --git a/src/components/chat/chat.js b/src/components/chat/chat.js
index 9f6e64e3..5a5c37b6 100644
--- a/src/components/chat/chat.js
+++ b/src/components/chat/chat.js
@@ -107,7 +107,7 @@ const Chat = {
         }
       })
     },
-    '$route': function () {
+    $route: function () {
       this.startFetching()
     },
     mastoUserSocketStatus (newValue) {
diff --git a/src/components/chat_list/chat_list.vue b/src/components/chat_list/chat_list.vue
index 58e8d0b3..1248c4c8 100644
--- a/src/components/chat_list/chat_list.vue
+++ b/src/components/chat_list/chat_list.vue
@@ -23,7 +23,7 @@
         class="timeline"
       >
         <List :items="sortedChatList">
-          <template v-slot:item="{item}">
+          <template #item="{item}">
             <ChatListItem
               :key="item.id"
               :compact="false"
diff --git a/src/components/chat_message/chat_message.vue b/src/components/chat_message/chat_message.vue
index 9b823f7d..d635c47e 100644
--- a/src/components/chat_message/chat_message.vue
+++ b/src/components/chat_message/chat_message.vue
@@ -16,7 +16,7 @@
       >
         <UserPopover
           v-if="chatViewItem.isHead"
-          :userId="author.id"
+          :user-id="author.id"
         >
           <UserAvatar
             :compact="true"
@@ -50,7 +50,7 @@
                 @show="menuOpened = true"
                 @close="menuOpened = false"
               >
-                <template v-slot:content>
+                <template #content>
                   <div class="dropdown-menu">
                     <button
                       class="button-default dropdown-item dropdown-item-icon"
@@ -60,7 +60,7 @@
                     </button>
                   </div>
                 </template>
-                <template v-slot:trigger>
+                <template #trigger>
                   <button
                     class="button-default menu-icon"
                     :title="$t('chats.more')"
@@ -75,7 +75,7 @@
               :status="messageForStatusContent"
               :full-content="true"
             >
-              <template v-slot:footer>
+              <template #footer>
                 <span
                   class="created-at"
                 >
@@ -96,7 +96,7 @@
   </div>
 </template>
 
-<script src="./chat_message.js" ></script>
+<script src="./chat_message.js"></script>
 <style lang="scss">
 @import './chat_message.scss';
 
diff --git a/src/components/chat_title/chat_title.vue b/src/components/chat_title/chat_title.vue
index 22d0e7c4..ab7491fa 100644
--- a/src/components/chat_title/chat_title.vue
+++ b/src/components/chat_title/chat_title.vue
@@ -4,9 +4,9 @@
     :title="title"
   >
     <UserPopover
-      class="avatar-container"
       v-if="withAvatar && user"
-      :userId="user.id"
+      class="avatar-container"
+      :user-id="user.id"
     >
       <UserAvatar
         class="titlebar-avatar"
diff --git a/src/components/checkbox/checkbox.vue b/src/components/checkbox/checkbox.vue
index 83695912..b6768d67 100644
--- a/src/components/checkbox/checkbox.vue
+++ b/src/components/checkbox/checkbox.vue
@@ -22,12 +22,12 @@
 
 <script>
 export default {
-  emits: ['update:modelValue'],
   props: [
     'modelValue',
     'indeterminate',
     'disabled'
-  ]
+  ],
+  emits: ['update:modelValue']
 }
 </script>
 
diff --git a/src/components/color_input/color_input.vue b/src/components/color_input/color_input.vue
index e84603c3..dfc084f9 100644
--- a/src/components/color_input/color_input.vue
+++ b/src/components/color_input/color_input.vue
@@ -46,7 +46,6 @@
     </div>
   </div>
 </template>
-<style lang="scss" src="./color_input.scss"></style>
 <script>
 import Checkbox from '../checkbox/checkbox.vue'
 import { hex2rgb } from '../../services/color_convert/color_convert.js'
@@ -108,6 +107,7 @@ export default {
   }
 }
 </script>
+<style lang="scss" src="./color_input.scss"></style>
 
 <style lang="scss">
 .color-control {
diff --git a/src/components/conversation/conversation.js b/src/components/conversation/conversation.js
index 2ef2977a..3b540cac 100644
--- a/src/components/conversation/conversation.js
+++ b/src/components/conversation/conversation.js
@@ -271,7 +271,7 @@ const conversation = {
           result[irid] = result[irid] || []
           result[irid].push({
             name: `#${i}`,
-            id: id
+            id
           })
         }
         i++
diff --git a/src/components/conversation/conversation.vue b/src/components/conversation/conversation.vue
index 6088e1ca..1adbe250 100644
--- a/src/components/conversation/conversation.vue
+++ b/src/components/conversation/conversation.vue
@@ -31,8 +31,8 @@
             keypath="status.show_all_conversation_with_icon"
             tag="button"
             class="button-unstyled -link"
-            @click.prevent="diveToTopLevel"
             scope="global"
+            @click.prevent="diveToTopLevel"
           >
             <template #icon>
               <FAIcon
diff --git a/src/components/desktop_nav/desktop_nav.js b/src/components/desktop_nav/desktop_nav.js
index e048f53d..08c0e44e 100644
--- a/src/components/desktop_nav/desktop_nav.js
+++ b/src/components/desktop_nav/desktop_nav.js
@@ -46,23 +46,27 @@ export default {
     enableMask () { return this.supportsMask && this.$store.state.instance.logoMask },
     logoStyle () {
       return {
-        'visibility': this.enableMask ? 'hidden' : 'visible'
+        visibility: this.enableMask ? 'hidden' : 'visible'
       }
     },
     logoMaskStyle () {
-      return this.enableMask ? {
-        'mask-image': `url(${this.$store.state.instance.logo})`
-      } : {
-        'background-color': this.enableMask ? '' : 'transparent'
-      }
+      return this.enableMask
+        ? {
+            'mask-image': `url(${this.$store.state.instance.logo})`
+          }
+        : {
+            'background-color': this.enableMask ? '' : 'transparent'
+          }
     },
     logoBgStyle () {
       return Object.assign({
-        'margin': `${this.$store.state.instance.logoMargin} 0`,
+        margin: `${this.$store.state.instance.logoMargin} 0`,
         opacity: this.searchBarHidden ? 1 : 0
-      }, this.enableMask ? {} : {
-        'background-color': this.enableMask ? '' : 'transparent'
-      })
+      }, this.enableMask
+        ? {}
+        : {
+            'background-color': this.enableMask ? '' : 'transparent'
+          })
     },
     logo () { return this.$store.state.instance.logo },
     sitename () { return this.$store.state.instance.name },
diff --git a/src/components/domain_mute_card/domain_mute_card.vue b/src/components/domain_mute_card/domain_mute_card.vue
index 836688aa..28c61631 100644
--- a/src/components/domain_mute_card/domain_mute_card.vue
+++ b/src/components/domain_mute_card/domain_mute_card.vue
@@ -9,7 +9,7 @@
       class="btn button-default"
     >
       {{ $t('domain_mute_card.unmute') }}
-      <template v-slot:progress>
+      <template #progress>
         {{ $t('domain_mute_card.unmute_progress') }}
       </template>
     </ProgressButton>
@@ -19,7 +19,7 @@
       class="btn button-default"
     >
       {{ $t('domain_mute_card.mute') }}
-      <template v-slot:progress>
+      <template #progress>
         {{ $t('domain_mute_card.mute_progress') }}
       </template>
     </ProgressButton>
diff --git a/src/components/emoji_input/emoji_input.js b/src/components/emoji_input/emoji_input.js
index 391cc5b5..5ba3907f 100644
--- a/src/components/emoji_input/emoji_input.js
+++ b/src/components/emoji_input/emoji_input.js
@@ -321,7 +321,7 @@ const EmojiInput = {
       }
     },
     scrollIntoView () {
-      const rootRef = this.$refs['picker'].$el
+      const rootRef = this.$refs.picker.$el
       /* Scroller is either `window` (replies in TL), sidebar (main post form,
        * replies in notifs) or mobile post form. Note that getting and setting
        * scroll is different for `Window` and `Element`s
diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js
index bd5c2e39..f6920208 100644
--- a/src/components/emoji_picker/emoji_picker.js
+++ b/src/components/emoji_picker/emoji_picker.js
@@ -25,7 +25,7 @@ const filterByKeyword = (list, keyword = '') => {
   if (keyword === '') return list
 
   const keywordLowercase = keyword.toLowerCase()
-  let orderedEmojiList = []
+  const orderedEmojiList = []
   for (const emoji of list) {
     const indexOfKeyword = emoji.displayText.toLowerCase().indexOf(keywordLowercase)
     if (indexOfKeyword > -1) {
diff --git a/src/components/emoji_reactions/emoji_reactions.vue b/src/components/emoji_reactions/emoji_reactions.vue
index 51d50359..4ea8b6a2 100644
--- a/src/components/emoji_reactions/emoji_reactions.vue
+++ b/src/components/emoji_reactions/emoji_reactions.vue
@@ -26,7 +26,7 @@
   </div>
 </template>
 
-<script src="./emoji_reactions.js" ></script>
+<script src="./emoji_reactions.js"></script>
 <style lang="scss">
 @import '../../_variables.scss';
 
diff --git a/src/components/extra_buttons/extra_buttons.js b/src/components/extra_buttons/extra_buttons.js
index 2f534896..22ffb65a 100644
--- a/src/components/extra_buttons/extra_buttons.js
+++ b/src/components/extra_buttons/extra_buttons.js
@@ -25,7 +25,7 @@ library.add(
 )
 
 const ExtraButtons = {
-  props: [ 'status' ],
+  props: ['status'],
   components: { Popover },
   methods: {
     deleteStatus () {
diff --git a/src/components/extra_buttons/extra_buttons.vue b/src/components/extra_buttons/extra_buttons.vue
index 2ea86201..2c893bf3 100644
--- a/src/components/extra_buttons/extra_buttons.vue
+++ b/src/components/extra_buttons/extra_buttons.vue
@@ -7,7 +7,7 @@
     :bound-to="{ x: 'container' }"
     remove-padding
   >
-    <template v-slot:content="{close}">
+    <template #content="{close}">
       <div class="dropdown-menu">
         <button
           v-if="canMute && !status.thread_muted"
@@ -120,7 +120,7 @@
         </button>
       </div>
     </template>
-    <template v-slot:trigger>
+    <template #trigger>
       <span class="button-unstyled popover-trigger">
         <FAIcon
           class="fa-scale-110 fa-old-padding"
@@ -131,7 +131,7 @@
   </Popover>
 </template>
 
-<script src="./extra_buttons.js" ></script>
+<script src="./extra_buttons.js"></script>
 
 <style lang="scss">
 @import '../../_variables.scss';
diff --git a/src/components/favorite_button/favorite_button.vue b/src/components/favorite_button/favorite_button.vue
index dce25e24..d5c4c61e 100644
--- a/src/components/favorite_button/favorite_button.vue
+++ b/src/components/favorite_button/favorite_button.vue
@@ -29,7 +29,7 @@
   </div>
 </template>
 
-<script src="./favorite_button.js" ></script>
+<script src="./favorite_button.js"></script>
 
 <style lang="scss">
 @import '../../_variables.scss';
diff --git a/src/components/features_panel/features_panel.vue b/src/components/features_panel/features_panel.vue
index a58a99af..4cdf56d0 100644
--- a/src/components/features_panel/features_panel.vue
+++ b/src/components/features_panel/features_panel.vue
@@ -32,7 +32,7 @@
   </div>
 </template>
 
-<script src="./features_panel.js" ></script>
+<script src="./features_panel.js"></script>
 
 <style lang="scss">
   .features-panel li {
diff --git a/src/components/flash/flash.js b/src/components/flash/flash.js
index 87f940a7..87c1d650 100644
--- a/src/components/flash/flash.js
+++ b/src/components/flash/flash.js
@@ -11,7 +11,7 @@ library.add(
 )
 
 const Flash = {
-  props: [ 'src' ],
+  props: ['src'],
   data () {
     return {
       player: false, // can be true, "hidden", false. hidden = element exists
diff --git a/src/components/font_control/font_control.vue b/src/components/font_control/font_control.vue
index f100c3a9..83c1cef7 100644
--- a/src/components/font_control/font_control.vue
+++ b/src/components/font_control/font_control.vue
@@ -47,7 +47,7 @@
   </div>
 </template>
 
-<script src="./font_control.js" ></script>
+<script src="./font_control.js"></script>
 
 <style lang="scss">
 @import '../../_variables.scss';
diff --git a/src/components/hashtag_link/hashtag_link.vue b/src/components/hashtag_link/hashtag_link.vue
index 918ed26b..596851b9 100644
--- a/src/components/hashtag_link/hashtag_link.vue
+++ b/src/components/hashtag_link/hashtag_link.vue
@@ -14,6 +14,6 @@
   </span>
 </template>
 
-<script src="./hashtag_link.js"/>
+<script src="./hashtag_link.js" />
 
-<style lang="scss" src="./hashtag_link.scss"/>
+<style lang="scss" src="./hashtag_link.scss" />
diff --git a/src/components/image_cropper/image_cropper.js b/src/components/image_cropper/image_cropper.js
index 05f6fd4c..55e901a0 100644
--- a/src/components/image_cropper/image_cropper.js
+++ b/src/components/image_cropper/image_cropper.js
@@ -95,7 +95,7 @@ const ImageCropper = {
       const fileInput = this.$refs.input
       if (fileInput.files != null && fileInput.files[0] != null) {
         this.file = fileInput.files[0]
-        let reader = new window.FileReader()
+        const reader = new window.FileReader()
         reader.onload = (e) => {
           this.dataUrl = e.target.result
           this.$emit('open')
diff --git a/src/components/instance_specific_panel/instance_specific_panel.vue b/src/components/instance_specific_panel/instance_specific_panel.vue
index 7448ca06..c8ed0a2d 100644
--- a/src/components/instance_specific_panel/instance_specific_panel.vue
+++ b/src/components/instance_specific_panel/instance_specific_panel.vue
@@ -10,4 +10,4 @@
   </div>
 </template>
 
-<script src="./instance_specific_panel.js" ></script>
+<script src="./instance_specific_panel.js"></script>
diff --git a/src/components/interactions/interactions.js b/src/components/interactions/interactions.js
index c5ceb63d..cc6a15e1 100644
--- a/src/components/interactions/interactions.js
+++ b/src/components/interactions/interactions.js
@@ -12,7 +12,7 @@ const Interactions = {
   data () {
     return {
       allowFollowingMove: this.$store.state.users.currentUser.allow_following_move,
-      filterMode: tabModeDict['mentions']
+      filterMode: tabModeDict.mentions
     }
   },
   methods: {
diff --git a/src/components/interface_language_switcher/interface_language_switcher.vue b/src/components/interface_language_switcher/interface_language_switcher.vue
index 7ad1fe2e..6997f149 100644
--- a/src/components/interface_language_switcher/interface_language_switcher.vue
+++ b/src/components/interface_language_switcher/interface_language_switcher.vue
@@ -25,6 +25,7 @@ import Select from '../select/select.vue'
 
 export default {
   components: {
+    // eslint-disable-next-line vue/no-reserved-component-names
     Select
   },
   props: {
diff --git a/src/components/login_form/login_form.js b/src/components/login_form/login_form.js
index 638bd812..b795640e 100644
--- a/src/components/login_form/login_form.js
+++ b/src/components/login_form/login_form.js
@@ -83,7 +83,7 @@ const LoginForm = {
     },
     clearError () { this.error = false },
     focusOnPasswordInput () {
-      let passwordInput = this.$refs.passwordInput
+      const passwordInput = this.$refs.passwordInput
       passwordInput.focus()
       passwordInput.setSelectionRange(0, passwordInput.value.length)
     }
diff --git a/src/components/login_form/login_form.vue b/src/components/login_form/login_form.vue
index 21482977..7a430c51 100644
--- a/src/components/login_form/login_form.vue
+++ b/src/components/login_form/login_form.vue
@@ -90,7 +90,7 @@
   </div>
 </template>
 
-<script src="./login_form.js" ></script>
+<script src="./login_form.js"></script>
 
 <style lang="scss">
 @import '../../_variables.scss';
diff --git a/src/components/media_upload/media_upload.js b/src/components/media_upload/media_upload.js
index 669d8190..cfd42d4c 100644
--- a/src/components/media_upload/media_upload.js
+++ b/src/components/media_upload/media_upload.js
@@ -42,7 +42,8 @@ const mediaUpload = {
         .then((fileData) => {
           self.$emit('uploaded', fileData)
           self.decreaseUploadCount()
-        }, (error) => { // eslint-disable-line handle-callback-err
+        }, (error) => {
+          console.error('Error uploading file', error)
           self.$emit('upload-failed', 'default')
           self.decreaseUploadCount()
         })
@@ -73,7 +74,7 @@ const mediaUpload = {
     'disabled'
   ],
   watch: {
-    'dropFiles': function (fileInfos) {
+    dropFiles: function (fileInfos) {
       if (!this.uploading) {
         this.multiUpload(fileInfos)
       }
diff --git a/src/components/media_upload/media_upload.vue b/src/components/media_upload/media_upload.vue
index 7cc59f5a..a538a5ed 100644
--- a/src/components/media_upload/media_upload.vue
+++ b/src/components/media_upload/media_upload.vue
@@ -26,7 +26,7 @@
   </label>
 </template>
 
-<script src="./media_upload.js" ></script>
+<script src="./media_upload.js"></script>
 
 <style lang="scss">
 @import '../../_variables.scss';
diff --git a/src/components/mention_link/mention_link.vue b/src/components/mention_link/mention_link.vue
index 56da8e0f..3af502ef 100644
--- a/src/components/mention_link/mention_link.vue
+++ b/src/components/mention_link/mention_link.vue
@@ -12,7 +12,7 @@
     /><!-- eslint-enable vue/no-v-html -->
     <UserPopover
       v-else
-      :userId="user.id"
+      :user-id="user.id"
       :disabled="!shouldShowTooltip"
     >
       <span
@@ -54,16 +54,19 @@
             :class="{ '-you': shouldBoldenYou }"
           > {{ ' ' + $t('status.you') }}</span>
           <!-- eslint-enable vue/no-v-html -->
-        </a><span class="full" ref="full">
-            <!-- eslint-disable vue/no-v-html -->
-            @<span v-html="userName" /><span v-html="'@' + serverName" />
-            <!-- eslint-enable vue/no-v-html -->
+        </a><span
+          ref="full"
+          class="full"
+        >
+          <!-- eslint-disable vue/no-v-html -->
+          @<span v-html="userName" /><span v-html="'@' + serverName" />
+          <!-- eslint-enable vue/no-v-html -->
         </span>
       </span>
     </UserPopover>
   </span>
 </template>
 
-<script src="./mention_link.js"/>
+<script src="./mention_link.js" />
 
-<style lang="scss" src="./mention_link.scss"/>
+<style lang="scss" src="./mention_link.scss" />
diff --git a/src/components/mentions_line/mentions_line.vue b/src/components/mentions_line/mentions_line.vue
index 161855e8..64c19bf1 100644
--- a/src/components/mentions_line/mentions_line.vue
+++ b/src/components/mentions_line/mentions_line.vue
@@ -14,12 +14,12 @@
         v-if="expanded"
         class="fullExtraMentions"
       >{{ ' ' }}<MentionLink
-          v-for="mention in extraMentions"
-          :key="mention.index"
-          class="mention-link"
-          :content="mention.content"
-          :url="mention.url"
-        />
+        v-for="mention in extraMentions"
+        :key="mention.index"
+        class="mention-link"
+        :content="mention.content"
+        :url="mention.url"
+      />
       </span><button
         v-if="!expanded"
         class="button-unstyled showMoreLess"
@@ -36,5 +36,5 @@
     </span>
   </span>
 </template>
-<script src="./mentions_line.js" ></script>
+<script src="./mentions_line.js"></script>
 <style lang="scss" src="./mentions_line.scss" />
diff --git a/src/components/mfa_form/recovery_form.vue b/src/components/mfa_form/recovery_form.vue
index a9cf39aa..5988fa51 100644
--- a/src/components/mfa_form/recovery_form.vue
+++ b/src/components/mfa_form/recovery_form.vue
@@ -69,4 +69,4 @@
     </div>
   </div>
 </template>
-<script src="./recovery_form.js" ></script>
+<script src="./recovery_form.js"></script>
diff --git a/src/components/mobile_nav/mobile_nav.vue b/src/components/mobile_nav/mobile_nav.vue
index c58d9e7c..949cf17e 100644
--- a/src/components/mobile_nav/mobile_nav.vue
+++ b/src/components/mobile_nav/mobile_nav.vue
@@ -67,11 +67,10 @@
         </a>
       </div>
       <div
-        class="mobile-notifications"
         id="mobile-notifications"
+        class="mobile-notifications"
         @scroll="onScroll"
-      >
-      </div>
+      />
     </div>
     <SideDrawer
       ref="sideDrawer"
diff --git a/src/components/modal/modal.vue b/src/components/modal/modal.vue
index 52d8d27e..2187f392 100644
--- a/src/components/modal/modal.vue
+++ b/src/components/modal/modal.vue
@@ -12,6 +12,9 @@
 
 <script>
 export default {
+  provide: {
+    popoversZLayer: 'modals'
+  },
   props: {
     isOpen: {
       type: Boolean,
@@ -22,14 +25,11 @@ export default {
       default: false
     }
   },
-  provide: {
-    popoversZLayer: 'modals'
-  },
   computed: {
     classes () {
       return {
         'modal-background': !this.noBackground,
-        'open': this.isOpen
+        open: this.isOpen
       }
     }
   }
diff --git a/src/components/moderation_tools/moderation_tools.vue b/src/components/moderation_tools/moderation_tools.vue
index 96b8c3a3..34fe2e7c 100644
--- a/src/components/moderation_tools/moderation_tools.vue
+++ b/src/components/moderation_tools/moderation_tools.vue
@@ -8,7 +8,7 @@
       @show="setToggled(true)"
       @close="setToggled(false)"
     >
-      <template v-slot:content>
+      <template #content>
         <div class="dropdown-menu">
           <span v-if="user.is_local">
             <button
@@ -122,7 +122,7 @@
           </span>
         </div>
       </template>
-      <template v-slot:trigger>
+      <template #trigger>
         <button
           class="btn button-default btn-block moderation-tools-button"
           :class="{ toggled }"
@@ -137,11 +137,11 @@
         v-if="showDeleteUserDialog"
         :on-cancel="deleteUserDialog.bind(this, false)"
       >
-        <template v-slot:header>
+        <template #header>
           {{ $t('user_card.admin_menu.delete_user') }}
         </template>
         <p>{{ $t('user_card.admin_menu.delete_user_confirmation') }}</p>
-        <template v-slot:footer>
+        <template #footer>
           <button
             class="btn button-default"
             @click="deleteUserDialog(false)"
diff --git a/src/components/mrf_transparency_panel/mrf_transparency_panel.js b/src/components/mrf_transparency_panel/mrf_transparency_panel.js
index 3fde8106..13cfb52e 100644
--- a/src/components/mrf_transparency_panel/mrf_transparency_panel.js
+++ b/src/components/mrf_transparency_panel/mrf_transparency_panel.js
@@ -9,10 +9,10 @@ import { get } from 'lodash'
  */
 const toInstanceReasonObject = (instances, info, key) => {
   return instances.map(instance => {
-    if (info[key] && info[key][instance] && info[key][instance]['reason']) {
-      return { instance: instance, reason: info[key][instance]['reason'] }
+    if (info[key] && info[key][instance] && info[key][instance].reason) {
+      return { instance, reason: info[key][instance].reason }
     }
-    return { instance: instance, reason: '' }
+    return { instance, reason: '' }
   })
 }
 
diff --git a/src/components/nav_panel/nav_panel.vue b/src/components/nav_panel/nav_panel.vue
index 62aab7f1..3fd27d89 100644
--- a/src/components/nav_panel/nav_panel.vue
+++ b/src/components/nav_panel/nav_panel.vue
@@ -90,7 +90,7 @@
   </div>
 </template>
 
-<script src="./nav_panel.js" ></script>
+<script src="./nav_panel.js"></script>
 
 <style lang="scss">
 @import '../../_variables.scss';
diff --git a/src/components/notification/notification.js b/src/components/notification/notification.js
index 77cdfa73..882b68f9 100644
--- a/src/components/notification/notification.js
+++ b/src/components/notification/notification.js
@@ -40,7 +40,7 @@ const Notification = {
       unmuted: false
     }
   },
-  props: [ 'notification' ],
+  props: ['notification'],
   components: {
     StatusContent,
     UserAvatar,
diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue
index 6427d117..d2b903f6 100644
--- a/src/components/notification/notification.vue
+++ b/src/components/notification/notification.vue
@@ -37,8 +37,8 @@
         @click.prevent
       >
         <UserPopover
-          :userId="notification.from_profile.id"
-          :overlayCenters="true"
+          :user-id="notification.from_profile.id"
+          :overlay-centers="true"
         >
           <UserAvatar
             class="post-avatar"
diff --git a/src/components/notifications/notification_filters.vue b/src/components/notifications/notification_filters.vue
index 00a531b3..b0213167 100644
--- a/src/components/notifications/notification_filters.vue
+++ b/src/components/notifications/notification_filters.vue
@@ -5,7 +5,7 @@
     placement="bottom"
     :bound-to="{ x: 'container' }"
   >
-    <template v-slot:content>
+    <template #content>
       <div class="dropdown-menu">
         <button
           class="button-default dropdown-item"
@@ -72,7 +72,7 @@
         </button>
       </div>
     </template>
-    <template v-slot:trigger>
+    <template #trigger>
       <button class="filter-trigger-button button-unstyled">
         <FAIcon icon="filter" />
       </button>
diff --git a/src/components/notifications/notifications.vue b/src/components/notifications/notifications.vue
index b46c06aa..e778e27b 100644
--- a/src/components/notifications/notifications.vue
+++ b/src/components/notifications/notifications.vue
@@ -1,5 +1,8 @@
 <template>
-  <teleport :disabled="minimalMode || disableTeleport" :to="teleportTarget">
+  <teleport
+    :disabled="minimalMode || disableTeleport"
+    :to="teleportTarget"
+  >
     <div
       :class="{ minimal: minimalMode }"
       class="Notifications"
diff --git a/src/components/popover/popover.js b/src/components/popover/popover.js
index 58f7126d..d2af59fe 100644
--- a/src/components/popover/popover.js
+++ b/src/components/popover/popover.js
@@ -104,21 +104,25 @@ const Popover = {
 
       // What are the screen bounds for the popover? Viewport vs container
       // when using viewport, using default margin values to dodge the navbar
-      const xBounds = this.boundTo && this.boundTo.x === 'container' ? {
-        min: parentScreenBox.left + (margin.left || 0),
-        max: parentScreenBox.right - (margin.right || 0)
-      } : {
-        min: 0 + (margin.left || 10),
-        max: window.innerWidth - (margin.right || 10)
-      }
-
-      const yBounds = this.boundTo && this.boundTo.y === 'container' ? {
-        min: parentScreenBox.top + (margin.top || 0),
-        max: parentScreenBox.bottom - (margin.bottom || 0)
-      } : {
-        min: 0 + (margin.top || 50),
-        max: window.innerHeight - (margin.bottom || 5)
-      }
+      const xBounds = this.boundTo && this.boundTo.x === 'container'
+        ? {
+            min: parentScreenBox.left + (margin.left || 0),
+            max: parentScreenBox.right - (margin.right || 0)
+          }
+        : {
+            min: 0 + (margin.left || 10),
+            max: window.innerWidth - (margin.right || 10)
+          }
+
+      const yBounds = this.boundTo && this.boundTo.y === 'container'
+        ? {
+            min: parentScreenBox.top + (margin.top || 0),
+            max: parentScreenBox.bottom - (margin.bottom || 0)
+          }
+        : {
+            min: 0 + (margin.top || 50),
+            max: window.innerHeight - (margin.bottom || 5)
+          }
 
       let horizOffset = 0
       let vertOffset = 0
diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js
index 2febf226..c0d80b20 100644
--- a/src/components/post_status_form/post_status_form.js
+++ b/src/components/post_status_form/post_status_form.js
@@ -41,7 +41,7 @@ const buildMentionsString = ({ user, attentions = [] }, currentUser) => {
   allAttentions = uniqBy(allAttentions, 'id')
   allAttentions = reject(allAttentions, { id: currentUser.id })
 
-  let mentions = map(allAttentions, (attention) => {
+  const mentions = map(allAttentions, (attention) => {
     return `@${attention.screen_name}`
   })
 
@@ -242,7 +242,7 @@ const PostStatusForm = {
     })
   },
   watch: {
-    'newStatus': {
+    newStatus: {
       deep: true,
       handler () {
         this.statusChanged()
@@ -273,7 +273,7 @@ const PostStatusForm = {
           this.$refs.textarea.focus()
         })
       }
-      let el = this.$el.querySelector('textarea')
+      const el = this.$el.querySelector('textarea')
       el.style.height = 'auto'
       el.style.height = undefined
       this.error = null
@@ -392,7 +392,7 @@ const PostStatusForm = {
       this.$emit('resize', { delayed: true })
     },
     removeMediaFile (fileInfo) {
-      let index = this.newStatus.files.indexOf(fileInfo)
+      const index = this.newStatus.files.indexOf(fileInfo)
       this.newStatus.files.splice(index, 1)
       this.$emit('resize')
     },
@@ -462,7 +462,7 @@ const PostStatusForm = {
     },
     onEmojiInputInput (e) {
       this.$nextTick(() => {
-        this.resize(this.$refs['textarea'])
+        this.resize(this.$refs.textarea)
       })
     },
     resize (e) {
@@ -477,8 +477,8 @@ const PostStatusForm = {
         return
       }
 
-      const formRef = this.$refs['form']
-      const bottomRef = this.$refs['bottom']
+      const formRef = this.$refs.form
+      const bottomRef = this.$refs.bottom
       /* Scroller is either `window` (replies in TL), sidebar (main post form,
        * replies in notifs) or mobile post form. Note that getting and setting
        * scroll is different for `Window` and `Element`s
@@ -564,7 +564,7 @@ const PostStatusForm = {
       this.$refs['emoji-input'].resize()
     },
     showEmojiPicker () {
-      this.$refs['textarea'].focus()
+      this.$refs.textarea.focus()
       this.$refs['emoji-input'].triggerShowPicker()
     },
     clearError () {
diff --git a/src/components/react_button/react_button.js b/src/components/react_button/react_button.js
index e6f9dbff..37d6e7d0 100644
--- a/src/components/react_button/react_button.js
+++ b/src/components/react_button/react_button.js
@@ -45,7 +45,7 @@ const ReactButton = {
     emojis () {
       if (this.filterWord !== '') {
         const filterWordLowercase = trim(this.filterWord.toLowerCase())
-        let orderedEmojiList = []
+        const orderedEmojiList = []
         for (const emoji of this.$store.state.instance.emoji) {
           if (emoji.replacement === this.filterWord) return [emoji]
 
diff --git a/src/components/react_button/react_button.vue b/src/components/react_button/react_button.vue
index b76fb244..5a809847 100644
--- a/src/components/react_button/react_button.vue
+++ b/src/components/react_button/react_button.vue
@@ -9,13 +9,13 @@
     popover-class="ReactButton popover-default"
     @show="focusInput"
   >
-    <template v-slot:content="{close}">
+    <template #content="{close}">
       <div class="reaction-picker-filter">
         <input
           v-model="filterWord"
-          @input="$event.target.composing = false"
           size="1"
           :placeholder="$t('emoji.search_emoji')"
+          @input="$event.target.composing = false"
         >
       </div>
       <div class="reaction-picker">
@@ -41,7 +41,7 @@
         <div class="reaction-bottom-fader" />
       </div>
     </template>
-    <template v-slot:trigger>
+    <template #trigger>
       <span
         class="button-unstyled popover-trigger"
         :title="$t('tool_tip.add_reaction')"
@@ -55,7 +55,7 @@
   </Popover>
 </template>
 
-<script src="./react_button.js" ></script>
+<script src="./react_button.js"></script>
 
 <style lang="scss">
 @import '../../_variables.scss';
diff --git a/src/components/remote_follow/remote_follow.js b/src/components/remote_follow/remote_follow.js
index 461d58c9..56b264fc 100644
--- a/src/components/remote_follow/remote_follow.js
+++ b/src/components/remote_follow/remote_follow.js
@@ -1,5 +1,5 @@
 export default {
-  props: [ 'user' ],
+  props: ['user'],
   computed: {
     subscribeUrl () {
       // eslint-disable-next-line no-undef
diff --git a/src/components/retweet_button/retweet_button.vue b/src/components/retweet_button/retweet_button.vue
index 859ce499..5a15d387 100644
--- a/src/components/retweet_button/retweet_button.vue
+++ b/src/components/retweet_button/retweet_button.vue
@@ -36,7 +36,7 @@
   </div>
 </template>
 
-<script src="./retweet_button.js" ></script>
+<script src="./retweet_button.js"></script>
 
 <style lang="scss">
 @import '../../_variables.scss';
diff --git a/src/components/search_bar/search_bar.js b/src/components/search_bar/search_bar.js
index 551649c7..3b297f09 100644
--- a/src/components/search_bar/search_bar.js
+++ b/src/components/search_bar/search_bar.js
@@ -16,7 +16,7 @@ const SearchBar = {
     error: false
   }),
   watch: {
-    '$route': function (route) {
+    $route: function (route) {
       if (route.name === 'search') {
         this.searchTerm = route.query.query
       }
diff --git a/src/components/selectable_list/selectable_list.vue b/src/components/selectable_list/selectable_list.vue
index 3c80660e..1f7683ab 100644
--- a/src/components/selectable_list/selectable_list.vue
+++ b/src/components/selectable_list/selectable_list.vue
@@ -24,7 +24,7 @@
       :items="items"
       :get-key="getKey"
     >
-      <template v-slot:item="{item}">
+      <template #item="{item}">
         <div
           class="selectable-list-item-inner"
           :class="{ 'selectable-list-item-selected-inner': isSelected(item) }"
@@ -41,7 +41,7 @@
           />
         </div>
       </template>
-      <template v-slot:empty>
+      <template #empty>
         <slot name="empty" />
       </template>
     </List>
diff --git a/src/components/settings_modal/helpers/modified_indicator.vue b/src/components/settings_modal/helpers/modified_indicator.vue
index 74366dc1..8311533a 100644
--- a/src/components/settings_modal/helpers/modified_indicator.vue
+++ b/src/components/settings_modal/helpers/modified_indicator.vue
@@ -6,14 +6,14 @@
     <Popover
       trigger="hover"
     >
-      <template v-slot:trigger>
+      <template #trigger>
         &nbsp;
         <FAIcon
           icon="wrench"
           :aria-label="$t('settings.setting_changed')"
         />
       </template>
-      <template v-slot:content>
+      <template #content>
         <div class="modified-tooltip">
           {{ $t('settings.setting_changed') }}
         </div>
diff --git a/src/components/settings_modal/helpers/server_side_indicator.vue b/src/components/settings_modal/helpers/server_side_indicator.vue
index cf53eb6a..bf181959 100644
--- a/src/components/settings_modal/helpers/server_side_indicator.vue
+++ b/src/components/settings_modal/helpers/server_side_indicator.vue
@@ -6,14 +6,14 @@
     <Popover
       trigger="hover"
     >
-      <template v-slot:trigger>
+      <template #trigger>
         &nbsp;
         <FAIcon
           icon="server"
           :aria-label="$t('settings.setting_server_side')"
         />
       </template>
-      <template v-slot:content>
+      <template #content>
         <div class="serverside-tooltip">
           {{ $t('settings.setting_server_side') }}
         </div>
diff --git a/src/components/settings_modal/settings_modal.vue b/src/components/settings_modal/settings_modal.vue
index d3bed061..7b457371 100644
--- a/src/components/settings_modal/settings_modal.vue
+++ b/src/components/settings_modal/settings_modal.vue
@@ -53,7 +53,7 @@
           :bound-to="{ x: 'container' }"
           remove-padding
         >
-          <template v-slot:trigger>
+          <template #trigger>
             <button
               class="btn button-default"
               :title="$t('general.close')"
@@ -65,7 +65,7 @@
               />
             </button>
           </template>
-          <template v-slot:content="{close}">
+          <template #content="{close}">
             <div class="dropdown-menu">
               <button
                 class="button-default dropdown-item dropdown-item-icon"
diff --git a/src/components/settings_modal/tabs/general_tab.vue b/src/components/settings_modal/tabs/general_tab.vue
index e201ab9d..a2609200 100644
--- a/src/components/settings_modal/tabs/general_tab.vue
+++ b/src/components/settings_modal/tabs/general_tab.vue
@@ -75,12 +75,18 @@
           </BooleanSetting>
         </li>
         <li>
-          <BooleanSetting path="userPopoverZoom" expert="1">
+          <BooleanSetting
+            path="userPopoverZoom"
+            expert="1"
+          >
             {{ $t('settings.user_popover_avatar_zoom') }}
           </BooleanSetting>
         </li>
         <li>
-          <BooleanSetting path="userPopoverOverlay" expert="1">
+          <BooleanSetting
+            path="userPopoverOverlay"
+            expert="1"
+          >
             {{ $t('settings.user_popover_avatar_overlay') }}
           </BooleanSetting>
         </li>
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 32a21415..c515d542 100644
--- a/src/components/settings_modal/tabs/mutes_and_blocks_tab.vue
+++ b/src/components/settings_modal/tabs/mutes_and_blocks_tab.vue
@@ -10,7 +10,7 @@
           :query="queryUserIds"
           :placeholder="$t('settings.search_user_to_block')"
         >
-          <template v-slot="row">
+          <template #default="row">
             <BlockCard
               :user-id="row.item"
             />
@@ -21,7 +21,7 @@
         :refresh="true"
         :get-key="i => i"
       >
-        <template v-slot:header="{selected}">
+        <template #header="{selected}">
           <div class="bulk-actions">
             <ProgressButton
               v-if="selected.length > 0"
@@ -29,7 +29,7 @@
               :click="() => blockUsers(selected)"
             >
               {{ $t('user_card.block') }}
-              <template v-slot:progress>
+              <template #progress>
                 {{ $t('user_card.block_progress') }}
               </template>
             </ProgressButton>
@@ -39,16 +39,16 @@
               :click="() => unblockUsers(selected)"
             >
               {{ $t('user_card.unblock') }}
-              <template v-slot:progress>
+              <template #progress>
                 {{ $t('user_card.unblock_progress') }}
               </template>
             </ProgressButton>
           </div>
         </template>
-        <template v-slot:item="{item}">
+        <template #item="{item}">
           <BlockCard :user-id="item" />
         </template>
-        <template v-slot:empty>
+        <template #empty>
           {{ $t('settings.no_blocks') }}
         </template>
       </BlockList>
@@ -63,7 +63,7 @@
               :query="queryUserIds"
               :placeholder="$t('settings.search_user_to_mute')"
             >
-              <template v-slot="row">
+              <template #default="row">
                 <MuteCard
                   :user-id="row.item"
                 />
@@ -74,7 +74,7 @@
             :refresh="true"
             :get-key="i => i"
           >
-            <template v-slot:header="{selected}">
+            <template #header="{selected}">
               <div class="bulk-actions">
                 <ProgressButton
                   v-if="selected.length > 0"
@@ -82,7 +82,7 @@
                   :click="() => muteUsers(selected)"
                 >
                   {{ $t('user_card.mute') }}
-                  <template v-slot:progress>
+                  <template #progress>
                     {{ $t('user_card.mute_progress') }}
                   </template>
                 </ProgressButton>
@@ -92,16 +92,16 @@
                   :click="() => unmuteUsers(selected)"
                 >
                   {{ $t('user_card.unmute') }}
-                  <template v-slot:progress>
+                  <template #progress>
                     {{ $t('user_card.unmute_progress') }}
                   </template>
                 </ProgressButton>
               </div>
             </template>
-            <template v-slot:item="{item}">
+            <template #item="{item}">
               <MuteCard :user-id="item" />
             </template>
-            <template v-slot:empty>
+            <template #empty>
               {{ $t('settings.no_mutes') }}
             </template>
           </MuteList>
@@ -114,7 +114,7 @@
               :query="queryKnownDomains"
               :placeholder="$t('settings.type_domains_to_mute')"
             >
-              <template v-slot="row">
+              <template #default="row">
                 <DomainMuteCard
                   :domain="row.item"
                 />
@@ -125,7 +125,7 @@
             :refresh="true"
             :get-key="i => i"
           >
-            <template v-slot:header="{selected}">
+            <template #header="{selected}">
               <div class="bulk-actions">
                 <ProgressButton
                   v-if="selected.length > 0"
@@ -133,16 +133,16 @@
                   :click="() => unmuteDomains(selected)"
                 >
                   {{ $t('domain_mute_card.unmute') }}
-                  <template v-slot:progress>
+                  <template #progress>
                     {{ $t('domain_mute_card.unmute_progress') }}
                   </template>
                 </ProgressButton>
               </div>
             </template>
-            <template v-slot:item="{item}">
+            <template #item="{item}">
               <DomainMuteCard :domain="item" />
             </template>
-            <template v-slot:empty>
+            <template #empty>
               {{ $t('settings.no_mutes') }}
             </template>
           </DomainMuteList>
diff --git a/src/components/settings_modal/tabs/profile_tab.js b/src/components/settings_modal/tabs/profile_tab.js
index 8781bb91..376248ef 100644
--- a/src/components/settings_modal/tabs/profile_tab.js
+++ b/src/components/settings_modal/tabs/profile_tab.js
@@ -71,10 +71,12 @@ const ProfileTab = {
       })
     },
     emojiSuggestor () {
-      return suggestor({ emoji: [
-        ...this.$store.state.instance.emoji,
-        ...this.$store.state.instance.customEmoji
-      ] })
+      return suggestor({
+        emoji: [
+          ...this.$store.state.instance.emoji,
+          ...this.$store.state.instance.customEmoji
+        ]
+      })
     },
     userSuggestor () {
       return suggestor({ store: this.$store })
diff --git a/src/components/settings_modal/tabs/profile_tab.vue b/src/components/settings_modal/tabs/profile_tab.vue
index 4cd93772..642d54ca 100644
--- a/src/components/settings_modal/tabs/profile_tab.vue
+++ b/src/components/settings_modal/tabs/profile_tab.vue
@@ -117,8 +117,8 @@
         <button
           v-if="!isDefaultAvatar && pickAvatarBtnVisible"
           :title="$t('settings.reset_avatar')"
-          @click="resetAvatar"
           class="button-unstyled reset-button"
+          @click="resetAvatar"
         >
           <FAIcon
             icon="times"
diff --git a/src/components/settings_modal/tabs/security_tab/mfa.js b/src/components/settings_modal/tabs/security_tab/mfa.js
index abf37062..5337d150 100644
--- a/src/components/settings_modal/tabs/security_tab/mfa.js
+++ b/src/components/settings_modal/tabs/security_tab/mfa.js
@@ -32,8 +32,8 @@ const Mfa = {
   components: {
     'recovery-codes': RecoveryCodes,
     'totp-item': TOTP,
-    'qrcode': VueQrcode,
-    'confirm': Confirm
+    qrcode: VueQrcode,
+    confirm: Confirm
   },
   computed: {
     canSetupOTP () {
@@ -139,7 +139,7 @@ const Mfa = {
 
     // fetch settings from server
     async fetchSettings () {
-      let result = await this.backendInteractor.settingsMFA()
+      const result = await this.backendInteractor.settingsMFA()
       if (result.error) return
       this.settings = result.settings
       this.settings.available = true
diff --git a/src/components/settings_modal/tabs/security_tab/mfa_totp.js b/src/components/settings_modal/tabs/security_tab/mfa_totp.js
index 8408d8e9..b0adb530 100644
--- a/src/components/settings_modal/tabs/security_tab/mfa_totp.js
+++ b/src/components/settings_modal/tabs/security_tab/mfa_totp.js
@@ -10,7 +10,7 @@ export default {
     inProgress: false // progress peform request to disable otp method
   }),
   components: {
-    'confirm': Confirm
+    confirm: Confirm
   },
   computed: {
     isActivated () {
diff --git a/src/components/settings_modal/tabs/security_tab/security_tab.js b/src/components/settings_modal/tabs/security_tab/security_tab.js
index fc732936..d253bc79 100644
--- a/src/components/settings_modal/tabs/security_tab/security_tab.js
+++ b/src/components/settings_modal/tabs/security_tab/security_tab.js
@@ -13,7 +13,7 @@ const SecurityTab = {
       deletingAccount: false,
       deleteAccountConfirmPasswordInput: '',
       deleteAccountError: false,
-      changePasswordInputs: [ '', '', '' ],
+      changePasswordInputs: ['', '', ''],
       changedPassword: false,
       changePasswordError: false,
       moveAccountTarget: '',
diff --git a/src/components/settings_modal/tabs/theme_tab/preview.vue b/src/components/settings_modal/tabs/theme_tab/preview.vue
index f266b603..ba6bd529 100644
--- a/src/components/settings_modal/tabs/theme_tab/preview.vue
+++ b/src/components/settings_modal/tabs/theme_tab/preview.vue
@@ -29,7 +29,10 @@
               {{ $t('settings.style.preview.content') }}
             </h4>
 
-            <i18n-t scope="global" keypath="settings.style.preview.text">
+            <i18n-t
+              scope="global"
+              keypath="settings.style.preview.text"
+            >
               <code style="font-family: var(--postCodeFont)">
                 {{ $t('settings.style.preview.mono') }}
               </code>
diff --git a/src/components/settings_modal/tabs/theme_tab/theme_tab.js b/src/components/settings_modal/tabs/theme_tab/theme_tab.js
index 7e1da7ab..282cb384 100644
--- a/src/components/settings_modal/tabs/theme_tab/theme_tab.js
+++ b/src/components/settings_modal/tabs/theme_tab/theme_tab.js
@@ -95,11 +95,11 @@ export default {
 
       ...Object.keys(SLOT_INHERITANCE)
         .map(key => [key, ''])
-        .reduce((acc, [key, val]) => ({ ...acc, [ key + 'ColorLocal' ]: val }), {}),
+        .reduce((acc, [key, val]) => ({ ...acc, [key + 'ColorLocal']: val }), {}),
 
       ...Object.keys(OPACITIES)
         .map(key => [key, ''])
-        .reduce((acc, [key, val]) => ({ ...acc, [ key + 'OpacityLocal' ]: val }), {}),
+        .reduce((acc, [key, val]) => ({ ...acc, [key + 'OpacityLocal']: val }), {}),
 
       shadowSelected: undefined,
       shadowsLocal: {},
@@ -212,12 +212,12 @@ export default {
     currentColors () {
       return Object.keys(SLOT_INHERITANCE)
         .map(key => [key, this[key + 'ColorLocal']])
-        .reduce((acc, [key, val]) => ({ ...acc, [ key ]: val }), {})
+        .reduce((acc, [key, val]) => ({ ...acc, [key]: val }), {})
     },
     currentOpacity () {
       return Object.keys(OPACITIES)
         .map(key => [key, this[key + 'OpacityLocal']])
-        .reduce((acc, [key, val]) => ({ ...acc, [ key ]: val }), {})
+        .reduce((acc, [key, val]) => ({ ...acc, [key]: val }), {})
     },
     currentRadii () {
       return {
diff --git a/src/components/shadow_control/shadow_control.js b/src/components/shadow_control/shadow_control.js
index 386a5756..a1d1012b 100644
--- a/src/components/shadow_control/shadow_control.js
+++ b/src/components/shadow_control/shadow_control.js
@@ -112,9 +112,11 @@ export default {
       return hex2rgb(this.selected.color)
     },
     style () {
-      return this.ready ? {
-        boxShadow: getCssShadow(this.fallback)
-      } : {}
+      return this.ready
+        ? {
+            boxShadow: getCssShadow(this.fallback)
+          }
+        : {}
     }
   }
 }
diff --git a/src/components/shadow_control/shadow_control.vue b/src/components/shadow_control/shadow_control.vue
index f2fc7b99..669cac71 100644
--- a/src/components/shadow_control/shadow_control.vue
+++ b/src/components/shadow_control/shadow_control.vue
@@ -215,7 +215,7 @@
   </div>
 </template>
 
-<script src="./shadow_control.js" ></script>
+<script src="./shadow_control.js"></script>
 
 <style lang="scss">
 @import '../../_variables.scss';
diff --git a/src/components/shout_panel/shout_panel.js b/src/components/shout_panel/shout_panel.js
index a6168971..fb0c5aa2 100644
--- a/src/components/shout_panel/shout_panel.js
+++ b/src/components/shout_panel/shout_panel.js
@@ -11,7 +11,7 @@ library.add(
 )
 
 const shoutPanel = {
-  props: [ 'floating' ],
+  props: ['floating'],
   data () {
     return {
       currentMessage: '',
diff --git a/src/components/side_drawer/side_drawer.js b/src/components/side_drawer/side_drawer.js
index bad1806b..f45f8def 100644
--- a/src/components/side_drawer/side_drawer.js
+++ b/src/components/side_drawer/side_drawer.js
@@ -32,7 +32,7 @@ library.add(
 )
 
 const SideDrawer = {
-  props: [ 'logout' ],
+  props: ['logout'],
   data: () => ({
     closed: true,
     closeGesture: undefined
diff --git a/src/components/side_drawer/side_drawer.vue b/src/components/side_drawer/side_drawer.vue
index aefd3915..7547fb08 100644
--- a/src/components/side_drawer/side_drawer.vue
+++ b/src/components/side_drawer/side_drawer.vue
@@ -204,7 +204,7 @@
   </div>
 </template>
 
-<script src="./side_drawer.js" ></script>
+<script src="./side_drawer.js"></script>
 
 <style lang="scss">
 @import '../../_variables.scss';
diff --git a/src/components/staff_panel/staff_panel.js b/src/components/staff_panel/staff_panel.js
index b9561bf1..a7fbc718 100644
--- a/src/components/staff_panel/staff_panel.js
+++ b/src/components/staff_panel/staff_panel.js
@@ -17,8 +17,8 @@ const StaffPanel = {
       const groupedStaffAccounts = groupBy(staffAccounts, 'role')
 
       return [
-        { role: 'admin', users: groupedStaffAccounts['admin'] },
-        { role: 'moderator', users: groupedStaffAccounts['moderator'] }
+        { role: 'admin', users: groupedStaffAccounts.admin },
+        { role: 'moderator', users: groupedStaffAccounts.moderator }
       ].filter(group => group.users)
     },
     ...mapGetters([
diff --git a/src/components/staff_panel/staff_panel.vue b/src/components/staff_panel/staff_panel.vue
index c52ade42..6b9e61f2 100644
--- a/src/components/staff_panel/staff_panel.vue
+++ b/src/components/staff_panel/staff_panel.vue
@@ -24,7 +24,7 @@
   </div>
 </template>
 
-<script src="./staff_panel.js" ></script>
+<script src="./staff_panel.js"></script>
 
 <style lang="scss">
 
diff --git a/src/components/status/status.js b/src/components/status/status.js
index 053c9441..0a2690f6 100644
--- a/src/components/status/status.js
+++ b/src/components/status/status.js
@@ -448,7 +448,7 @@ const Status = {
     scrollIfHighlighted (highlightId) {
       const id = highlightId
       if (this.status.id === id) {
-        let rect = this.$el.getBoundingClientRect()
+        const rect = this.$el.getBoundingClientRect()
         if (rect.top < 100) {
           // Post is above screen, match its top to screen top
           window.scrollBy(0, rect.top - 100)
@@ -463,7 +463,7 @@ const Status = {
     }
   },
   watch: {
-    'highlight': function (id) {
+    highlight: function (id) {
       this.scrollIfHighlighted(id)
     },
     'status.repeat_num': function (num) {
@@ -478,7 +478,7 @@ const Status = {
         this.$store.dispatch('fetchFavs', this.status.id)
       }
     },
-    'isSuspendable': function (val) {
+    isSuspendable: function (val) {
       this.suspendable = val
     }
   }
diff --git a/src/components/status/status.vue b/src/components/status/status.vue
index bbb41d41..967a966c 100644
--- a/src/components/status/status.vue
+++ b/src/components/status/status.vue
@@ -122,10 +122,13 @@
           v-if="!noHeading"
           class="left-side"
         >
-          <a :href="$router.resolve(userProfileLink).href" @click.prevent>
+          <a
+            :href="$router.resolve(userProfileLink).href"
+            @click.prevent
+          >
             <UserPopover
-              :userId="status.user.id"
-              :overlayCenters="true"
+              :user-id="status.user.id"
+              :overlay-centers="true"
             >
               <UserAvatar
                 class="post-avatar"
@@ -488,6 +491,6 @@
   </div>
 </template>
 
-<script src="./status.js" ></script>
+<script src="./status.js"></script>
 
 <style src="./status.scss" lang="scss"></style>
diff --git a/src/components/status_body/status_body.vue b/src/components/status_body/status_body.vue
index 976fe98c..fb356360 100644
--- a/src/components/status_body/status_body.vue
+++ b/src/components/status_body/status_body.vue
@@ -96,5 +96,5 @@
     <slot v-if="!hideSubjectStatus" />
   </div>
 </template>
-<script src="./status_body.js" ></script>
+<script src="./status_body.js"></script>
 <style lang="scss" src="./status_body.scss" />
diff --git a/src/components/status_content/status_content.vue b/src/components/status_content/status_content.vue
index 9e7d7956..e2120f7a 100644
--- a/src/components/status_content/status_content.vue
+++ b/src/components/status_content/status_content.vue
@@ -56,7 +56,7 @@
   </div>
 </template>
 
-<script src="./status_content.js" ></script>
+<script src="./status_content.js"></script>
 <style lang="scss">
 .StatusContent {
   flex: 1;
diff --git a/src/components/status_popover/status_popover.vue b/src/components/status_popover/status_popover.vue
index 9cabb751..f4ab357b 100644
--- a/src/components/status_popover/status_popover.vue
+++ b/src/components/status_popover/status_popover.vue
@@ -1,16 +1,16 @@
 <template>
   <Popover
+    ref="popover"
     trigger="hover"
     :stay-on-click="true"
     popover-class="popover-default status-popover"
     :bound-to="{ x: 'container' }"
     @show="enter"
-    ref="popover"
   >
-    <template v-slot:trigger>
+    <template #trigger>
       <slot />
     </template>
-    <template v-slot:content>
+    <template #content>
       <Status
         v-if="status"
         :is-preview="true"
@@ -37,7 +37,7 @@
   </Popover>
 </template>
 
-<script src="./status_popover.js" ></script>
+<script src="./status_popover.js"></script>
 
 <style lang="scss">
 @import '../../_variables.scss';
diff --git a/src/components/sticker_picker/sticker_picker.js b/src/components/sticker_picker/sticker_picker.js
index 3a2d3914..b06384e5 100644
--- a/src/components/sticker_picker/sticker_picker.js
+++ b/src/components/sticker_picker/sticker_picker.js
@@ -31,8 +31,8 @@ const StickerPicker = {
       fetch(sticker)
         .then((res) => {
           res.blob().then((blob) => {
-            var file = new File([blob], name, { mimetype: 'image/png' })
-            var formData = new FormData()
+            const file = new File([blob], name, { mimetype: 'image/png' })
+            const formData = new FormData()
             formData.append('file', file)
             statusPosterService.uploadMedia({ store, formData })
               .then((fileData) => {
diff --git a/src/components/terms_of_service_panel/terms_of_service_panel.vue b/src/components/terms_of_service_panel/terms_of_service_panel.vue
index 63dc58b8..1df41d70 100644
--- a/src/components/terms_of_service_panel/terms_of_service_panel.vue
+++ b/src/components/terms_of_service_panel/terms_of_service_panel.vue
@@ -13,7 +13,7 @@
   </div>
 </template>
 
-<script src="./terms_of_service_panel.js" ></script>
+<script src="./terms_of_service_panel.js"></script>
 
 <style lang="scss">
 .tos-content {
diff --git a/src/components/timeline/timeline.vue b/src/components/timeline/timeline.vue
index f65881b6..266c1d9a 100644
--- a/src/components/timeline/timeline.vue
+++ b/src/components/timeline/timeline.vue
@@ -46,7 +46,10 @@
       </div>
     </div>
     <div :class="classes.footer">
-      <teleport :to="footerSlipgate" :disabled="!embedded || !footerSlipgate">
+      <teleport
+        :to="footerSlipgate"
+        :disabled="!embedded || !footerSlipgate"
+      >
         <div
           v-if="count===0"
           class="new-status-notification text-center faint"
diff --git a/src/components/timeline/timeline_quick_settings.vue b/src/components/timeline/timeline_quick_settings.vue
index 98fab926..297bc72a 100644
--- a/src/components/timeline/timeline_quick_settings.vue
+++ b/src/components/timeline/timeline_quick_settings.vue
@@ -4,7 +4,7 @@
     class="TimelineQuickSettings"
     :bound-to="{ x: 'container' }"
   >
-    <template v-slot:content>
+    <template #content>
       <div class="dropdown-menu">
         <div v-if="loggedIn">
           <button
@@ -80,7 +80,7 @@
         </button>
       </div>
     </template>
-    <template v-slot:trigger>
+    <template #trigger>
       <button class="button-unstyled">
         <FAIcon icon="filter" />
       </button>
diff --git a/src/components/timeline_menu/timeline_menu.js b/src/components/timeline_menu/timeline_menu.js
index bab51e75..a11e7b7e 100644
--- a/src/components/timeline_menu/timeline_menu.js
+++ b/src/components/timeline_menu/timeline_menu.js
@@ -11,9 +11,9 @@ library.add(faChevronDown)
 // because nav panel benefits from the same information.
 export const timelineNames = () => {
   return {
-    'friends': 'nav.home_timeline',
-    'bookmarks': 'nav.bookmarks',
-    'dms': 'nav.dms',
+    friends: 'nav.home_timeline',
+    bookmarks: 'nav.bookmarks',
+    dms: 'nav.dms',
     'public-timeline': 'nav.public_tl',
     'public-external-timeline': 'nav.twkn'
   }
diff --git a/src/components/timeline_menu/timeline_menu.vue b/src/components/timeline_menu/timeline_menu.vue
index 1e054f5a..c24b9d72 100644
--- a/src/components/timeline_menu/timeline_menu.vue
+++ b/src/components/timeline_menu/timeline_menu.vue
@@ -9,10 +9,10 @@
     @show="openMenu"
     @close="() => isOpen = false"
   >
-    <template v-slot:content>
+    <template #content>
       <TimelineMenuContent />
     </template>
-    <template v-slot:trigger>
+    <template #trigger>
       <span class="button-unstyled title timeline-menu-title">
         <span class="timeline-title">{{ timelineName() }}</span>
         <span>
@@ -30,7 +30,7 @@
   </Popover>
 </template>
 
-<script src="./timeline_menu.js" ></script>
+<script src="./timeline_menu.js"></script>
 
 <style lang="scss">
 @import '../../_variables.scss';
diff --git a/src/components/timeline_menu/timeline_menu_content.vue b/src/components/timeline_menu/timeline_menu_content.vue
index bed1b679..59e9e43c 100644
--- a/src/components/timeline_menu/timeline_menu_content.vue
+++ b/src/components/timeline_menu/timeline_menu_content.vue
@@ -63,4 +63,4 @@
   </ul>
 </template>
 
-<script src="./timeline_menu_content.js" ></script>
+<script src="./timeline_menu_content.js"></script>
diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js
index b0fa11b3..4c81e2c7 100644
--- a/src/components/user_card/user_card.js
+++ b/src/components/user_card/user_card.js
@@ -67,7 +67,7 @@ export default {
     style () {
       return {
         backgroundImage: [
-          `linear-gradient(to bottom, var(--profileTint), var(--profileTint))`,
+          'linear-gradient(to bottom, var(--profileTint), var(--profileTint))',
           `url(${this.user.cover_photo})`
         ].join(', ')
       }
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index bc23e68e..ace89c51 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -29,10 +29,10 @@
           </a>
           <UserAvatar
             v-else-if="typeof avatarAction === 'function'"
-            @click="avatarAction"
             class="user-info-avatar"
             :better-shadow="betterShadow"
             :user="user"
+            @click="avatarAction"
           />
           <router-link
             v-else
diff --git a/src/components/user_list_popover/user_list_popover.vue b/src/components/user_list_popover/user_list_popover.vue
index bdc3aa92..a3ce54c3 100644
--- a/src/components/user_list_popover/user_list_popover.vue
+++ b/src/components/user_list_popover/user_list_popover.vue
@@ -4,10 +4,10 @@
     placement="top"
     :offset="{ y: 5 }"
   >
-    <template v-slot:trigger>
+    <template #trigger>
       <slot />
     </template>
-    <template v-slot:content>
+    <template #content>
       <div class="user-list-popover">
         <template v-if="users.length">
           <div
@@ -45,7 +45,7 @@
   </Popover>
 </template>
 
-<script src="./user_list_popover.js" ></script>
+<script src="./user_list_popover.js"></script>
 
 <style lang="scss">
 @import '../../_variables.scss';
diff --git a/src/components/user_popover/user_popover.vue b/src/components/user_popover/user_popover.vue
index 72bb7f77..4e999672 100644
--- a/src/components/user_popover/user_popover.vue
+++ b/src/components/user_popover/user_popover.vue
@@ -1,27 +1,27 @@
 <template>
-<Popover
-  trigger="click"
-  popover-class="popover-default user-popover"
-  :overlay-centers-selector="overlayCentersSelector || '.user-info .Avatar'"
-  :overlay-centers="overlayCenters && userPopoverOverlay"
-  :disabled="disabled"
->
-  <template v-slot:trigger>
-    <slot />
-  </template>
-  <template v-slot:content={close}>
-    <UserCard
-      class="user-popover"
-      :user-id="userId"
-      :hide-bio="true"
-      :avatar-action="userPopoverZoom ? 'zoom' : close"
-      :on-close="close"
-    />
-  </template>
-</Popover>
+  <Popover
+    trigger="click"
+    popover-class="popover-default user-popover"
+    :overlay-centers-selector="overlayCentersSelector || '.user-info .Avatar'"
+    :overlay-centers="overlayCenters && userPopoverOverlay"
+    :disabled="disabled"
+  >
+    <template #trigger>
+      <slot />
+    </template>
+    <template #content="{close}">
+      <UserCard
+        class="user-popover"
+        :user-id="userId"
+        :hide-bio="true"
+        :avatar-action="userPopoverZoom ? 'zoom' : close"
+        :on-close="close"
+      />
+    </template>
+  </Popover>
 </template>
 
-<script src="./user_popover.js" ></script>
+<script src="./user_popover.js"></script>
 
 <style lang="scss">
 @import '../../_variables.scss';
diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue
index dbf28981..d0da2b5b 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -56,7 +56,7 @@
           :user-id="userId"
           :pinned-status-ids="user.pinnedStatusIds"
           :in-profile="true"
-          :footerSlipgate="footerRef"
+          :footer-slipgate="footerRef"
         />
         <div
           v-if="followsTabVisible"
@@ -65,7 +65,7 @@
           :disabled="!user.friends_count"
         >
           <FriendList :user-id="userId">
-            <template v-slot:item="{item}">
+            <template #item="{item}">
               <FollowCard :user="item" />
             </template>
           </FriendList>
@@ -77,7 +77,7 @@
           :disabled="!user.followers_count"
         >
           <FollowerList :user-id="userId">
-            <template v-slot:item="{item}">
+            <template #item="{item}">
               <FollowCard
                 :user="item"
                 :no-follows-you="isUs"
@@ -95,7 +95,7 @@
           :timeline="media"
           :user-id="userId"
           :in-profile="true"
-          :footerSlipgate="footerRef"
+          :footer-slipgate="footerRef"
         />
         <Timeline
           v-if="isUs"
@@ -107,10 +107,13 @@
           timeline-name="favorites"
           :timeline="favorites"
           :in-profile="true"
-          :footerSlipgate="footerRef"
+          :footer-slipgate="footerRef"
         />
       </tab-switcher>
-      <div class="panel-footer" :ref="setFooterRef"></div>
+      <div
+        :ref="setFooterRef"
+        class="panel-footer"
+      />
     </div>
     <div
       v-else
diff --git a/src/components/user_reporting_modal/user_reporting_modal.vue b/src/components/user_reporting_modal/user_reporting_modal.vue
index 030ce2c4..429a66e2 100644
--- a/src/components/user_reporting_modal/user_reporting_modal.vue
+++ b/src/components/user_reporting_modal/user_reporting_modal.vue
@@ -45,7 +45,7 @@
         </div>
         <div class="user-reporting-panel-right">
           <List :items="statuses">
-            <template v-slot:item="{item}">
+            <template #item="{item}">
               <div class="status-fadein user-reporting-panel-sitem">
                 <Status
                   :in-conversation="false"
diff --git a/src/components/who_to_follow/who_to_follow.js b/src/components/who_to_follow/who_to_follow.js
index ecd97dd7..53f05272 100644
--- a/src/components/who_to_follow/who_to_follow.js
+++ b/src/components/who_to_follow/who_to_follow.js
@@ -28,7 +28,7 @@ const WhoToFollow = {
     getWhoToFollow () {
       const credentials = this.$store.state.users.currentUser.credentials
       if (credentials) {
-        apiService.suggestions({ credentials: credentials })
+        apiService.suggestions({ credentials })
           .then((reply) => {
             this.showWhoToFollow(reply)
           })
diff --git a/src/components/who_to_follow_panel/who_to_follow_panel.js b/src/components/who_to_follow_panel/who_to_follow_panel.js
index 818e8bd5..f19ba948 100644
--- a/src/components/who_to_follow_panel/who_to_follow_panel.js
+++ b/src/components/who_to_follow_panel/who_to_follow_panel.js
@@ -6,9 +6,9 @@ function showWhoToFollow (panel, reply) {
   const shuffled = shuffle(reply)
 
   panel.usersToFollow.forEach((toFollow, index) => {
-    let user = shuffled[index]
-    let img = user.avatar || this.$store.state.instance.defaultAvatar
-    let name = user.acct
+    const user = shuffled[index]
+    const img = user.avatar || this.$store.state.instance.defaultAvatar
+    const name = user.acct
 
     toFollow.img = img
     toFollow.name = name
@@ -24,12 +24,12 @@ function showWhoToFollow (panel, reply) {
 }
 
 function getWhoToFollow (panel) {
-  var credentials = panel.$store.state.users.currentUser.credentials
+  const credentials = panel.$store.state.users.currentUser.credentials
   if (credentials) {
     panel.usersToFollow.forEach(toFollow => {
       toFollow.name = 'Loading...'
     })
-    apiService.suggestions({ credentials: credentials })
+    apiService.suggestions({ credentials })
       .then((reply) => {
         showWhoToFollow(panel, reply)
       })
diff --git a/src/components/who_to_follow_panel/who_to_follow_panel.vue b/src/components/who_to_follow_panel/who_to_follow_panel.vue
index 518acd97..c1ba6fb1 100644
--- a/src/components/who_to_follow_panel/who_to_follow_panel.vue
+++ b/src/components/who_to_follow_panel/who_to_follow_panel.vue
@@ -27,7 +27,7 @@
   </div>
 </template>
 
-<script src="./who_to_follow_panel.js" ></script>
+<script src="./who_to_follow_panel.js"></script>
 
 <style lang="scss">
   .who-to-follow * {
diff --git a/src/i18n/messages.js b/src/i18n/messages.js
index 18ed79b7..eae75c80 100644
--- a/src/i18n/messages.js
+++ b/src/i18n/messages.js
@@ -46,7 +46,7 @@ const messages = {
   },
   setLanguage: async (i18n, language) => {
     if (loaders[language]) {
-      let messages = await loaders[language]()
+      const messages = await loaders[language]()
       i18n.setLocaleMessage(language, messages.default)
     }
     i18n.locale = language
diff --git a/src/lib/notification-i18n-loader.js b/src/lib/notification-i18n-loader.js
index 71f9156a..d7a4430d 100644
--- a/src/lib/notification-i18n-loader.js
+++ b/src/lib/notification-i18n-loader.js
@@ -3,8 +3,8 @@
 // meant to be used to load the partial i18n we need for
 // the service worker.
 module.exports = function (source) {
-  var object = JSON.parse(source)
-  var smol = {
+  const object = JSON.parse(source)
+  const smol = {
     notifications: object.notifications || {}
   }
 
diff --git a/src/lib/persisted_state.js b/src/lib/persisted_state.js
index 24b835da..c73a38ec 100644
--- a/src/lib/persisted_state.js
+++ b/src/lib/persisted_state.js
@@ -5,10 +5,12 @@ import { each, get, set, cloneDeep } from 'lodash'
 let loaded = false
 
 const defaultReducer = (state, paths) => (
-  paths.length === 0 ? state : paths.reduce((substate, path) => {
-    set(substate, path, get(state, path))
-    return substate
-  }, {})
+  paths.length === 0
+    ? state
+    : paths.reduce((substate, path) => {
+      set(substate, path, get(state, path))
+      return substate
+    }, {})
 )
 
 const saveImmedeatelyActions = [
@@ -30,7 +32,7 @@ export default function createPersistedState ({
   key = 'vuex-lz',
   paths = [],
   getState = (key, storage) => {
-    let value = storage.getItem(key)
+    const value = storage.getItem(key)
     return value
   },
   setState = (key, state, storage) => {
diff --git a/src/modules/api.js b/src/modules/api.js
index 54f94356..28f2076e 100644
--- a/src/modules/api.js
+++ b/src/modules/api.js
@@ -233,7 +233,7 @@ const api = {
 
     // Follow requests
     startFetchingFollowRequests (store) {
-      if (store.state.fetchers['followRequests']) return
+      if (store.state.fetchers.followRequests) return
       const fetcher = store.state.backendInteractor.startFetchingFollowRequests({ store })
 
       store.commit('addFetcher', { fetcherName: 'followRequests', fetcher })
@@ -244,7 +244,7 @@ const api = {
       store.commit('removeFetcher', { fetcherName: 'followRequests', fetcher })
     },
     removeFollowRequest (store, request) {
-      let requests = store.state.followRequests.filter((it) => it !== request)
+      const requests = store.state.followRequests.filter((it) => it !== request)
       store.commit('setFollowRequests', requests)
     },
 
diff --git a/src/modules/config.js b/src/modules/config.js
index f7f142ad..eaf67a91 100644
--- a/src/modules/config.js
+++ b/src/modules/config.js
@@ -147,7 +147,7 @@ const config = {
       const knownKeys = new Set(Object.keys(defaultState))
       const presentKeys = new Set(Object.keys(data))
       const intersection = new Set()
-      for (let elem of presentKeys) {
+      for (const elem of presentKeys) {
         if (knownKeys.has(elem)) {
           intersection.add(elem)
         }
diff --git a/src/modules/errors.js b/src/modules/errors.js
index ca89dc0f..d2e24100 100644
--- a/src/modules/errors.js
+++ b/src/modules/errors.js
@@ -2,8 +2,8 @@ import { capitalize } from 'lodash'
 
 export function humanizeErrors (errors) {
   return Object.entries(errors).reduce((errs, [k, val]) => {
-    let message = val.reduce((acc, message) => {
-      let key = capitalize(k.replace(/_/g, ' '))
+    const message = val.reduce((acc, message) => {
+      const key = capitalize(k.replace(/_/g, ' '))
       return acc + [key, message].join(' ') + '. '
     }, '')
     return [...errs, message]
diff --git a/src/modules/serverSideConfig.js b/src/modules/serverSideConfig.js
index 4b73af26..476263bc 100644
--- a/src/modules/serverSideConfig.js
+++ b/src/modules/serverSideConfig.js
@@ -39,53 +39,53 @@ const notificationsApi = ({ rootState, commit }, { path, value, oldValue }) => {
  * If no api is specified, defaultApi is used (see above)
  */
 export const settingsMap = {
-  'defaultScope': 'source.privacy',
-  'defaultNSFW': 'source.sensitive', // BROKEN: pleroma/pleroma#2837
-  'stripRichContent': {
+  defaultScope: 'source.privacy',
+  defaultNSFW: 'source.sensitive', // BROKEN: pleroma/pleroma#2837
+  stripRichContent: {
     get: 'source.pleroma.no_rich_text',
     set: 'no_rich_text'
   },
   // Privacy
-  'locked': 'locked',
-  'acceptChatMessages': {
+  locked: 'locked',
+  acceptChatMessages: {
     get: 'pleroma.accepts_chat_messages',
     set: 'accepts_chat_messages'
   },
-  'allowFollowingMove': {
+  allowFollowingMove: {
     get: 'pleroma.allow_following_move',
     set: 'allow_following_move'
   },
-  'discoverable': {
+  discoverable: {
     get: 'source.pleroma.discoverable',
     set: 'discoverable'
   },
-  'hideFavorites': {
+  hideFavorites: {
     get: 'pleroma.hide_favorites',
     set: 'hide_favorites'
   },
-  'hideFollowers': {
+  hideFollowers: {
     get: 'pleroma.hide_followers',
     set: 'hide_followers'
   },
-  'hideFollows': {
+  hideFollows: {
     get: 'pleroma.hide_follows',
     set: 'hide_follows'
   },
-  'hideFollowersCount': {
+  hideFollowersCount: {
     get: 'pleroma.hide_followers_count',
     set: 'hide_followers_count'
   },
-  'hideFollowsCount': {
+  hideFollowsCount: {
     get: 'pleroma.hide_follows_count',
     set: 'hide_follows_count'
   },
   // NotificationSettingsAPIs
-  'webPushHideContents': {
+  webPushHideContents: {
     get: 'pleroma.notification_settings.hide_notification_contents',
     set: 'hide_notification_contents',
     api: notificationsApi
   },
-  'blockNotificationsFromStrangers': {
+  blockNotificationsFromStrangers: {
     get: 'pleroma.notification_settings.block_from_strangers',
     set: 'block_from_strangers',
     api: notificationsApi
diff --git a/src/modules/statuses.js b/src/modules/statuses.js
index a13930e9..67026832 100644
--- a/src/modules/statuses.js
+++ b/src/modules/statuses.js
@@ -245,10 +245,10 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
   }
 
   const processors = {
-    'status': (status) => {
+    status: (status) => {
       addStatus(status, showImmediately)
     },
-    'retweet': (status) => {
+    retweet: (status) => {
       // RetweetedStatuses are never shown immediately
       const retweetedStatus = addStatus(status.retweeted_status, false, false)
 
@@ -270,7 +270,7 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
 
       retweet.retweeted_status = retweetedStatus
     },
-    'favorite': (favorite) => {
+    favorite: (favorite) => {
       // Only update if this is a new favorite.
       // Ignore our own favorites because we get info about likes as response to like request
       if (!state.favorites.has(favorite.id)) {
@@ -278,7 +278,7 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
         favoriteStatus(favorite)
       }
     },
-    'deletion': (deletion) => {
+    deletion: (deletion) => {
       const uri = deletion.uri
       const status = find(allStatuses, { uri })
       if (!status) {
@@ -292,10 +292,10 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
         remove(timelineObject.visibleStatuses, { uri })
       }
     },
-    'follow': (follow) => {
+    follow: (follow) => {
       // NOOP, it is known status but we don't do anything about it for now
     },
-    'default': (unknown) => {
+    default: (unknown) => {
       console.log('unknown status type')
       console.log(unknown)
     }
@@ -303,7 +303,7 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
 
   each(statuses, (status) => {
     const type = status.type
-    const processor = processors[type] || processors['default']
+    const processor = processors[type] || processors.default
     processor(status)
   })
 
@@ -522,7 +522,7 @@ export const mutations = {
   },
   addEmojiReactionsBy (state, { id, emojiReactions, currentUser }) {
     const status = state.allStatusesObject[id]
-    status['emoji_reactions'] = emojiReactions
+    status.emoji_reactions = emojiReactions
   },
   addOwnReaction (state, { id, emoji, currentUser }) {
     const status = state.allStatusesObject[id]
@@ -543,7 +543,7 @@ export const mutations = {
     if (reactionIndex >= 0) {
       status.emoji_reactions[reactionIndex] = newReaction
     } else {
-      status['emoji_reactions'] = [...status.emoji_reactions, newReaction]
+      status.emoji_reactions = [...status.emoji_reactions, newReaction]
     }
   },
   removeOwnReaction (state, { id, emoji, currentUser }) {
@@ -564,7 +564,7 @@ export const mutations = {
     if (newReaction.count > 0) {
       status.emoji_reactions[reactionIndex] = newReaction
     } else {
-      status['emoji_reactions'] = status.emoji_reactions.filter(r => r.name !== emoji)
+      status.emoji_reactions = status.emoji_reactions.filter(r => r.name !== emoji)
     }
   },
   updateStatusWithPoll (state, { id, poll }) {
diff --git a/src/modules/users.js b/src/modules/users.js
index f951483f..13d4e318 100644
--- a/src/modules/users.js
+++ b/src/modules/users.js
@@ -103,23 +103,23 @@ export const mutations = {
     const user = state.usersObject[id]
     const tags = user.tags || []
     const newTags = tags.concat([tag])
-    user['tags'] = newTags
+    user.tags = newTags
   },
   untagUser (state, { user: { id }, tag }) {
     const user = state.usersObject[id]
     const tags = user.tags || []
     const newTags = tags.filter(t => t !== tag)
-    user['tags'] = newTags
+    user.tags = newTags
   },
   updateRight (state, { user: { id }, right, value }) {
     const user = state.usersObject[id]
-    let newRights = user.rights
+    const newRights = user.rights
     newRights[right] = value
-    user['rights'] = newRights
+    user.rights = newRights
   },
   updateActivationStatus (state, { user: { id }, deactivated }) {
     const user = state.usersObject[id]
-    user['deactivated'] = deactivated
+    user.deactivated = deactivated
   },
   setCurrentUser (state, user) {
     state.lastLoginName = user.screen_name
@@ -148,13 +148,13 @@ export const mutations = {
   clearFriends (state, userId) {
     const user = state.usersObject[userId]
     if (user) {
-      user['friendIds'] = []
+      user.friendIds = []
     }
   },
   clearFollowers (state, userId) {
     const user = state.usersObject[userId]
     if (user) {
-      user['followerIds'] = []
+      user.followerIds = []
     }
   },
   addNewUsers (state, users) {
@@ -222,7 +222,7 @@ export const mutations = {
   },
   setColor (state, { user: { id }, highlighted }) {
     const user = state.usersObject[id]
-    user['highlight'] = highlighted
+    user.highlight = highlighted
   },
   signUpPending (state) {
     state.signUpPending = true
@@ -393,7 +393,7 @@ const users = {
     toggleActivationStatus ({ rootState, commit }, { user }) {
       const api = user.deactivated ? rootState.api.backendInteractor.activateUser : rootState.api.backendInteractor.deactivateUser
       api({ user })
-        .then((user) => { let deactivated = !user.is_active; commit('updateActivationStatus', { user, deactivated }) })
+        .then((user) => { const deactivated = !user.is_active; commit('updateActivationStatus', { user, deactivated }) })
     },
     registerPushNotifications (store) {
       const token = store.state.currentUser.credentials
@@ -457,17 +457,17 @@ const users = {
     async signUp (store, userInfo) {
       store.commit('signUpPending')
 
-      let rootState = store.rootState
+      const rootState = store.rootState
 
       try {
-        let data = await rootState.api.backendInteractor.register(
+        const data = await rootState.api.backendInteractor.register(
           { params: { ...userInfo } }
         )
         store.commit('signUpSuccess')
         store.commit('setToken', data.access_token)
         store.dispatch('loginUser', data.access_token)
       } catch (e) {
-        let errors = e.message
+        const errors = e.message
         store.commit('signUpFailure', errors)
         throw e
       }
diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js
index e413baee..da3bccc5 100644
--- a/src/services/api/api.service.js
+++ b/src/services/api/api.service.js
@@ -76,7 +76,7 @@ const MASTODON_PIN_OWN_STATUS = id => `/api/v1/statuses/${id}/pin`
 const MASTODON_UNPIN_OWN_STATUS = id => `/api/v1/statuses/${id}/unpin`
 const MASTODON_MUTE_CONVERSATION = id => `/api/v1/statuses/${id}/mute`
 const MASTODON_UNMUTE_CONVERSATION = id => `/api/v1/statuses/${id}/unmute`
-const MASTODON_SEARCH_2 = `/api/v2/search`
+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'
@@ -84,7 +84,7 @@ 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}`
-const PLEROMA_CHATS_URL = `/api/v1/pleroma/chats`
+const PLEROMA_CHATS_URL = '/api/v1/pleroma/chats'
 const PLEROMA_CHAT_URL = id => `/api/v1/pleroma/chats/by-account-id/${id}`
 const PLEROMA_CHAT_MESSAGES_URL = id => `/api/v1/pleroma/chats/${id}/messages`
 const PLEROMA_CHAT_READ_URL = id => `/api/v1/pleroma/chats/${id}/read`
@@ -93,7 +93,7 @@ const PLEROMA_BACKUP_URL = '/api/v1/pleroma/backups'
 
 const oldfetch = window.fetch
 
-let fetch = (url, options) => {
+const fetch = (url, options) => {
   options = options || {}
   const baseUrl = ''
   const fullUrl = baseUrl + url
@@ -105,7 +105,7 @@ const promisedRequest = ({ method, url, params, payload, credentials, headers =
   const options = {
     method,
     headers: {
-      'Accept': 'application/json',
+      Accept: 'application/json',
       'Content-Type': 'application/json',
       ...headers
     }
@@ -229,16 +229,16 @@ const getCaptcha = () => fetch('/api/pleroma/captcha').then(resp => resp.json())
 
 const authHeaders = (accessToken) => {
   if (accessToken) {
-    return { 'Authorization': `Bearer ${accessToken}` }
+    return { Authorization: `Bearer ${accessToken}` }
   } else {
     return { }
   }
 }
 
 const followUser = ({ id, credentials, ...options }) => {
-  let url = MASTODON_FOLLOW_URL(id)
+  const url = MASTODON_FOLLOW_URL(id)
   const form = {}
-  if (options.reblogs !== undefined) { form['reblogs'] = options.reblogs }
+  if (options.reblogs !== undefined) { form.reblogs = options.reblogs }
   return fetch(url, {
     body: JSON.stringify(form),
     headers: {
@@ -250,7 +250,7 @@ const followUser = ({ id, credentials, ...options }) => {
 }
 
 const unfollowUser = ({ id, credentials }) => {
-  let url = MASTODON_UNFOLLOW_URL(id)
+  const url = MASTODON_UNFOLLOW_URL(id)
   return fetch(url, {
     headers: authHeaders(credentials),
     method: 'POST'
@@ -292,7 +292,7 @@ const unblockUser = ({ id, credentials }) => {
 }
 
 const approveUser = ({ id, credentials }) => {
-  let url = MASTODON_APPROVE_USER_URL(id)
+  const url = MASTODON_APPROVE_USER_URL(id)
   return fetch(url, {
     headers: authHeaders(credentials),
     method: 'POST'
@@ -300,7 +300,7 @@ const approveUser = ({ id, credentials }) => {
 }
 
 const denyUser = ({ id, credentials }) => {
-  let url = MASTODON_DENY_USER_URL(id)
+  const url = MASTODON_DENY_USER_URL(id)
   return fetch(url, {
     headers: authHeaders(credentials),
     method: 'POST'
@@ -308,13 +308,13 @@ const denyUser = ({ id, credentials }) => {
 }
 
 const fetchUser = ({ id, credentials }) => {
-  let url = `${MASTODON_USER_URL}/${id}`
+  const url = `${MASTODON_USER_URL}/${id}`
   return promisedRequest({ url, credentials })
     .then((data) => parseUser(data))
 }
 
 const fetchUserRelationship = ({ id, credentials }) => {
-  let url = `${MASTODON_USER_RELATIONSHIPS_URL}/?id=${id}`
+  const url = `${MASTODON_USER_RELATIONSHIPS_URL}/?id=${id}`
   return fetch(url, { headers: authHeaders(credentials) })
     .then((response) => {
       return new Promise((resolve, reject) => response.json()
@@ -333,7 +333,7 @@ const fetchFriends = ({ id, maxId, sinceId, limit = 20, credentials }) => {
     maxId && `max_id=${maxId}`,
     sinceId && `since_id=${sinceId}`,
     limit && `limit=${limit}`,
-    `with_relationships=true`
+    'with_relationships=true'
   ].filter(_ => _).join('&')
 
   url = url + (args ? '?' + args : '')
@@ -368,7 +368,7 @@ const fetchFollowers = ({ id, maxId, sinceId, limit = 20, credentials }) => {
     maxId && `max_id=${maxId}`,
     sinceId && `since_id=${sinceId}`,
     limit && `limit=${limit}`,
-    `with_relationships=true`
+    'with_relationships=true'
   ].filter(_ => _).join('&')
 
   url += args ? '?' + args : ''
@@ -385,7 +385,7 @@ const fetchFollowRequests = ({ credentials }) => {
 }
 
 const fetchConversation = ({ id, credentials }) => {
-  let urlContext = MASTODON_STATUS_CONTEXT_URL(id)
+  const urlContext = MASTODON_STATUS_CONTEXT_URL(id)
   return fetch(urlContext, { headers: authHeaders(credentials) })
     .then((data) => {
       if (data.ok) {
@@ -401,7 +401,7 @@ const fetchConversation = ({ id, credentials }) => {
 }
 
 const fetchStatus = ({ id, credentials }) => {
-  let url = MASTODON_STATUS_URL(id)
+  const url = MASTODON_STATUS_URL(id)
   return fetch(url, { headers: authHeaders(credentials) })
     .then((data) => {
       if (data.ok) {
@@ -425,7 +425,7 @@ const tagUser = ({ tag, credentials, user }) => {
 
   return fetch(TAG_USER_URL, {
     method: 'PUT',
-    headers: headers,
+    headers,
     body: JSON.stringify(form)
   })
 }
@@ -442,7 +442,7 @@ const untagUser = ({ tag, credentials, user }) => {
 
   return fetch(TAG_USER_URL, {
     method: 'DELETE',
-    headers: headers,
+    headers,
     body: JSON.stringify(body)
   })
 }
@@ -495,7 +495,7 @@ const deleteUser = ({ credentials, user }) => {
 
   return fetch(`${ADMIN_USERS_URL}?nickname=${screenName}`, {
     method: 'DELETE',
-    headers: headers
+    headers
   })
 }
 
@@ -514,7 +514,7 @@ const fetchTimeline = ({
     friends: MASTODON_USER_HOME_TIMELINE_URL,
     dms: MASTODON_DIRECT_MESSAGES_TIMELINE_URL,
     notifications: MASTODON_USER_NOTIFICATIONS_URL,
-    'publicAndExternal': MASTODON_PUBLIC_TIMELINE,
+    publicAndExternal: MASTODON_PUBLIC_TIMELINE,
     user: MASTODON_USER_TIMELINE_URL,
     media: MASTODON_USER_TIMELINE_URL,
     favorites: MASTODON_USER_FAVORITES_TIMELINE_URL,
@@ -688,7 +688,7 @@ const postStatus = ({
     form.append('preview', 'true')
   }
 
-  let postHeaders = authHeaders(credentials)
+  const postHeaders = authHeaders(credentials)
   if (idempotencyKey) {
     postHeaders['idempotency-key'] = idempotencyKey
   }
@@ -993,7 +993,7 @@ const vote = ({ pollId, choices, credentials }) => {
     method: 'POST',
     credentials,
     payload: {
-      choices: choices
+      choices
     }
   })
 }
@@ -1053,8 +1053,8 @@ const reportUser = ({ credentials, userId, statusIds, comment, forward }) => {
     url: MASTODON_REPORT_USER_URL,
     method: 'POST',
     payload: {
-      'account_id': userId,
-      'status_ids': statusIds,
+      account_id: userId,
+      status_ids: statusIds,
       comment,
       forward
     },
@@ -1076,7 +1076,7 @@ const searchUsers = ({ credentials, query }) => {
 
 const search2 = ({ credentials, q, resolve, limit, offset, following }) => {
   let url = MASTODON_SEARCH_2
-  let params = []
+  const params = []
 
   if (q) {
     params.push(['q', encodeURIComponent(q)])
@@ -1100,7 +1100,7 @@ const search2 = ({ credentials, q, resolve, limit, offset, following }) => {
 
   params.push(['with_relationships', true])
 
-  let queryString = map(params, (param) => `${param[0]}=${param[1]}`).join('&')
+  const queryString = map(params, (param) => `${param[0]}=${param[1]}`).join('&')
   url += `?${queryString}`
 
   return fetch(url, { headers: authHeaders(credentials) })
@@ -1254,12 +1254,12 @@ export const handleMastoWS = (wsEvent) => {
 }
 
 export const WSConnectionStatus = Object.freeze({
-  'JOINED': 1,
-  'CLOSED': 2,
-  'ERROR': 3,
-  'DISABLED': 4,
-  'STARTING': 5,
-  'STARTING_INITIAL': 6
+  JOINED: 1,
+  CLOSED: 2,
+  ERROR: 3,
+  DISABLED: 4,
+  STARTING: 5,
+  STARTING_INITIAL: 6
 })
 
 const chats = ({ credentials }) => {
@@ -1297,11 +1297,11 @@ const chatMessages = ({ id, credentials, maxId, sinceId, limit = 20 }) => {
 
 const sendChatMessage = ({ id, content, mediaId = null, idempotencyKey, credentials }) => {
   const payload = {
-    'content': content
+    content
   }
 
   if (mediaId) {
-    payload['media_id'] = mediaId
+    payload.media_id = mediaId
   }
 
   const headers = {}
@@ -1313,7 +1313,7 @@ const sendChatMessage = ({ id, content, mediaId = null, idempotencyKey, credenti
   return promisedRequest({
     url: PLEROMA_CHAT_MESSAGES_URL(id),
     method: 'POST',
-    payload: payload,
+    payload,
     credentials,
     headers
   })
@@ -1324,7 +1324,7 @@ const readChat = ({ id, lastReadId, credentials }) => {
     url: PLEROMA_CHAT_READ_URL(id),
     method: 'POST',
     payload: {
-      'last_read_id': lastReadId
+      last_read_id: lastReadId
     },
     credentials
   })
diff --git a/src/services/chat_service/chat_service.js b/src/services/chat_service/chat_service.js
index 92ff689d..eb26a0ab 100644
--- a/src/services/chat_service/chat_service.js
+++ b/src/services/chat_service/chat_service.js
@@ -7,7 +7,7 @@ const empty = (chatId) => {
     messages: [],
     newMessageCount: 0,
     lastSeenMessageId: '0',
-    chatId: chatId,
+    chatId,
     minId: undefined,
     maxId: undefined
   }
@@ -101,7 +101,7 @@ const add = (storage, { messages: newMessages, updateMaxId = true }) => {
           storage.messages = storage.messages.filter(msg => msg.id !== message.id)
         }
         Object.assign(fakeMessage, message, { error: false })
-        delete fakeMessage['fakeId']
+        delete fakeMessage.fakeId
         storage.idIndex[fakeMessage.id] = fakeMessage
         delete storage.idIndex[message.fakeId]
 
@@ -178,7 +178,7 @@ const getView = (storage) => {
         id: date.getTime().toString()
       })
 
-      previousMessage['isTail'] = true
+      previousMessage.isTail = true
       currentMessageChainId = undefined
       afterDate = true
     }
@@ -193,15 +193,15 @@ const getView = (storage) => {
 
     // end a message chian
     if ((nextMessage && nextMessage.account_id) !== message.account_id) {
-      object['isTail'] = true
+      object.isTail = true
       currentMessageChainId = undefined
     }
 
     // start a new message chain
     if ((previousMessage && previousMessage.data && previousMessage.data.account_id) !== message.account_id || afterDate) {
       currentMessageChainId = _.uniqueId()
-      object['isHead'] = true
-      object['messageChainId'] = currentMessageChainId
+      object.isHead = true
+      object.messageChainId = currentMessageChainId
     }
 
     result.push(object)
diff --git a/src/services/chat_utils/chat_utils.js b/src/services/chat_utils/chat_utils.js
index de6e0625..a8da1eed 100644
--- a/src/services/chat_utils/chat_utils.js
+++ b/src/services/chat_utils/chat_utils.js
@@ -25,7 +25,7 @@ export const buildFakeMessage = ({ content, chatId, attachments, userId, idempot
     chat_id: chatId,
     created_at: new Date(),
     id: `${new Date().getTime()}`,
-    attachments: attachments,
+    attachments,
     account_id: userId,
     idempotency_key: idempotencyKey,
     emojis: [],
diff --git a/src/services/color_convert/color_convert.js b/src/services/color_convert/color_convert.js
index ec104269..47d6344e 100644
--- a/src/services/color_convert/color_convert.js
+++ b/src/services/color_convert/color_convert.js
@@ -144,11 +144,13 @@ export const invert = (rgb) => {
  */
 export const hex2rgb = (hex) => {
   const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
-  return result ? {
-    r: parseInt(result[1], 16),
-    g: parseInt(result[2], 16),
-    b: parseInt(result[3], 16)
-  } : null
+  return result
+    ? {
+        r: parseInt(result[1], 16),
+        g: parseInt(result[2], 16),
+        b: parseInt(result[3], 16)
+      }
+    : null
 }
 
 /**
diff --git a/src/services/completion/completion.js b/src/services/completion/completion.js
index 8a6eba7e..8fa4f75b 100644
--- a/src/services/completion/completion.js
+++ b/src/services/completion/completion.js
@@ -35,7 +35,7 @@ export const addPositionToWords = (words) => {
 }
 
 export const splitByWhitespaceBoundary = (str) => {
-  let result = []
+  const result = []
   let currentWord = ''
   for (let i = 0; i < str.length; i++) {
     const currentChar = str[i]
diff --git a/src/services/date_utils/date_utils.js b/src/services/date_utils/date_utils.js
index 677c184c..c93d2176 100644
--- a/src/services/date_utils/date_utils.js
+++ b/src/services/date_utils/date_utils.js
@@ -10,7 +10,7 @@ export const relativeTime = (date, nowThreshold = 1) => {
   if (typeof date === 'string') date = Date.parse(date)
   const round = Date.now() > date ? Math.floor : Math.ceil
   const d = Math.abs(Date.now() - date)
-  let r = { num: round(d / YEAR), key: 'time.unit.years' }
+  const r = { num: round(d / YEAR), key: 'time.unit.years' }
   if (d < nowThreshold * SECOND) {
     r.num = 0
     r.key = 'time.now'
diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js
index f219c161..86472b42 100644
--- a/src/services/entity_normalizer/entity_normalizer.service.js
+++ b/src/services/entity_normalizer/entity_normalizer.service.js
@@ -371,8 +371,8 @@ export const parseStatus = (data) => {
 
 export const parseNotification = (data) => {
   const mastoDict = {
-    'favourite': 'like',
-    'reblog': 'repeat'
+    favourite: 'like',
+    reblog: 'repeat'
   }
   const masto = !data.hasOwnProperty('ntype')
   const output = {}
diff --git a/src/services/file_size_format/file_size_format.js b/src/services/file_size_format/file_size_format.js
index 7e6cd4d7..d481dfb0 100644
--- a/src/services/file_size_format/file_size_format.js
+++ b/src/services/file_size_format/file_size_format.js
@@ -1,7 +1,7 @@
 const fileSizeFormat = (num) => {
-  var exponent
-  var unit
-  var units = ['B', 'KiB', 'MiB', 'GiB', 'TiB']
+  let exponent
+  let unit
+  const units = ['B', 'KiB', 'MiB', 'GiB', 'TiB']
   if (num < 1) {
     return num + ' ' + units[0]
   }
@@ -9,7 +9,7 @@ const fileSizeFormat = (num) => {
   exponent = Math.min(Math.floor(Math.log(num) / Math.log(1024)), units.length - 1)
   num = (num / Math.pow(1024, exponent)).toFixed(2) * 1
   unit = units[exponent]
-  return { num: num, unit: unit }
+  return { num, unit }
 }
 const fileSizeFormatService = {
   fileSizeFormat
diff --git a/src/services/html_converter/html_line_converter.service.js b/src/services/html_converter/html_line_converter.service.js
index 5eeaa7cb..9c3d1f19 100644
--- a/src/services/html_converter/html_line_converter.service.js
+++ b/src/services/html_converter/html_line_converter.service.js
@@ -46,7 +46,7 @@ export const convertHtmlToLines = (html = '') => {
   // All block-level elements that aren't empty elements, i.e. not <hr>
   const nonEmptyElements = new Set(visualLineElements)
   // Difference
-  for (let elem of emptyElements) {
+  for (const elem of emptyElements) {
     nonEmptyElements.delete(elem)
   }
 
@@ -56,7 +56,7 @@ export const convertHtmlToLines = (html = '') => {
     ...emptyElements.values()
   ])
 
-  let buffer = [] // Current output buffer
+  const buffer = [] // Current output buffer
   const level = [] // How deep we are in tags and which tags were there
   let textBuffer = '' // Current line content
   let tagBuffer = null // Current tag buffer, if null = we are not currently reading a tag
diff --git a/src/services/html_converter/utility.service.js b/src/services/html_converter/utility.service.js
index 4d0c36c2..583ccca5 100644
--- a/src/services/html_converter/utility.service.js
+++ b/src/services/html_converter/utility.service.js
@@ -50,7 +50,7 @@ export const processTextForEmoji = (text, emojis, processor) => {
     if (char === ':') {
       const next = text.slice(i + 1)
       let found = false
-      for (let emoji of emojis) {
+      for (const emoji of emojis) {
         if (next.slice(0, emoji.shortcode.length + 1) === (emoji.shortcode + ':')) {
           found = emoji
           break
diff --git a/src/services/locale/locale.service.js b/src/services/locale/locale.service.js
index 8cef2522..d3389785 100644
--- a/src/services/locale/locale.service.js
+++ b/src/services/locale/locale.service.js
@@ -3,9 +3,9 @@ import ISO6391 from 'iso-639-1'
 import _ from 'lodash'
 
 const specialLanguageCodes = {
-  'ja_easy': 'ja',
-  'zh_Hant': 'zh-HANT',
-  'zh': 'zh-Hans'
+  ja_easy: 'ja',
+  zh_Hant: 'zh-HANT',
+  zh: 'zh-Hans'
 }
 
 const internalToBrowserLocale = code => specialLanguageCodes[code] || code
@@ -14,16 +14,16 @@ const internalToBackendLocale = code => internalToBrowserLocale(code).replace('_
 
 const getLanguageName = (code) => {
   const specialLanguageNames = {
-    'ja_easy': 'やさしいにほんご',
-    'zh': '简体中文',
-    'zh_Hant': '繁體中文'
+    ja_easy: 'やさしいにほんご',
+    zh: '简体中文',
+    zh_Hant: '繁體中文'
   }
   const languageName = specialLanguageNames[code] || ISO6391.getNativeName(code)
   const browserLocale = internalToBrowserLocale(code)
   return languageName.charAt(0).toLocaleUpperCase(browserLocale) + languageName.slice(1)
 }
 
-const languages = _.map(languagesObject.languages, (code) => ({ code: code, name: getLanguageName(code) })).sort((a, b) => a.name.localeCompare(b.name))
+const languages = _.map(languagesObject.languages, (code) => ({ code, name: getLanguageName(code) })).sort((a, b) => a.name.localeCompare(b.name))
 
 const localeService = {
   internalToBrowserLocale,
diff --git a/src/services/new_api/password_reset.js b/src/services/new_api/password_reset.js
index 43199625..9f3c27b5 100644
--- a/src/services/new_api/password_reset.js
+++ b/src/services/new_api/password_reset.js
@@ -1,6 +1,6 @@
 import { reduce } from 'lodash'
 
-const MASTODON_PASSWORD_RESET_URL = `/auth/password`
+const MASTODON_PASSWORD_RESET_URL = '/auth/password'
 
 const resetPassword = ({ instance, email }) => {
   const params = { email }
diff --git a/src/services/notifications_fetcher/notifications_fetcher.service.js b/src/services/notifications_fetcher/notifications_fetcher.service.js
index f83f871e..c0e299e4 100644
--- a/src/services/notifications_fetcher/notifications_fetcher.service.js
+++ b/src/services/notifications_fetcher/notifications_fetcher.service.js
@@ -12,20 +12,20 @@ const fetchAndUpdate = ({ store, credentials, older = false, since }) => {
   const timelineData = rootState.statuses.notifications
   const hideMutedPosts = getters.mergedConfig.hideMutedPosts
 
-  args['withMuted'] = !hideMutedPosts
+  args.withMuted = !hideMutedPosts
 
-  args['timeline'] = 'notifications'
+  args.timeline = 'notifications'
   if (older) {
     if (timelineData.minId !== Number.POSITIVE_INFINITY) {
-      args['until'] = timelineData.minId
+      args.until = timelineData.minId
     }
     return fetchNotifications({ store, args, older })
   } else {
     // fetch new notifications
     if (since === undefined && timelineData.maxId !== Number.POSITIVE_INFINITY) {
-      args['since'] = timelineData.maxId
+      args.since = timelineData.maxId
     } else if (since !== null) {
-      args['since'] = since
+      args.since = since
     }
     const result = fetchNotifications({ store, args, older })
 
@@ -38,7 +38,7 @@ const fetchAndUpdate = ({ store, credentials, older = false, since }) => {
     const readNotifsIds = notifications.filter(n => n.seen).map(n => n.id)
     const numUnseenNotifs = notifications.length - readNotifsIds.length
     if (numUnseenNotifs > 0 && readNotifsIds.length > 0) {
-      args['since'] = Math.max(...readNotifsIds)
+      args.since = Math.max(...readNotifsIds)
       fetchNotifications({ store, args, older })
     }
 
diff --git a/src/services/push/push.js b/src/services/push/push.js
index 5836fc26..40d7b0fd 100644
--- a/src/services/push/push.js
+++ b/src/services/push/push.js
@@ -43,7 +43,7 @@ function deleteSubscriptionFromBackEnd (token) {
     method: 'DELETE',
     headers: {
       'Content-Type': 'application/json',
-      'Authorization': `Bearer ${token}`
+      Authorization: `Bearer ${token}`
     }
   }).then((response) => {
     if (!response.ok) throw new Error('Bad status code from server.')
@@ -56,7 +56,7 @@ function sendSubscriptionToBackEnd (subscription, token, notificationVisibility)
     method: 'POST',
     headers: {
       'Content-Type': 'application/json',
-      'Authorization': `Bearer ${token}`
+      Authorization: `Bearer ${token}`
     },
     body: JSON.stringify({
       subscription,
diff --git a/src/services/theme_data/theme_data.service.js b/src/services/theme_data/theme_data.service.js
index b619f810..da48f02c 100644
--- a/src/services/theme_data/theme_data.service.js
+++ b/src/services/theme_data/theme_data.service.js
@@ -39,7 +39,7 @@ import { LAYERS, DEFAULT_OPACITY, SLOT_INHERITANCE } from './pleromafe.js'
 export const CURRENT_VERSION = 3
 
 export const getLayersArray = (layer, data = LAYERS) => {
-  let array = [layer]
+  const array = [layer]
   let parent = data[layer]
   while (parent) {
     array.unshift(parent)
diff --git a/src/services/timeline_fetcher/timeline_fetcher.service.js b/src/services/timeline_fetcher/timeline_fetcher.service.js
index 46bba41a..7ba138e0 100644
--- a/src/services/timeline_fetcher/timeline_fetcher.service.js
+++ b/src/services/timeline_fetcher/timeline_fetcher.service.js
@@ -34,20 +34,20 @@ const fetchAndUpdate = ({
   const loggedIn = !!rootState.users.currentUser
 
   if (older) {
-    args['until'] = until || timelineData.minId
+    args.until = until || timelineData.minId
   } else {
     if (since === undefined) {
-      args['since'] = timelineData.maxId
+      args.since = timelineData.maxId
     } else if (since !== null) {
-      args['since'] = since
+      args.since = since
     }
   }
 
-  args['userId'] = userId
-  args['tag'] = tag
-  args['withMuted'] = !hideMutedPosts
+  args.userId = userId
+  args.tag = tag
+  args.withMuted = !hideMutedPosts
   if (loggedIn && ['friends', 'public', 'publicAndExternal'].includes(timeline)) {
-    args['replyVisibility'] = replyVisibility
+    args.replyVisibility = replyVisibility
   }
 
   const numStatusesBeforeFetch = timelineData.statuses.length
@@ -60,7 +60,7 @@ const fetchAndUpdate = ({
 
       const { data: statuses, pagination } = response
       if (!older && statuses.length >= 20 && !timelineData.loading && numStatusesBeforeFetch > 0) {
-        store.dispatch('queueFlush', { timeline: timeline, id: timelineData.maxId })
+        store.dispatch('queueFlush', { timeline, id: timelineData.maxId })
       }
       update({ store, statuses, timeline, showImmediately, userId, pagination })
       return { statuses, pagination }
diff --git a/src/services/user_highlighter/user_highlighter.js b/src/services/user_highlighter/user_highlighter.js
index 3b07592e..b5f58040 100644
--- a/src/services/user_highlighter/user_highlighter.js
+++ b/src/services/user_highlighter/user_highlighter.js
@@ -36,7 +36,7 @@ const highlightStyle = (prefs) => {
         'linear-gradient(to right,',
         `${solidColor} ,`,
         `${solidColor} 2px,`,
-        `transparent 6px`
+        'transparent 6px'
       ].join(' '),
       backgroundPosition: '0 0',
       ...customProps
diff --git a/src/sw.js b/src/sw.js
index 9118dd71..70fed44b 100644
--- a/src/sw.js
+++ b/src/sw.js
@@ -57,8 +57,8 @@ self.addEventListener('notificationclick', (event) => {
   event.notification.close()
 
   event.waitUntil(getWindowClients().then((list) => {
-    for (var i = 0; i < list.length; i++) {
-      var client = list[i]
+    for (let i = 0; i < list.length; i++) {
+      const client = list[i]
       if (client.url === '/' && 'focus' in client) { return client.focus() }
     }
 
diff --git a/test/e2e/custom-assertions/elementCount.js b/test/e2e/custom-assertions/elementCount.js
index c0d5fe00..5d5a57b9 100644
--- a/test/e2e/custom-assertions/elementCount.js
+++ b/test/e2e/custom-assertions/elementCount.js
@@ -16,7 +16,7 @@ exports.assertion = function (selector, count) {
     return res.value
   }
   this.command = function (cb) {
-    var self = this
+    const self = this
     return this.api.execute(function (selector) {
       return document.querySelectorAll(selector).length
     }, [selector], function (res) {
diff --git a/test/e2e/nightwatch.conf.js b/test/e2e/nightwatch.conf.js
index 07d974df..4041c698 100644
--- a/test/e2e/nightwatch.conf.js
+++ b/test/e2e/nightwatch.conf.js
@@ -1,45 +1,45 @@
 require('@babel/register')
-var config = require('../../config')
+const config = require('../../config')
 
 // http://nightwatchjs.org/guide#settings-file
 module.exports = {
-  'src_folders': ['test/e2e/specs'],
-  'output_folder': 'test/e2e/reports',
-  'custom_assertions_path': ['test/e2e/custom-assertions'],
+  src_folders: ['test/e2e/specs'],
+  output_folder: 'test/e2e/reports',
+  custom_assertions_path: ['test/e2e/custom-assertions'],
 
-  'selenium': {
-    'start_process': true,
-    'server_path': 'node_modules/selenium-server/lib/runner/selenium-server-standalone-2.53.1.jar',
-    'host': '127.0.0.1',
-    'port': 4444,
-    'cli_args': {
+  selenium: {
+    start_process: true,
+    server_path: 'node_modules/selenium-server/lib/runner/selenium-server-standalone-2.53.1.jar',
+    host: '127.0.0.1',
+    port: 4444,
+    cli_args: {
       'webdriver.chrome.driver': require('chromedriver').path
     }
   },
 
-  'test_settings': {
-    'default': {
-      'selenium_port': 4444,
-      'selenium_host': 'localhost',
-      'silent': true,
-      'globals': {
-        'devServerURL': 'http://localhost:' + (process.env.PORT || config.dev.port)
+  test_settings: {
+    default: {
+      selenium_port: 4444,
+      selenium_host: 'localhost',
+      silent: true,
+      globals: {
+        devServerURL: 'http://localhost:' + (process.env.PORT || config.dev.port)
       }
     },
 
-    'chrome': {
-      'desiredCapabilities': {
-        'browserName': 'chrome',
-        'javascriptEnabled': true,
-        'acceptSslCerts': true
+    chrome: {
+      desiredCapabilities: {
+        browserName: 'chrome',
+        javascriptEnabled: true,
+        acceptSslCerts: true
       }
     },
 
-    'firefox': {
-      'desiredCapabilities': {
-        'browserName': 'firefox',
-        'javascriptEnabled': true,
-        'acceptSslCerts': true
+    firefox: {
+      desiredCapabilities: {
+        browserName: 'firefox',
+        javascriptEnabled: true,
+        acceptSslCerts: true
       }
     }
   }
diff --git a/test/e2e/runner.js b/test/e2e/runner.js
index 2a5c6ef9..57abc2e1 100644
--- a/test/e2e/runner.js
+++ b/test/e2e/runner.js
@@ -1,6 +1,6 @@
 // 1. start the dev server using production config
 process.env.NODE_ENV = 'testing'
-var server = require('../../build/dev-server.js')
+const server = require('../../build/dev-server.js')
 
 // 2. run the nightwatch test suite against it
 // to run in additional browsers:
@@ -9,7 +9,7 @@ var server = require('../../build/dev-server.js')
 // or override the environment flag, for example: `npm run e2e -- --env chrome,firefox`
 // For more information on Nightwatch's config file, see
 // http://nightwatchjs.org/guide#settings-file
-var opts = process.argv.slice(2)
+let opts = process.argv.slice(2)
 if (opts.indexOf('--config') === -1) {
   opts = opts.concat(['--config', 'test/e2e/nightwatch.conf.js'])
 }
@@ -17,8 +17,8 @@ if (opts.indexOf('--env') === -1) {
   opts = opts.concat(['--env', 'chrome'])
 }
 
-var spawn = require('cross-spawn')
-var runner = spawn('./node_modules/.bin/nightwatch', opts, { stdio: 'inherit' })
+const spawn = require('cross-spawn')
+const runner = spawn('./node_modules/.bin/nightwatch', opts, { stdio: 'inherit' })
 
 runner.on('exit', function (code) {
   server.close()
diff --git a/test/unit/karma.conf.js b/test/unit/karma.conf.js
index 45d74f14..8959e009 100644
--- a/test/unit/karma.conf.js
+++ b/test/unit/karma.conf.js
@@ -4,14 +4,14 @@
 //   https://github.com/webpack/karma-webpack
 
 // var path = require('path')
-var merge = require('webpack-merge')
-var HtmlWebpackPlugin = require('html-webpack-plugin')
-var baseConfig = require('../../build/webpack.base.conf')
-var utils = require('../../build/utils')
-var webpack = require('webpack')
+const merge = require('webpack-merge')
+const HtmlWebpackPlugin = require('html-webpack-plugin')
+const baseConfig = require('../../build/webpack.base.conf')
+const utils = require('../../build/utils')
+const webpack = require('webpack')
 // var projectRoot = path.resolve(__dirname, '../../')
 
-var webpackConfig = merge(baseConfig, {
+const webpackConfig = merge(baseConfig, {
   // use inline sourcemap for karma-sourcemap-loader
   module: {
     rules: utils.styleLoaders()
@@ -63,7 +63,7 @@ module.exports = function (config) {
     frameworks: ['mocha', 'sinon-chai'],
     reporters: ['mocha'],
     customLaunchers: {
-      'FirefoxHeadless': {
+      FirefoxHeadless: {
         base: 'Firefox',
         flags: [
           '-headless'
diff --git a/test/unit/specs/components/emoji_input.spec.js b/test/unit/specs/components/emoji_input.spec.js
index 6188308e..752111ef 100644
--- a/test/unit/specs/components/emoji_input.spec.js
+++ b/test/unit/specs/components/emoji_input.spec.js
@@ -29,7 +29,7 @@ const generateInput = (value, padEmoji = true) => {
       modelValue: value
     },
     slots: {
-      'default': () => h('input', '')
+      default: () => h('input', '')
     }
   })
   return wrapper
diff --git a/test/unit/specs/components/rich_content.spec.js b/test/unit/specs/components/rich_content.spec.js
index 8a18a08b..616df6a0 100644
--- a/test/unit/specs/components/rich_content.spec.js
+++ b/test/unit/specs/components/rich_content.spec.js
@@ -4,7 +4,7 @@ import RichContent from 'src/components/rich_content/rich_content.jsx'
 const attentions = []
 const global = {
   mocks: {
-    '$store': {
+    $store: {
       state: {},
       getters: {
         mergedConfig: () => ({
diff --git a/test/unit/specs/components/user_profile.spec.js b/test/unit/specs/components/user_profile.spec.js
index 584758f7..0fbab722 100644
--- a/test/unit/specs/components/user_profile.spec.js
+++ b/test/unit/specs/components/user_profile.spec.js
@@ -163,7 +163,7 @@ const localProfileStore = createStore({
       currentUser: {
         credentials: ''
       },
-      usersObject: { 100: localUser, 'testuser': localUser },
+      usersObject: { 100: localUser, testuser: localUser },
       users: [localUser],
       relationships: {}
     }
@@ -175,7 +175,7 @@ describe.skip('UserProfile', () => {
   it('renders external profile', () => {
     const wrapper = mount(UserProfile, {
       global: {
-        plugins: [ externalProfileStore ],
+        plugins: [externalProfileStore],
         mocks: {
           $route: {
             params: { id: 100 },
@@ -192,7 +192,7 @@ describe.skip('UserProfile', () => {
   it('renders local profile', () => {
     const wrapper = mount(UserProfile, {
       global: {
-        plugins: [ localProfileStore ],
+        plugins: [localProfileStore],
         mocks: {
           $route: {
             params: { name: 'testUser' },
diff --git a/test/unit/specs/modules/statuses.spec.js b/test/unit/specs/modules/statuses.spec.js
index b790b231..a8d0e5a3 100644
--- a/test/unit/specs/modules/statuses.spec.js
+++ b/test/unit/specs/modules/statuses.spec.js
@@ -245,7 +245,7 @@ describe('Statuses module', () => {
     it('increments count in existing reaction', () => {
       const state = defaultState()
       const status = makeMockStatus({ id: '1' })
-      status.emoji_reactions = [ { name: '😂', count: 1, accounts: [] } ]
+      status.emoji_reactions = [{ name: '😂', count: 1, accounts: [] }]
 
       mutations.addNewStatuses(state, { statuses: [status], showImmediately: true, timeline: 'public' })
       mutations.addOwnReaction(state, { id: '1', emoji: '😂', currentUser: { id: 'me' } })
@@ -269,7 +269,7 @@ describe('Statuses module', () => {
     it('decreases count in existing reaction', () => {
       const state = defaultState()
       const status = makeMockStatus({ id: '1' })
-      status.emoji_reactions = [ { name: '😂', count: 2, accounts: [{ id: 'me' }] } ]
+      status.emoji_reactions = [{ name: '😂', count: 2, accounts: [{ id: 'me' }] }]
 
       mutations.addNewStatuses(state, { statuses: [status], showImmediately: true, timeline: 'public' })
       mutations.removeOwnReaction(state, { id: '1', emoji: '😂', currentUser: { id: 'me' } })
diff --git a/test/unit/specs/services/chat_service/chat_service.spec.js b/test/unit/specs/services/chat_service/chat_service.spec.js
index fbbca436..a42269b4 100644
--- a/test/unit/specs/services/chat_service/chat_service.spec.js
+++ b/test/unit/specs/services/chat_service/chat_service.spec.js
@@ -24,23 +24,23 @@ describe('chatService', () => {
   describe('.add', () => {
     it("Doesn't add duplicates", () => {
       const chat = chatService.empty()
-      chatService.add(chat, { messages: [ message1 ] })
-      chatService.add(chat, { messages: [ message1 ] })
+      chatService.add(chat, { messages: [message1] })
+      chatService.add(chat, { messages: [message1] })
       expect(chat.messages.length).to.eql(1)
 
-      chatService.add(chat, { messages: [ message2 ] })
+      chatService.add(chat, { messages: [message2] })
       expect(chat.messages.length).to.eql(2)
     })
 
     it('Updates minId and lastMessage and newMessageCount', () => {
       const chat = chatService.empty()
 
-      chatService.add(chat, { messages: [ message1 ] })
+      chatService.add(chat, { messages: [message1] })
       expect(chat.maxId).to.eql(message1.id)
       expect(chat.minId).to.eql(message1.id)
       expect(chat.newMessageCount).to.eql(1)
 
-      chatService.add(chat, { messages: [ message2 ] })
+      chatService.add(chat, { messages: [message2] })
       expect(chat.maxId).to.eql(message2.id)
       expect(chat.minId).to.eql(message1.id)
       expect(chat.newMessageCount).to.eql(2)
@@ -50,7 +50,7 @@ describe('chatService', () => {
       expect(chat.lastSeenMessageId).to.eql(message2.id)
 
       // Add message with higher id
-      chatService.add(chat, { messages: [ message3 ] })
+      chatService.add(chat, { messages: [message3] })
       expect(chat.newMessageCount).to.eql(1)
     })
   })
@@ -59,9 +59,9 @@ describe('chatService', () => {
     it('Updates minId and lastMessage', () => {
       const chat = chatService.empty()
 
-      chatService.add(chat, { messages: [ message1 ] })
-      chatService.add(chat, { messages: [ message2 ] })
-      chatService.add(chat, { messages: [ message3 ] })
+      chatService.add(chat, { messages: [message1] })
+      chatService.add(chat, { messages: [message2] })
+      chatService.add(chat, { messages: [message3] })
 
       expect(chat.maxId).to.eql(message3.id)
       expect(chat.minId).to.eql(message1.id)
@@ -80,9 +80,9 @@ describe('chatService', () => {
     it('Inserts date separators', () => {
       const chat = chatService.empty()
 
-      chatService.add(chat, { messages: [ message1 ] })
-      chatService.add(chat, { messages: [ message2 ] })
-      chatService.add(chat, { messages: [ message3 ] })
+      chatService.add(chat, { messages: [message1] })
+      chatService.add(chat, { messages: [message2] })
+      chatService.add(chat, { messages: [message3] })
 
       const view = chatService.getView(chat)
       expect(view.map(i => i.type)).to.eql(['date', 'message', 'message', 'date', 'message'])
diff --git a/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js b/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js
index 03fb32c9..525e57a5 100644
--- a/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js
+++ b/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js
@@ -314,8 +314,8 @@ describe('API Entities normalizer', () => {
       const linkHeader = '<https://example.com/api/v1/notifications?max_id=861676>; rel="next", <https://example.com/api/v1/notifications?min_id=861741>; rel="prev"'
       const result = parseLinkHeaderPagination(linkHeader)
       expect(result).to.eql({
-        'maxId': 861676,
-        'minId': 861741
+        maxId: 861676,
+        minId: 861741
       })
     })
 
@@ -323,8 +323,8 @@ describe('API Entities normalizer', () => {
       const linkHeader = '<http://example.com/api/v1/timelines/home?max_id=9waQx5IIS48qVue2Ai>; rel="next", <http://example.com/api/v1/timelines/home?min_id=9wi61nIPnfn674xgie>; rel="prev"'
       const result = parseLinkHeaderPagination(linkHeader, { flakeId: true })
       expect(result).to.eql({
-        'maxId': '9waQx5IIS48qVue2Ai',
-        'minId': '9wi61nIPnfn674xgie'
+        maxId: '9waQx5IIS48qVue2Ai',
+        minId: '9wi61nIPnfn674xgie'
       })
     })
   })
diff --git a/test/unit/specs/services/file_size_format/file_size_format.spec.js b/test/unit/specs/services/file_size_format/file_size_format.spec.js
index e02ac379..6804b6eb 100644
--- a/test/unit/specs/services/file_size_format/file_size_format.spec.js
+++ b/test/unit/specs/services/file_size_format/file_size_format.spec.js
@@ -25,8 +25,8 @@ describe('fileSizeFormat', () => {
       }
     ]
 
-    var res = []
-    for (var value in values) {
+    const res = []
+    for (const value in values) {
       res.push(fileSizeFormatService.fileSizeFormat(values[value]))
     }
     expect(res).to.eql(expected)
-- 
cgit v1.2.3-70-g09d2


From 0a79a747730bb4a10eb2544412dab68a10602240 Mon Sep 17 00:00:00 2001
From: Tusooa Zhu <tusooa@kazv.moe>
Date: Mon, 29 Aug 2022 18:46:41 -0400
Subject: Use dedicated indicator for non-ascii domain names

---
 src/components/basic_user_card/basic_user_card.js  |  4 ++-
 src/components/basic_user_card/basic_user_card.vue |  8 ++---
 src/components/emoji_input/emoji_input.js          |  4 ++-
 src/components/emoji_input/emoji_input.vue         | 16 ++++++++-
 src/components/emoji_input/suggestor.js            | 11 ++++---
 src/components/mention_link/mention_link.js        |  2 ++
 src/components/mention_link/mention_link.vue       |  3 ++
 src/components/notification/notification.js        |  4 ++-
 src/components/notification/notification.vue       | 21 ++++++------
 src/components/status/status.js                    |  4 ++-
 src/components/status/status.vue                   | 16 ++++-----
 .../unicode_domain_indicator.vue                   | 26 +++++++++++++++
 src/components/user_card/user_card.js              |  4 ++-
 src/components/user_card/user_card.vue             |  9 ++---
 src/components/user_link/user_link.vue             | 38 ++++++++++++++++++++++
 .../user_list_popover/user_list_popover.js         |  2 ++
 .../user_list_popover/user_list_popover.vue        |  2 +-
 .../user_reporting_modal/user_reporting_modal.js   |  4 ++-
 .../user_reporting_modal/user_reporting_modal.vue  | 10 ++++--
 src/i18n/en.json                                   |  3 ++
 .../entity_normalizer/entity_normalizer.service.js |  6 ++--
 .../entity_normalizer/entity_normalizer.spec.js    |  3 +-
 22 files changed, 151 insertions(+), 49 deletions(-)
 create mode 100644 src/components/unicode_domain_indicator/unicode_domain_indicator.vue
 create mode 100644 src/components/user_link/user_link.vue

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

diff --git a/src/components/basic_user_card/basic_user_card.js b/src/components/basic_user_card/basic_user_card.js
index 8b1a2c38..31de2d75 100644
--- a/src/components/basic_user_card/basic_user_card.js
+++ b/src/components/basic_user_card/basic_user_card.js
@@ -1,5 +1,6 @@
 import UserPopover from '../user_popover/user_popover.vue'
 import UserAvatar from '../user_avatar/user_avatar.vue'
+import UserLink from '../user_link/user_link.vue'
 import RichContent from 'src/components/rich_content/rich_content.jsx'
 import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
 
@@ -10,7 +11,8 @@ const BasicUserCard = {
   components: {
     UserPopover,
     UserAvatar,
-    RichContent
+    RichContent,
+    UserLink
   },
   methods: {
     userProfileLink (user) {
diff --git a/src/components/basic_user_card/basic_user_card.vue b/src/components/basic_user_card/basic_user_card.vue
index 9cca7840..418de926 100644
--- a/src/components/basic_user_card/basic_user_card.vue
+++ b/src/components/basic_user_card/basic_user_card.vue
@@ -30,12 +30,10 @@
         />
       </div>
       <div>
-        <router-link
+        <user-link
           class="basic-user-card-screen-name"
-          :to="userProfileLink(user)"
-        >
-          @{{ user.screen_name_ui }}
-        </router-link>
+          :user="user"
+        />
       </div>
       <slot />
     </div>
diff --git a/src/components/emoji_input/emoji_input.js b/src/components/emoji_input/emoji_input.js
index 5ba3907f..b664d6b3 100644
--- a/src/components/emoji_input/emoji_input.js
+++ b/src/components/emoji_input/emoji_input.js
@@ -1,5 +1,6 @@
 import Completion from '../../services/completion/completion.js'
 import EmojiPicker from '../emoji_picker/emoji_picker.vue'
+import UnicodeDomainIndicator from '../unicode_domain_indicator/unicode_domain_indicator.vue'
 import { take } from 'lodash'
 import { findOffset } from '../../services/offset_finder/offset_finder.service.js'
 
@@ -120,7 +121,8 @@ const EmojiInput = {
     }
   },
   components: {
-    EmojiPicker
+    EmojiPicker,
+    UnicodeDomainIndicator
   },
   computed: {
     padEmoji () {
diff --git a/src/components/emoji_input/emoji_input.vue b/src/components/emoji_input/emoji_input.vue
index 7d95ab7e..81b81913 100644
--- a/src/components/emoji_input/emoji_input.vue
+++ b/src/components/emoji_input/emoji_input.vue
@@ -50,7 +50,21 @@
             <span v-else>{{ suggestion.replacement }}</span>
           </span>
           <div class="label">
-            <span class="displayText">{{ suggestion.displayText }}</span>
+            <span
+              v-if="suggestion.user"
+              class="displayText"
+            >
+              {{ suggestion.displayText }}<UnicodeDomainIndicator
+                :user="suggestion.user"
+                :at="false"
+              />
+            </span>
+            <span
+              v-if="!suggestion.user"
+              class="displayText"
+            >
+              {{ suggestion.displayText }}
+            </span>
             <span class="detailText">{{ suggestion.detailText }}</span>
           </div>
         </div>
diff --git a/src/components/emoji_input/suggestor.js b/src/components/emoji_input/suggestor.js
index e8efbd1e..0ddb4d68 100644
--- a/src/components/emoji_input/suggestor.js
+++ b/src/components/emoji_input/suggestor.js
@@ -116,11 +116,12 @@ export const suggestUsers = ({ dispatch, state }) => {
 
       return diff + nameAlphabetically + screenNameAlphabetically
       /* eslint-disable camelcase */
-    }).map(({ screen_name, screen_name_ui, name, profile_image_url_original }) => ({
-      displayText: screen_name_ui,
-      detailText: name,
-      imageUrl: profile_image_url_original,
-      replacement: '@' + screen_name + ' '
+    }).map((user) => ({
+      user,
+      displayText: user.screen_name_ui,
+      detailText: user.name,
+      imageUrl: user.profile_image_url_original,
+      replacement: '@' + user.screen_name + ' '
     }))
     /* eslint-enable camelcase */
 
diff --git a/src/components/mention_link/mention_link.js b/src/components/mention_link/mention_link.js
index 4a74fbe2..6515bd11 100644
--- a/src/components/mention_link/mention_link.js
+++ b/src/components/mention_link/mention_link.js
@@ -2,6 +2,7 @@ import generateProfileLink from 'src/services/user_profile_link_generator/user_p
 import { mapGetters, mapState } from 'vuex'
 import { highlightClass, highlightStyle } from '../../services/user_highlighter/user_highlighter.js'
 import UserAvatar from '../user_avatar/user_avatar.vue'
+import UnicodeDomainIndicator from '../unicode_domain_indicator/unicode_domain_indicator.vue'
 import { defineAsyncComponent } from 'vue'
 import { library } from '@fortawesome/fontawesome-svg-core'
 import {
@@ -16,6 +17,7 @@ const MentionLink = {
   name: 'MentionLink',
   components: {
     UserAvatar,
+    UnicodeDomainIndicator,
     UserPopover: defineAsyncComponent(() => import('../user_popover/user_popover.vue'))
   },
   props: {
diff --git a/src/components/mention_link/mention_link.vue b/src/components/mention_link/mention_link.vue
index 3af502ef..869a3257 100644
--- a/src/components/mention_link/mention_link.vue
+++ b/src/components/mention_link/mention_link.vue
@@ -47,6 +47,9 @@
             class="serverName"
             :class="{ '-faded': shouldFadeDomain }"
             v-html="'@' + serverName"
+          /><UnicodeDomainIndicator
+            v-if="shouldShowFullUserName"
+            :user="user"
           />
           </span>
           <span
diff --git a/src/components/notification/notification.js b/src/components/notification/notification.js
index f60a1a6a..ddba560e 100644
--- a/src/components/notification/notification.js
+++ b/src/components/notification/notification.js
@@ -5,6 +5,7 @@ import UserAvatar from '../user_avatar/user_avatar.vue'
 import UserCard from '../user_card/user_card.vue'
 import Timeago from '../timeago/timeago.vue'
 import Report from '../report/report.vue'
+import UserLink from '../user_link/user_link.vue'
 import RichContent from 'src/components/rich_content/rich_content.jsx'
 import UserPopover from '../user_popover/user_popover.vue'
 import { isStatusNotification } from '../../services/notification_utils/notification_utils.js'
@@ -50,7 +51,8 @@ const Notification = {
     Status,
     Report,
     RichContent,
-    UserPopover
+    UserPopover,
+    UserLink
   },
   methods: {
     toggleUserExpanded () {
diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue
index 6a5417b3..26b174ff 100644
--- a/src/components/notification/notification.vue
+++ b/src/components/notification/notification.vue
@@ -11,9 +11,10 @@
       class="Notification container -muted"
     >
       <small>
-        <router-link :to="userProfileLink">
-          {{ notification.from_profile.screen_name_ui }}
-        </router-link>
+        <user-link
+          :user="notification.from_profile"
+          :at="false"
+        />
       </small>
       <button
         class="button-unstyled unmute"
@@ -174,12 +175,10 @@
           v-if="notification.type === 'follow' || notification.type === 'follow_request'"
           class="follow-text"
         >
-          <router-link
-            :to="userProfileLink"
+          <user-link
             class="follow-name"
-          >
-            @{{ notification.from_profile.screen_name_ui }}
-          </router-link>
+            :user="notification.from_profile"
+          />
           <div
             v-if="notification.type === 'follow_request'"
             style="white-space: nowrap;"
@@ -210,9 +209,9 @@
           v-else-if="notification.type === 'move'"
           class="move-text"
         >
-          <router-link :to="targetUserProfileLink">
-            @{{ notification.target.screen_name_ui }}
-          </router-link>
+          <user-link
+            :user="notification.target"
+          />
         </div>
         <Report
           v-else-if="notification.type === 'pleroma:report'"
diff --git a/src/components/status/status.js b/src/components/status/status.js
index 384063a7..19356664 100644
--- a/src/components/status/status.js
+++ b/src/components/status/status.js
@@ -13,6 +13,7 @@ import StatusPopover from '../status_popover/status_popover.vue'
 import UserPopover from '../user_popover/user_popover.vue'
 import UserListPopover from '../user_list_popover/user_list_popover.vue'
 import EmojiReactions from '../emoji_reactions/emoji_reactions.vue'
+import UserLink from '../user_link/user_link.vue'
 import MentionsLine from 'src/components/mentions_line/mentions_line.vue'
 import MentionLink from 'src/components/mention_link/mention_link.vue'
 import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
@@ -115,7 +116,8 @@ const Status = {
     RichContent,
     MentionLink,
     MentionsLine,
-    UserPopover
+    UserPopover,
+    UserLink
   },
   props: [
     'statusoid',
diff --git a/src/components/status/status.vue b/src/components/status/status.vue
index 967a966c..91f5fffa 100644
--- a/src/components/status/status.vue
+++ b/src/components/status/status.vue
@@ -25,9 +25,10 @@
             class="fa-scale-110 fa-old-padding repeat-icon"
             icon="retweet"
           />
-          <router-link :to="userProfileLink">
-            {{ status.user.screen_name_ui }}
-          </router-link>
+          <user-link
+            :user="status.user"
+            :at="false"
+          />
         </small>
         <small
           v-if="showReasonMutedThread"
@@ -164,13 +165,12 @@
                 >
                   {{ status.user.name }}
                 </h4>
-                <router-link
+                <user-link
                   class="account-name"
                   :title="status.user.screen_name_ui"
-                  :to="userProfileLink"
-                >
-                  {{ status.user.screen_name_ui }}
-                </router-link>
+                  :user="status.user"
+                  :at="false"
+                />
                 <img
                   v-if="!!(status.user && status.user.favicon)"
                   class="status-favicon"
diff --git a/src/components/unicode_domain_indicator/unicode_domain_indicator.vue b/src/components/unicode_domain_indicator/unicode_domain_indicator.vue
new file mode 100644
index 00000000..8f35245f
--- /dev/null
+++ b/src/components/unicode_domain_indicator/unicode_domain_indicator.vue
@@ -0,0 +1,26 @@
+<template>
+  <FAIcon
+    v-if="user && user.screen_name_ui_contains_non_ascii"
+    icon="code"
+    :title="$t('unicode_domain_indicator.tooltip')"
+  />
+</template>
+
+<script>
+import { library } from '@fortawesome/fontawesome-svg-core'
+import {
+  faCode
+} from '@fortawesome/free-solid-svg-icons'
+
+library.add(
+  faCode
+)
+
+const UnicodeDomainIndicator = {
+  props: {
+    user: Object
+  }
+}
+
+export default UnicodeDomainIndicator
+</script>
diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js
index 4c81e2c7..37458ba2 100644
--- a/src/components/user_card/user_card.js
+++ b/src/components/user_card/user_card.js
@@ -5,6 +5,7 @@ import FollowButton from '../follow_button/follow_button.vue'
 import ModerationTools from '../moderation_tools/moderation_tools.vue'
 import AccountActions from '../account_actions/account_actions.vue'
 import Select from '../select/select.vue'
+import UserLink from '../user_link/user_link.vue'
 import RichContent from 'src/components/rich_content/rich_content.jsx'
 import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
 import { mapGetters } from 'vuex'
@@ -134,7 +135,8 @@ export default {
     ProgressButton,
     FollowButton,
     Select,
-    RichContent
+    RichContent,
+    UserLink
   },
   methods: {
     muteUser () {
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index ace89c51..b84ff27d 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -106,13 +106,10 @@
               </button>
             </div>
             <div class="bottom-line">
-              <router-link
+              <user-link
                 class="user-screen-name"
-                :title="user.screen_name_ui"
-                :to="userProfileLink(user)"
-              >
-                @{{ user.screen_name_ui }}
-              </router-link>
+                :user="user"
+              />
               <template v-if="!hideBio">
                 <span
                   v-if="user.deactivated"
diff --git a/src/components/user_link/user_link.vue b/src/components/user_link/user_link.vue
new file mode 100644
index 00000000..efd96e12
--- /dev/null
+++ b/src/components/user_link/user_link.vue
@@ -0,0 +1,38 @@
+<template>
+  <router-link
+    :title="user.screen_name_ui"
+    :to="userProfileLink(user)"
+  >
+    {{ at ? '@' : '' }}{{ user.screen_name_ui }}<UnicodeDomainIndicator
+      :user="user"
+    />
+  </router-link>
+</template>
+
+<script>
+import UnicodeDomainIndicator from '../unicode_domain_indicator/unicode_domain_indicator.vue'
+import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
+
+const UserLink = {
+  props: {
+    user: Object,
+    at: {
+      type: Boolean,
+      default: true
+    }
+  },
+  components: {
+    UnicodeDomainIndicator
+  },
+  methods: {
+    userProfileLink (user) {
+      return generateProfileLink(
+        user.id, user.screen_name,
+        this.$store.state.instance.restrictedNicknames
+      )
+    }
+  }
+}
+
+export default UserLink
+</script>
diff --git a/src/components/user_list_popover/user_list_popover.js b/src/components/user_list_popover/user_list_popover.js
index e24eb9f7..046e0abd 100644
--- a/src/components/user_list_popover/user_list_popover.js
+++ b/src/components/user_list_popover/user_list_popover.js
@@ -1,5 +1,6 @@
 import { defineAsyncComponent } from 'vue'
 import RichContent from 'src/components/rich_content/rich_content.jsx'
+import UnicodeDomainIndicator from '../unicode_domain_indicator/unicode_domain_indicator.vue'
 
 import { library } from '@fortawesome/fontawesome-svg-core'
 import { faCircleNotch } from '@fortawesome/free-solid-svg-icons'
@@ -15,6 +16,7 @@ const UserListPopover = {
   ],
   components: {
     RichContent,
+    UnicodeDomainIndicator,
     Popover: defineAsyncComponent(() => import('../popover/popover.vue')),
     UserAvatar: defineAsyncComponent(() => import('../user_avatar/user_avatar.vue'))
   },
diff --git a/src/components/user_list_popover/user_list_popover.vue b/src/components/user_list_popover/user_list_popover.vue
index a3ce54c3..635dc7f6 100644
--- a/src/components/user_list_popover/user_list_popover.vue
+++ b/src/components/user_list_popover/user_list_popover.vue
@@ -29,7 +29,7 @@
                 :emoji="user.emoji"
               />
               <!-- eslint-enable vue/no-v-html -->
-              <span class="user-list-screen-name">{{ user.screen_name_ui }}</span>
+              <span class="user-list-screen-name">{{ user.screen_name_ui }}</span><UnicodeDomainIndicator :user="user" />
             </div>
           </div>
         </template>
diff --git a/src/components/user_reporting_modal/user_reporting_modal.js b/src/components/user_reporting_modal/user_reporting_modal.js
index 85ffc661..67fde084 100644
--- a/src/components/user_reporting_modal/user_reporting_modal.js
+++ b/src/components/user_reporting_modal/user_reporting_modal.js
@@ -2,13 +2,15 @@ import Status from '../status/status.vue'
 import List from '../list/list.vue'
 import Checkbox from '../checkbox/checkbox.vue'
 import Modal from '../modal/modal.vue'
+import UserLink from '../user_link/user_link.vue'
 
 const UserReportingModal = {
   components: {
     Status,
     List,
     Checkbox,
-    Modal
+    Modal,
+    UserLink
   },
   data () {
     return {
diff --git a/src/components/user_reporting_modal/user_reporting_modal.vue b/src/components/user_reporting_modal/user_reporting_modal.vue
index 429a66e2..8c42ab7b 100644
--- a/src/components/user_reporting_modal/user_reporting_modal.vue
+++ b/src/components/user_reporting_modal/user_reporting_modal.vue
@@ -5,9 +5,13 @@
   >
     <div class="user-reporting-panel panel">
       <div class="panel-heading">
-        <div class="title">
-          {{ $t('user_reporting.title', [user.screen_name_ui]) }}
-        </div>
+        <i18n-t
+          tag="div"
+          keypath="user_reporting.title"
+          class="title"
+        >
+          <UserLink :user="user" />
+        </i18n-t>
       </div>
       <div class="panel-body">
         <div class="user-reporting-panel-left">
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 91722d9a..4ce56678 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -1006,5 +1006,8 @@
     "update_changelog": "For more details on what's changed, see {theFullChangelog}.",
     "update_changelog_here": "the full changelog",
     "art_by": "Art by {linkToArtist}"
+  },
+  "unicode_domain_indicator": {
+    "tooltip": "This domain contains non-ascii characters."
   }
 }
diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js
index e9cbcfe6..ce316832 100644
--- a/src/services/entity_normalizer/entity_normalizer.service.js
+++ b/src/services/entity_normalizer/entity_normalizer.service.js
@@ -214,12 +214,14 @@ export const parseUser = (data) => {
   output.screen_name_ui = output.screen_name
   if (output.screen_name && output.screen_name.includes('@')) {
     const parts = output.screen_name.split('@')
-    let unicodeDomain = punycode.toUnicode(parts[1])
+    const unicodeDomain = punycode.toUnicode(parts[1])
     if (unicodeDomain !== parts[1]) {
       // Add some identifier so users can potentially spot spoofing attempts:
       // lain.com and xn--lin-6cd.com would appear identical otherwise.
-      unicodeDomain = '🌏' + unicodeDomain
+      output.screen_name_ui_contains_non_ascii = true
       output.screen_name_ui = [parts[0], unicodeDomain].join('@')
+    } else {
+      output.screen_name_ui_contains_non_ascii = false
     }
   }
 
diff --git a/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js b/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js
index 98bb05a8..3923596b 100644
--- a/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js
+++ b/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js
@@ -269,7 +269,8 @@ describe('API Entities normalizer', () => {
     it('converts IDN to unicode and marks it as internatonal', () => {
       const user = makeMockUserMasto({ acct: 'lain@xn--lin-6cd.com' })
 
-      expect(parseUser(user)).to.have.property('screen_name_ui').that.equal('lain@🌏lаin.com')
+      expect(parseUser(user)).to.have.property('screen_name_ui').that.equal('lain@lаin.com')
+      expect(parseUser(user)).to.have.property('screen_name_ui_contains_non_ascii').that.equal(true)
     })
   })
 
-- 
cgit v1.2.3-70-g09d2


From 17aa503106f129e391f8478ade6821f09ef7494a Mon Sep 17 00:00:00 2001
From: tusooa <tusooa@kazv.moe>
Date: Tue, 8 Nov 2022 00:43:33 -0500
Subject: Make notification panel a list of articles

---
 src/components/notification/notification.vue   | 17 ++++++++++-------
 src/components/notifications/notifications.vue |  6 +++++-
 2 files changed, 15 insertions(+), 8 deletions(-)

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

diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue
index 26b174ff..84f3f7de 100644
--- a/src/components/notification/notification.vue
+++ b/src/components/notification/notification.vue
@@ -1,11 +1,14 @@
 <template>
-  <Status
+  <article
     v-if="notification.type === 'mention'"
-    class="Notification"
-    :compact="true"
-    :statusoid="notification.status"
-  />
-  <div v-else>
+  >
+    <Status
+      class="Notification"
+      :compact="true"
+      :statusoid="notification.status"
+    />
+  </article>
+  <article v-else>
     <div
       v-if="needMute && !unmuted"
       class="Notification container -muted"
@@ -226,7 +229,7 @@
         </template>
       </div>
     </div>
-  </div>
+  </article>
 </template>
 
 <script src="./notification.js"></script>
diff --git a/src/components/notifications/notifications.vue b/src/components/notifications/notifications.vue
index 7ed419d1..02a87fcc 100644
--- a/src/components/notifications/notifications.vue
+++ b/src/components/notifications/notifications.vue
@@ -50,10 +50,14 @@
           </button>
           <NotificationFilters class="rightside-button" />
         </div>
-        <div class="panel-body">
+        <div
+          class="panel-body"
+          role="list"
+        >
           <div
             v-for="notification in notificationsToDisplay"
             :key="notification.id"
+            role="listitem"
             class="notification"
             :class="{unseen: !minimalMode && !notification.seen}"
           >
-- 
cgit v1.2.3-70-g09d2


From efdcfedfbeabcb71ad1756e993eba6a4c6ac720a Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Mon, 19 Dec 2022 22:20:15 +0200
Subject: add icon to allow expand collapsed (status-related) notifications

---
 src/components/notification/notification.js     | 15 ++++++++++-----
 src/components/notification/notification.vue    | 16 +++++++++++++---
 src/components/notifications/notifications.scss | 10 ++++++++++
 3 files changed, 33 insertions(+), 8 deletions(-)

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

diff --git a/src/components/notification/notification.js b/src/components/notification/notification.js
index ddba560e..3e834bd5 100644
--- a/src/components/notification/notification.js
+++ b/src/components/notification/notification.js
@@ -20,7 +20,9 @@ import {
   faUserPlus,
   faEyeSlash,
   faUser,
-  faSuitcaseRolling
+  faSuitcaseRolling,
+  faExpandAlt,
+  faCompressAlt
 } from '@fortawesome/free-solid-svg-icons'
 
 library.add(
@@ -31,13 +33,15 @@ library.add(
   faUserPlus,
   faUser,
   faEyeSlash,
-  faSuitcaseRolling
+  faSuitcaseRolling,
+  faExpandAlt,
+  faCompressAlt
 )
 
 const Notification = {
   data () {
     return {
-      userExpanded: false,
+      statusExpanded: false,
       betterShadow: this.$store.state.interface.browserSupport.cssFilter,
       unmuted: false
     }
@@ -55,8 +59,9 @@ const Notification = {
     UserLink
   },
   methods: {
-    toggleUserExpanded () {
-      this.userExpanded = !this.userExpanded
+    toggleStatusExpanded () {
+      console.log('as')
+      this.statusExpanded = !this.statusExpanded
     },
     generateUserProfileLink (user) {
       return generateProfileLink(user.id, user.screen_name, this.$store.state.instance.restrictedNicknames)
diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue
index 84f3f7de..2079cc75 100644
--- a/src/components/notification/notification.vue
+++ b/src/components/notification/notification.vue
@@ -144,13 +144,23 @@
             <router-link
               v-if="notification.status"
               :to="{ name: 'conversation', params: { id: notification.status.id } }"
-              class="faint-link"
+              class="timeago-link faint-link"
             >
               <Timeago
                 :time="notification.created_at"
                 :auto-update="240"
               />
             </router-link>
+            <button
+              class="button-unstyled expand-icon"
+              @click.prevent="toggleStatusExpanded"
+            >
+              <FAIcon
+                class="fa-scale-110"
+                fixed-width
+                :icon="statusExpanded ? 'compress-alt' : 'expand-alt'"
+              />
+            </button>
           </div>
           <div
             v-else
@@ -222,8 +232,8 @@
         />
         <template v-else>
           <StatusContent
-            class="faint"
-            :compact="true"
+            :class="{ faint: !statusExpanded }"
+            :compact="!statusExpanded"
             :status="notification.action"
           />
         </template>
diff --git a/src/components/notifications/notifications.scss b/src/components/notifications/notifications.scss
index f71f9b76..9b241565 100644
--- a/src/components/notifications/notifications.scss
+++ b/src/components/notifications/notifications.scss
@@ -112,6 +112,16 @@
       min-width: 3em;
       text-align: right;
     }
+
+    .timeago-link {
+      margin-right: 0.2em;
+    }
+
+    .expand-icon {
+      .svg-inline--fa {
+        margin-left: 0.25em;
+      }
+    }
   }
 
   .emoji-reaction-emoji {
-- 
cgit v1.2.3-70-g09d2


From 5bde89297c11a0d35b1dfd314abaace8c238b4b5 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Wed, 21 Dec 2022 22:58:41 +0200
Subject: a11y

---
 src/components/notification/notification.vue | 2 ++
 src/i18n/en.json                             | 4 +++-
 2 files changed, 5 insertions(+), 1 deletion(-)

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

diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue
index 2079cc75..fcd48ed5 100644
--- a/src/components/notification/notification.vue
+++ b/src/components/notification/notification.vue
@@ -154,6 +154,7 @@
             <button
               class="button-unstyled expand-icon"
               @click.prevent="toggleStatusExpanded"
+              :title="$t('tool_tip.toggle_expand')"
             >
               <FAIcon
                 class="fa-scale-110"
@@ -176,6 +177,7 @@
           <button
             v-if="needMute"
             class="button-unstyled"
+            :title="$t('tool_tip.toggle_mute')"
             @click.prevent="toggleMute"
           >
             <FAIcon
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 5793c3c8..ddaa12cd 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -986,7 +986,9 @@
     "user_settings": "User Settings",
     "accept_follow_request": "Accept follow request",
     "reject_follow_request": "Reject follow request",
-    "bookmark": "Bookmark"
+    "bookmark": "Bookmark",
+    "toggle_expand": "Expand or collapse notification to show post in full",
+    "toggle_mute": "Expand or collapse notification to reveal muted content"
   },
   "upload": {
     "error": {
-- 
cgit v1.2.3-70-g09d2


From 8a594e2f98f49eeff105de9c956764c15a0ef80a Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Thu, 22 Dec 2022 12:31:36 +0200
Subject: more aria

---
 src/components/notification/notification.vue | 2 ++
 1 file changed, 2 insertions(+)

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

diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue
index fcd48ed5..f1aa5420 100644
--- a/src/components/notification/notification.vue
+++ b/src/components/notification/notification.vue
@@ -155,6 +155,7 @@
               class="button-unstyled expand-icon"
               @click.prevent="toggleStatusExpanded"
               :title="$t('tool_tip.toggle_expand')"
+              :aria-expanded="statusExpanded"
             >
               <FAIcon
                 class="fa-scale-110"
@@ -178,6 +179,7 @@
             v-if="needMute"
             class="button-unstyled"
             :title="$t('tool_tip.toggle_mute')"
+            :aria-expanded="!unmuted"
             @click.prevent="toggleMute"
           >
             <FAIcon
-- 
cgit v1.2.3-70-g09d2

