From 1a333aabba759fb68449ead9c47e986f456e8c8c Mon Sep 17 00:00:00 2001
From: Sean King <seanking2919@protonmail.com>
Date: Tue, 7 Jun 2022 21:31:48 -0600
Subject: Add edit status functionality

---
 src/App.vue | 1 +
 1 file changed, 1 insertion(+)

(limited to 'src/App.vue')

diff --git a/src/App.vue b/src/App.vue
index 5b448972..9484f993 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -52,6 +52,7 @@
     <MobilePostStatusButton />
     <UserReportingModal />
     <PostStatusModal />
+    <EditStatusModal />
     <SettingsModal />
     <div id="modal" />
     <GlobalNoticeList />
-- 
cgit v1.2.3-70-g09d2


From fa5d35523dd081b6948d38325374cac5707b7868 Mon Sep 17 00:00:00 2001
From: Sean King <seanking2919@protonmail.com>
Date: Mon, 20 Jun 2022 22:52:08 -0600
Subject: Add ability to view status history for edited statuses

---
 src/App.js                                         |  2 +
 src/App.vue                                        |  1 +
 src/components/extra_buttons/extra_buttons.js      | 23 ++++++++-
 src/components/extra_buttons/extra_buttons.vue     | 11 ++++
 .../status_history_modal/status_history_modal.js   | 60 ++++++++++++++++++++++
 .../status_history_modal/status_history_modal.vue  | 46 +++++++++++++++++
 src/i18n/en.json                                   |  3 +-
 src/main.js                                        |  2 +
 src/modules/statusHistory.js                       | 25 +++++++++
 src/modules/statuses.js                            |  3 ++
 src/services/api/api.service.js                    | 17 +++---
 .../entity_normalizer/entity_normalizer.service.js |  6 ++-
 12 files changed, 186 insertions(+), 13 deletions(-)
 create mode 100644 src/components/status_history_modal/status_history_modal.js
 create mode 100644 src/components/status_history_modal/status_history_modal.vue
 create mode 100644 src/modules/statusHistory.js

(limited to 'src/App.vue')

diff --git a/src/App.js b/src/App.js
index 6e0e34a8..af638a1c 100644
--- a/src/App.js
+++ b/src/App.js
@@ -13,6 +13,7 @@ import DesktopNav from './components/desktop_nav/desktop_nav.vue'
 import UserReportingModal from './components/user_reporting_modal/user_reporting_modal.vue'
 import EditStatusModal from './components/edit_status_modal/edit_status_modal.vue'
 import PostStatusModal from './components/post_status_modal/post_status_modal.vue'
+import StatusHistoryModal from './components/status_history_modal/status_history_modal.vue'
 import GlobalNoticeList from './components/global_notice_list/global_notice_list.vue'
 import { windowWidth, windowHeight } from './services/window_utils/window_utils'
 import { mapGetters } from 'vuex'
@@ -37,6 +38,7 @@ export default {
     UserReportingModal,
     PostStatusModal,
     EditStatusModal,
+    StatusHistoryModal,
     GlobalNoticeList
   },
   data: () => ({
diff --git a/src/App.vue b/src/App.vue
index 9484f993..1b513e08 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -53,6 +53,7 @@
     <UserReportingModal />
     <PostStatusModal />
     <EditStatusModal />
+    <StatusHistoryModal />
     <SettingsModal />
     <div id="modal" />
     <GlobalNoticeList />
diff --git a/src/components/extra_buttons/extra_buttons.js b/src/components/extra_buttons/extra_buttons.js
index 8a703953..11fe3235 100644
--- a/src/components/extra_buttons/extra_buttons.js
+++ b/src/components/extra_buttons/extra_buttons.js
@@ -6,7 +6,8 @@ import {
   faEyeSlash,
   faThumbtack,
   faShareAlt,
-  faExternalLinkAlt
+  faExternalLinkAlt,
+  faHistory
 } from '@fortawesome/free-solid-svg-icons'
 import {
   faBookmark as faBookmarkReg,
@@ -21,7 +22,8 @@ library.add(
   faThumbtack,
   faShareAlt,
   faExternalLinkAlt,
-  faFlag
+  faFlag,
+  faHistory
 )
 
 const ExtraButtons = {
@@ -84,6 +86,20 @@ const ExtraButtons = {
           visibility: this.status.visibility,
           statusContentType: data.content_type
         }))
+    },
+    showStatusHistory () {
+      let originalStatus = {}
+      Object.assign(originalStatus, this.status)
+      delete originalStatus.attachments
+      delete originalStatus.created_at
+      delete originalStatus.emojis
+      delete originalStatus.text
+      delete originalStatus.raw_html
+      delete originalStatus.nsfw
+      delete originalStatus.poll
+      delete originalStatus.summary
+      delete originalStatus.summary_raw_html
+      this.$store.dispatch('openStatusHistoryModal', originalStatus)
     }
   },
   computed: {
@@ -104,6 +120,9 @@ const ExtraButtons = {
     },
     statusLink () {
       return `${this.$store.state.instance.server}${this.$router.resolve({ name: 'conversation', params: { id: this.status.id } }).href}`
+    },
+    isEdited () {
+      return this.status.edited_at !== null
     }
   }
 }
diff --git a/src/components/extra_buttons/extra_buttons.vue b/src/components/extra_buttons/extra_buttons.vue
index 8e90ee27..877e1424 100644
--- a/src/components/extra_buttons/extra_buttons.vue
+++ b/src/components/extra_buttons/extra_buttons.vue
@@ -84,6 +84,17 @@
             icon="pen"
           /><span>{{ $t("status.edit") }}</span>
         </button>
+        <button
+          v-if="isEdited"
+          class="button-default dropdown-item dropdown-item-icon"
+          @click.prevent="showStatusHistory"
+          @click="close"
+        >
+          <FAIcon
+            fixed-width
+            icon="history"
+          /><span>{{ $t("status.status_history") }}</span>
+        </button>
         <button
           v-if="canDelete"
           class="button-default dropdown-item dropdown-item-icon"
diff --git a/src/components/status_history_modal/status_history_modal.js b/src/components/status_history_modal/status_history_modal.js
new file mode 100644
index 00000000..3941a56f
--- /dev/null
+++ b/src/components/status_history_modal/status_history_modal.js
@@ -0,0 +1,60 @@
+import { get } from 'lodash'
+import Modal from '../modal/modal.vue'
+import Status from '../status/status.vue'
+
+const StatusHistoryModal = {
+  components: {
+    Modal,
+    Status
+  },
+  data () {
+    return {
+      statuses: []
+    }
+  },
+  computed: {
+    modalActivated () {
+      return this.$store.state.statusHistory.modalActivated
+    },
+    params () {
+      return this.$store.state.statusHistory.params
+    },
+    statusId () {
+      return this.params.id
+    },
+    historyCount () {
+      return this.statuses.length
+    },
+    history () {
+      return this.statuses
+    }
+  },
+  watch: {
+    params (newVal, oldVal) {
+      const newStatusId = get(newVal, 'id') !== get(oldVal, 'id')
+      if (newStatusId) {
+        this.resetHistory()
+      }
+
+      if (newStatusId || get(newVal, 'edited_at') !== get(oldVal, 'edited_at')) {
+        this.fetchStatusHistory()
+      }
+    }
+  },
+  methods: {
+    resetHistory () {
+      this.statuses = []
+    },
+    fetchStatusHistory () {
+      this.$store.dispatch('fetchStatusHistory', this.params)
+        .then(data => {
+          this.statuses = data
+        })
+    },
+    closeModal () {
+      this.$store.dispatch('closeStatusHistoryModal')
+    }
+  }
+}
+
+export default StatusHistoryModal
diff --git a/src/components/status_history_modal/status_history_modal.vue b/src/components/status_history_modal/status_history_modal.vue
new file mode 100644
index 00000000..d6680df2
--- /dev/null
+++ b/src/components/status_history_modal/status_history_modal.vue
@@ -0,0 +1,46 @@
+<template>
+  <Modal
+    v-if="modalActivated"
+    class="status-history-modal-view"
+    @backdropClicked="closeModal"
+  >
+    <div class="status-history-modal-panel panel">
+      <div class="panel-heading">
+        {{ $t('status.status_history') }} ({{ historyCount }})
+      </div>
+      <div class="panel-body">
+        <div
+          v-if="historyCount > 0"
+          class="history-body"
+        >
+          <status
+            v-for="status in history"
+            :key="status.id"
+            :statusoid="status"
+            :isPreview="true"
+            class="conversation-status status-fadein panel-body"
+        />
+        </div>
+      </div>
+    </div>
+  </Modal>
+</template>
+
+<script src="./status_history_modal.js"></script>
+
+<style lang="scss">
+.modal-view.status-history-modal-view {
+  align-items: flex-start;
+}
+.status-history-modal-panel {
+  flex-shrink: 0;
+  margin-top: 25%;
+  margin-bottom: 2em;
+  width: 100%;
+  max-width: 700px;
+
+  @media (orientation: landscape) {
+    margin-top: 8%;
+  }
+}
+</style>
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 7b1bac79..f125c249 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -795,7 +795,8 @@
     "ancestor_follow_with_icon": "{icon} {text}",
     "show_all_conversation_with_icon": "{icon} {text}",
     "show_all_conversation": "Show full conversation ({numStatus} other status) | Show full conversation ({numStatus} other statuses)",
-    "show_only_conversation_under_this": "Only show replies to this status"
+    "show_only_conversation_under_this": "Only show replies to this status",
+    "status_history": "Status history"
   },
   "user_card": {
     "approve": "Approve",
diff --git a/src/main.js b/src/main.js
index f11b80ed..032b4c58 100644
--- a/src/main.js
+++ b/src/main.js
@@ -19,6 +19,7 @@ import reportsModule from './modules/reports.js'
 import pollsModule from './modules/polls.js'
 import postStatusModule from './modules/postStatus.js'
 import editStatusModule from './modules/editStatus.js'
+import statusHistoryModule from './modules/statusHistory.js'
 
 import chatsModule from './modules/chats.js'
 
@@ -84,6 +85,7 @@ const persistedStateOptions = {
       polls: pollsModule,
       postStatus: postStatusModule,
       editStatus: editStatusModule,
+      statusHistory: statusHistoryModule,
       chats: chatsModule
     },
     plugins,
diff --git a/src/modules/statusHistory.js b/src/modules/statusHistory.js
new file mode 100644
index 00000000..db3d6d4b
--- /dev/null
+++ b/src/modules/statusHistory.js
@@ -0,0 +1,25 @@
+const statusHistory = {
+  state: {
+    params: {},
+    modalActivated: false
+  },
+  mutations: {
+    openStatusHistoryModal (state, params) {
+      state.params = params
+      state.modalActivated = true
+    },
+    closeStatusHistoryModal (state) {
+      state.modalActivated = false
+    }
+  },
+  actions: {
+    openStatusHistoryModal ({ commit }, params) {
+      commit('openStatusHistoryModal', params)
+    },
+    closeStatusHistoryModal ({ commit }) {
+      commit('closeStatusHistoryModal')
+    }
+  }
+}
+
+export default statusHistory
diff --git a/src/modules/statuses.js b/src/modules/statuses.js
index 19220442..a2e27b87 100644
--- a/src/modules/statuses.js
+++ b/src/modules/statuses.js
@@ -606,6 +606,9 @@ const statuses = {
     fetchStatusSource ({ rootState, dispatch }, status) {
       return apiService.fetchStatusSource({ id: status.id, credentials: rootState.users.currentUser.credentials })
     },
+    fetchStatusHistory ({ rootState, dispatch }, status) {
+      return apiService.fetchStatusHistory({ status })
+    },
     deleteStatus ({ rootState, commit }, status) {
       commit('setDeleted', { status })
       apiService.deleteStatus({ id: status.id, credentials: rootState.users.currentUser.credentials })
diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js
index 49b7e95a..9bc420c3 100644
--- a/src/services/api/api.service.js
+++ b/src/services/api/api.service.js
@@ -425,17 +425,16 @@ const fetchStatusSource = ({ id, credentials }) => {
     .then((data) => parseSource(data))
 }
 
-const fetchStatusHistory = ({ id, credentials }) => {
-  let url = MASTODON_STATUS_HISTORY_URL(id)
-  return fetch(url, { headers: authHeaders(credentials) })
+const fetchStatusHistory = ({ status, credentials }) => {
+  let url = MASTODON_STATUS_HISTORY_URL(status.id)
+  return promisedRequest({ url, credentials })
     .then((data) => {
-      if (data.ok) {
-        return data
-      }
-      throw new Error('Error fetching history', data)
+      data.reverse()
+      return data.map((item) => {
+        item.originalStatus = status
+        return parseStatus(item)
+      })
     })
-    .then((data) => data.json())
-    .then((data) => parseStatus(data))
 }
 
 const tagUser = ({ tag, credentials, user }) => {
diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js
index 82c19655..2a186ba1 100644
--- a/src/services/entity_normalizer/entity_normalizer.service.js
+++ b/src/services/entity_normalizer/entity_normalizer.service.js
@@ -275,7 +275,7 @@ export const parseStatus = (data) => {
 
     output.tags = data.tags
 
-    output.is_edited = data.edited_at !== null
+    output.edited_at = data.edited_at
 
     if (data.pleroma) {
       const { pleroma } = data
@@ -378,6 +378,10 @@ export const parseStatus = (data) => {
   output.favoritedBy = []
   output.rebloggedBy = []
 
+  if (data.hasOwnProperty('originalStatus')) {
+    Object.assign(output, data.originalStatus)
+  }
+
   return output
 }
 
-- 
cgit v1.2.3-70-g09d2


From f56298adbd6fc4b30f759f58336f881e9ebfab65 Mon Sep 17 00:00:00 2001
From: Sean King <seanking2919@protonmail.com>
Date: Tue, 21 Jun 2022 17:44:04 -0600
Subject: Add ability to detect whether backend supports editing

---
 src/App.js                                     | 1 +
 src/App.vue                                    | 4 ++--
 src/boot/after_store.js                        | 1 +
 src/components/extra_buttons/extra_buttons.js  | 3 ++-
 src/components/extra_buttons/extra_buttons.vue | 4 ++--
 5 files changed, 8 insertions(+), 5 deletions(-)

(limited to 'src/App.vue')

diff --git a/src/App.js b/src/App.js
index af638a1c..f87b3962 100644
--- a/src/App.js
+++ b/src/App.js
@@ -94,6 +94,7 @@ export default {
       return this.$store.getters.mergedConfig.alwaysShowNewPostButton || this.layoutType === 'mobile'
     },
     showFeaturesPanel () { return this.$store.state.instance.showFeaturesPanel },
+    editingAvailable () { return this.$store.state.instance.editingAvailable },
     shoutboxPosition () {
       return this.$store.getters.mergedConfig.alwaysShowNewPostButton || false
     },
diff --git a/src/App.vue b/src/App.vue
index 1b513e08..c20a4d9d 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -52,8 +52,8 @@
     <MobilePostStatusButton />
     <UserReportingModal />
     <PostStatusModal />
-    <EditStatusModal />
-    <StatusHistoryModal />
+    <EditStatusModal v-if="editingAvailable" />
+    <StatusHistoryModal v-if="editingAvailable" />
     <SettingsModal />
     <div id="modal" />
     <GlobalNoticeList />
diff --git a/src/boot/after_store.js b/src/boot/after_store.js
index f655c38f..55e46c85 100644
--- a/src/boot/after_store.js
+++ b/src/boot/after_store.js
@@ -251,6 +251,7 @@ const getNodeInfo = async ({ store }) => {
       store.dispatch('setInstanceOption', { name: 'pleromaChatMessagesAvailable', value: features.includes('pleroma_chat_messages') })
       store.dispatch('setInstanceOption', { name: 'gopherAvailable', value: features.includes('gopher') })
       store.dispatch('setInstanceOption', { name: 'pollsAvailable', value: features.includes('polls') })
+      store.dispatch('setInstanceOption', { name: 'editingAvailable', value: features.includes('editing') })
       store.dispatch('setInstanceOption', { name: 'pollLimits', value: metadata.pollLimits })
       store.dispatch('setInstanceOption', { name: 'mailerEnabled', value: metadata.mailerEnabled })
 
diff --git a/src/components/extra_buttons/extra_buttons.js b/src/components/extra_buttons/extra_buttons.js
index 11fe3235..92eb63b0 100644
--- a/src/components/extra_buttons/extra_buttons.js
+++ b/src/components/extra_buttons/extra_buttons.js
@@ -123,7 +123,8 @@ const ExtraButtons = {
     },
     isEdited () {
       return this.status.edited_at !== null
-    }
+    },
+    editingAvailable () { return this.$store.state.instance.editingAvailable }
   }
 }
 
diff --git a/src/components/extra_buttons/extra_buttons.vue b/src/components/extra_buttons/extra_buttons.vue
index 877e1424..eda838dc 100644
--- a/src/components/extra_buttons/extra_buttons.vue
+++ b/src/components/extra_buttons/extra_buttons.vue
@@ -74,7 +74,7 @@
           /><span>{{ $t("status.unbookmark") }}</span>
         </button>
         <button
-          v-if="ownStatus"
+          v-if="ownStatus && editingAvailable"
           class="button-default dropdown-item dropdown-item-icon"
           @click.prevent="editStatus"
           @click="close"
@@ -85,7 +85,7 @@
           /><span>{{ $t("status.edit") }}</span>
         </button>
         <button
-          v-if="isEdited"
+          v-if="isEdited && editingAvailable"
           class="button-default dropdown-item dropdown-item-icon"
           @click.prevent="showStatusHistory"
           @click="close"
-- 
cgit v1.2.3-70-g09d2


From 5b7c6538745083dfd48771392ab22de557a7a344 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Tue, 2 Aug 2022 00:37:48 +0300
Subject: initial scratch

---
 src/App.js                                         |   1 +
 src/App.vue                                        |   1 +
 src/assets/pleromatan_apology.png                  | Bin 0 -> 405742 bytes
 src/assets/pleromatan_apology_fox.png              | Bin 0 -> 533320 bytes
 .../update_notification/update_notification.js     |  24 ++++++++++++
 .../update_notification/update_notification.scss   |  34 +++++++++++++++++
 .../update_notification/update_notification.vue    |  41 +++++++++++++++++++++
 src/i18n/en.json                                   |   9 +++++
 8 files changed, 110 insertions(+)
 create mode 100644 src/assets/pleromatan_apology.png
 create mode 100644 src/assets/pleromatan_apology_fox.png
 create mode 100644 src/components/update_notification/update_notification.js
 create mode 100644 src/components/update_notification/update_notification.scss
 create mode 100644 src/components/update_notification/update_notification.vue

(limited to 'src/App.vue')

diff --git a/src/App.js b/src/App.js
index d5967685..f5bd7e2e 100644
--- a/src/App.js
+++ b/src/App.js
@@ -32,6 +32,7 @@ export default {
     MobileNav,
     DesktopNav,
     SettingsModal: defineAsyncComponent(() => import('./components/settings_modal/settings_modal.vue')),
+    UpdateNotification: defineAsyncComponent(() => import('./components/update_notification/update_notification.vue')),
     UserReportingModal,
     PostStatusModal,
     GlobalNoticeList
diff --git a/src/App.vue b/src/App.vue
index 0efadaf0..c741aa70 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -65,6 +65,7 @@
     <UserReportingModal />
     <PostStatusModal />
     <SettingsModal />
+    <UpdateNotification />
     <div id="modal" />
     <GlobalNoticeList />
     <div id="popovers" />
diff --git a/src/assets/pleromatan_apology.png b/src/assets/pleromatan_apology.png
new file mode 100644
index 00000000..36ad7aeb
Binary files /dev/null and b/src/assets/pleromatan_apology.png differ
diff --git a/src/assets/pleromatan_apology_fox.png b/src/assets/pleromatan_apology_fox.png
new file mode 100644
index 00000000..17f87694
Binary files /dev/null and b/src/assets/pleromatan_apology_fox.png differ
diff --git a/src/components/update_notification/update_notification.js b/src/components/update_notification/update_notification.js
new file mode 100644
index 00000000..6b8665dd
--- /dev/null
+++ b/src/components/update_notification/update_notification.js
@@ -0,0 +1,24 @@
+import Modal from 'src/components/modal/modal.vue'
+import { library } from '@fortawesome/fontawesome-svg-core'
+import pleromaTan from 'src/assets/pleromatan_apology.png'
+import pleromaTanFox from 'src/assets/pleromatan_apology_fox.png'
+
+import {
+  faTimes
+} from '@fortawesome/free-solid-svg-icons'
+library.add(
+  faTimes
+)
+
+const SettingsModal = {
+  data () {
+    return {
+      pleromaTanVariant: Math.random() > 0.5 ? pleromaTan : pleromaTanFox
+    }
+  },
+  components: {
+    Modal
+  }
+}
+
+export default SettingsModal
diff --git a/src/components/update_notification/update_notification.scss b/src/components/update_notification/update_notification.scss
new file mode 100644
index 00000000..5fd9eb9b
--- /dev/null
+++ b/src/components/update_notification/update_notification.scss
@@ -0,0 +1,34 @@
+@import 'src/_variables.scss';
+.UpdateNotificationModal {
+  /* Explanation:
+   * Modal is positioned vertically centered.
+   * 100vh - 100% = Distance between modal's top+bottom boundaries and screen
+   * (100vh - 100%) / 2 = Distance between bottom (or top) boundary and screen
+   * + 10% - we move modal completely off-screen, it's top boundary touches
+   *   bottom of the screen
+   * - 50px - leaving tiny amount of space so that titlebar + tiny amount of modal is visible
+   */
+  transform: translateY(calc(((100vh - 100%) / 2 + 5%)));
+  max-width: 90vh;
+  width: 30em;
+  position: relative;
+
+  @media all and (max-width: 800px) {
+    /* For mobile, the modal takes 100% of the available screen.
+    This ensures the minimized modal is always 50px above the browser bottom bar regardless of whether or not it is visible.
+   */
+    transform: translateY(calc(100% - 50px));
+  }
+  .panel-body > p {
+    width: calc(100% - 10em)
+  }
+
+  .pleroma-tan {
+    max-width: 20em;
+    max-height: 40em;
+    position: absolute;
+    right: -5em;
+    top: -10em;
+    z-index: 10;
+  }
+}
diff --git a/src/components/update_notification/update_notification.vue b/src/components/update_notification/update_notification.vue
new file mode 100644
index 00000000..e7118d81
--- /dev/null
+++ b/src/components/update_notification/update_notification.vue
@@ -0,0 +1,41 @@
+<template>
+  <Modal
+    :is-open="true"
+    class="UpdateNotification"
+    :class="{ peek: modalPeeked }"
+    :no-background="true"
+  >
+    <div class="UpdateNotificationModal panel">
+      <div class="panel-heading">
+        <span class="title">
+          {{ $t('update.big_update_title') }}
+        </span>
+      </div>
+      <div class="panel-body">
+        <p>
+          {{ $t('update.big_update_content') }}
+        </p>
+        <p>
+        <button
+          class="button-unstyled -link tall-status-hider"
+          @click.prevent="toggleShowMore"
+        >
+          {{ $t("general.show_more") }}
+        </button>
+        {{ ' ' }}
+        <button
+          class="button-unstyled -link tall-status-hider"
+          @click.prevent="toggleShowMore"
+        >
+          {{ $t("general.never_show_again") }}
+        </button>
+          </p>
+        <img class="pleroma-tan" :src="pleromaTanVariant"/>
+      </div>
+    </div>
+  </Modal>
+</template>
+
+<script src="./update_notification.js"></script>
+
+<style src="./update_notification.scss" lang="scss"></style>
diff --git a/src/i18n/en.json b/src/i18n/en.json
index a10b271a..cd095ffb 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -71,6 +71,7 @@
     "optional": "optional",
     "show_more": "Show more",
     "show_less": "Show less",
+    "never_show_again": "Never show again",
     "dismiss": "Dismiss",
     "cancel": "Cancel",
     "disable": "Disable",
@@ -956,5 +957,13 @@
   },
   "display_date": {
     "today": "Today"
+  },
+  "update": {
+    "big_update_title": "Please bear with us",
+    "big_update_content": "We haven't had a release in a while, so there things might look and feel different than what you're used to.",
+    "update_bugs": "Please report any issues and bugs on {pleromaGitlab} we don't have a QA team so some things fall through the cracks, we're also open to feedback and suggestions.",
+    "update_bugs_gitlab": "Pleroma Gitlab",
+    "update_changelog": "You can see the full changelog {here}",
+    "update_changelog_here": "here"
   }
 }
-- 
cgit v1.2.3-70-g09d2


From d074aefb4ffe8fc7bdb0e5f0afec46f7042a90fe Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Wed, 17 Aug 2022 00:48:10 +0300
Subject: List edit UI overhaul

---
 src/App.js                                         |   4 +
 src/App.vue                                        |   2 +-
 src/components/lists_edit/lists_edit.js            |  80 +++++---
 src/components/lists_edit/lists_edit.vue           | 210 +++++++++++++++------
 .../lists_user_search/lists_user_search.js         |   7 +-
 .../lists_user_search/lists_user_search.vue        |  20 +-
 .../mobile_post_status_button.js                   |   3 +-
 src/components/tab_switcher/tab_switcher.scss      |   1 +
 src/i18n/en.json                                   |  13 +-
 9 files changed, 248 insertions(+), 92 deletions(-)

(limited to 'src/App.vue')

diff --git a/src/App.js b/src/App.js
index f5bd7e2e..12a12f71 100644
--- a/src/App.js
+++ b/src/App.js
@@ -85,8 +85,12 @@ export default {
     isChats () {
       return this.$route.name === 'chat' || this.$route.name === 'chats'
     },
+    isListEdit () {
+      return this.$route.name === 'lists-edit'
+    },
     newPostButtonShown () {
       if (this.isChats) return false
+      if (this.isListEdit) return false
       return this.$store.getters.mergedConfig.alwaysShowNewPostButton || this.layoutType === 'mobile'
     },
     showFeaturesPanel () { return this.$store.state.instance.showFeaturesPanel },
diff --git a/src/App.vue b/src/App.vue
index c741aa70..cb6a0115 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -33,7 +33,7 @@
       <div
         id="main-scroller"
         class="column main"
-        :class="{ '-full-height': isChats }"
+        :class="{ '-full-height': isChats || isListEdit }"
       >
         <div
           v-if="!currentUser"
diff --git a/src/components/lists_edit/lists_edit.js b/src/components/lists_edit/lists_edit.js
index e4d0c22a..b1516af0 100644
--- a/src/components/lists_edit/lists_edit.js
+++ b/src/components/lists_edit/lists_edit.js
@@ -1,7 +1,9 @@
 import { mapState, mapGetters } from 'vuex'
 import BasicUserCard from '../basic_user_card/basic_user_card.vue'
 import ListsUserSearch from '../lists_user_search/lists_user_search.vue'
+import PanelLoading from 'src/components/panel_loading/panel_loading.vue'
 import UserAvatar from '../user_avatar/user_avatar.vue'
+import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx'
 import { library } from '@fortawesome/fontawesome-svg-core'
 import {
   faSearch,
@@ -17,22 +19,32 @@ const ListsNew = {
   components: {
     BasicUserCard,
     UserAvatar,
-    ListsUserSearch
+    ListsUserSearch,
+    TabSwitcher,
+    PanelLoading
   },
   data () {
     return {
       title: '',
-      userIds: [],
-      selectedUserIds: []
+      titleDraft: '',
+      membersUserIds: [],
+      removedUserIds: new Set([]), // users we added for members, to undo
+      searchUserIds: [],
+      addedUserIds: new Set([]), // users we added from search, to undo
+      searchLoading: false,
+      reallyDelete: false
     }
   },
   created () {
     this.$store.dispatch('fetchList', { listId: this.id })
-      .then(() => { this.title = this.findListTitle(this.id) })
+      .then(() => {
+        this.title = this.findListTitle(this.id)
+        this.titleDraft = this.title
+      })
     this.$store.dispatch('fetchListAccounts', { listId: this.id })
       .then(() => {
-        this.selectedUserIds = this.findListAccounts(this.id)
-        this.selectedUserIds.forEach(userId => {
+        this.membersUserIds = this.findListAccounts(this.id)
+        this.membersUserIds.forEach(userId => {
           this.$store.dispatch('fetchUserIfMissing', userId)
         })
       })
@@ -41,11 +53,12 @@ const ListsNew = {
     id () {
       return this.$route.params.id
     },
-    users () {
-      return this.userIds.map(userId => this.findUser(userId))
+    membersUsers () {
+      return [...this.membersUserIds, ...this.addedUserIds]
+        .map(userId => this.findUser(userId)).filter(user => user)
     },
-    selectedUsers () {
-      return this.selectedUserIds.map(userId => this.findUser(userId)).filter(user => user)
+    searchUsers () {
+      return this.searchUserIds.map(userId => this.findUser(userId)).filter(user => user)
     },
     ...mapState({
       currentUser: state => state.users.currentUser
@@ -56,30 +69,51 @@ const ListsNew = {
     onInput () {
       this.search(this.query)
     },
-    selectUser (user) {
-      if (this.selectedUserIds.includes(user.id)) {
+    toggleRemoveMember (user) {
+      if (this.removedUserIds.has(user.id)) {
+        this.addUser(user)
+        this.removedUserIds.delete(user.id)
+      } else {
+        this.removeUser(user.id)
+        this.removedUserIds.add(user.id)
+      }
+    },
+    toggleAddFromSearch (user) {
+      if (this.addedUserIds.has(user.id)) {
         this.removeUser(user.id)
+        this.addedUserIds.delete(user.id)
       } else {
         this.addUser(user)
+        this.addedUserIds.add(user.id)
       }
     },
-    isSelected (user) {
-      return this.selectedUserIds.includes(user.id)
+    isRemoved (user) {
+      return this.removedUserIds.has(user.id)
+    },
+    isAdded (user) {
+      return this.addedUserIds.has(user.id)
     },
     addUser (user) {
-      this.selectedUserIds.push(user.id)
+      // this.selectedUserIds.push(user.id)
     },
     removeUser (userId) {
-      this.selectedUserIds = this.selectedUserIds.filter(id => id !== userId)
+      // this.selectedUserIds = this.selectedUserIds.filter(id => id !== userId)
     },
-    onResults (results) {
-      this.userIds = results
+    onSearchLoading (results) {
+      this.searchLoading = true
     },
-    updateList () {
-      this.$store.dispatch('setList', { listId: this.id, title: this.title })
-      this.$store.dispatch('setListAccounts', { listId: this.id, accountIds: this.selectedUserIds })
-
-      this.$router.push({ name: 'lists-timeline', params: { id: this.id } })
+    onSearchLoadingDone (results) {
+      this.searchLoading = false
+    },
+    onSearchResults (results) {
+      this.searchLoading = false
+      this.searchUserIds = results
+    },
+    updateListTitle () {
+      this.$store.dispatch('setList', { listId: this.id, title: this.titleDraft })
+        .then(() => {
+          this.title = this.findListTitle(this.id)
+        })
     },
     deleteList () {
       this.$store.dispatch('deleteList', { listId: this.id })
diff --git a/src/components/lists_edit/lists_edit.vue b/src/components/lists_edit/lists_edit.vue
index 69007b02..dffbff2f 100644
--- a/src/components/lists_edit/lists_edit.vue
+++ b/src/components/lists_edit/lists_edit.vue
@@ -1,8 +1,8 @@
 <template>
-  <div class="panel-default panel list-edit">
+  <div class="panel-default panel ListEdit">
     <div
       ref="header"
-      class="panel-heading"
+      class="panel-heading list-edit-heading"
     >
       <button
         class="button-unstyled go-back-button"
@@ -13,54 +13,129 @@
           icon="chevron-left"
         />
       </button>
-    </div>
-    <div class="input-wrap">
-      <input
-        ref="title"
-        v-model="title"
-        :placeholder="$t('lists.title')"
+      <div class="title">
+      <i18n-t
+        keypath="lists.editing_list"
       >
+        <template #listTitle>{{ title }}</template>
+      </i18n-t>
+      </div>
     </div>
-    <div class="member-list">
-      <div
-        v-for="user in selectedUsers"
-        :key="user.id"
-        class="member"
-      >
-        <BasicUserCard
-          :user="user"
-          :class="isSelected(user) ? 'selected' : ''"
-          @click.capture.prevent="selectUser(user)"
-        />
+    <div class="panel-body">
+      <div class="input-wrap">
+        <label for="list-edit-title">{{ $t('lists.title') }}</label>
+        {{ ' ' }}
+        <input
+          id="list-edit-title"
+          ref="title"
+          v-model="titleDraft"
+        >
+        <button
+          class="btn button-default follow-button"
+          @click="updateListTitle"
+        >
+          {{ $t('lists.update_title') }}
+        </button>
       </div>
+      <tab-switcher
+        class="list-member-management"
+        :scrollable-tabs="true"
+        >
+        <div
+          :label="$t('lists.manage_members')"
+          class="members-list"
+          >
+          <div class="users-list">
+            <div
+              v-for="user in membersUsers"
+              :key="user.id"
+              class="member"
+            >
+              <BasicUserCard
+                :user="user"
+              >
+                <button
+                  class="btn button-default follow-button"
+                  @click="toggleRemoveMember(user)"
+                >
+                  {{ isRemoved(user) ? $t('general.undo') : $t('lists.remove_from_list') }}
+                </button>
+              </BasicUserCard>
+            </div>
+          </div>
+        </div>
+
+        <div
+          class="search-list"
+          :label="$t('lists.add_members')"
+          >
+          <ListsUserSearch
+            @results="onSearchResults"
+            @loading="onSearchLoading"
+            @loadingDone="onSearchLoadingDone"
+          />
+          <div v-if="searchLoading" class="loading">
+            <PanelLoading />
+          </div>
+          <div v-else class="users-list">
+            <div
+              v-for="user in searchUsers"
+              :key="user.id"
+              class="member"
+            >
+              <BasicUserCard
+                :user="user"
+              >
+                <span
+                  v-if="membersUserIds.includes(user.id)"
+                >
+                  {{ $t('lists.is_in_list') }}
+                </span>
+                <button
+                  v-if="!membersUserIds.includes(user.id)"
+                  class="btn button-default follow-button"
+                  @click="toggleAddFromSearch(user)"
+                >
+                  {{ isAdded(user) ? $t('general.undo') : $t('lists.add_to_list') }}
+                </button>
+                <button
+                  v-else
+                  class="btn button-default follow-button"
+                  @click="toggleRemoveMember(user)"
+                >
+                  {{ isRemoved(user) ? $t('general.undo') : $t('lists.remove_from_list') }}
+                </button>
+              </BasicUserCard>
+            </div>
+          </div>
+        </div>
+      </tab-switcher>
     </div>
-    <ListsUserSearch @results="onResults" />
-    <div class="member-list">
-      <div
-        v-for="user in users"
-        :key="user.id"
-        class="member"
+    <div class="panel-footer">
+      <span class="spacer" />
+      <button
+        class="btn button-default delete-button"
+        @click="reallyDelete = true"
+        v-if="!reallyDelete"
       >
-        <BasicUserCard
-          :user="user"
-          :class="isSelected(user) ? 'selected' : ''"
-          @click.capture.prevent="selectUser(user)"
-        />
-      </div>
+        {{ $t('lists.delete') }}
+      </button>
+      <template v-else>
+        {{ $t('lists.really_delete') }}
+        <button
+          class="btn button-default delete-button"
+          @click="deleteList"
+        >
+        {{ $t('general.yes') }}
+        </button>
+        <button
+          class="btn button-default delete-button"
+          @click="reallyDelete = false"
+        >
+        {{ $t('general.no') }}
+        </button>
+      </template>
     </div>
-    <button
-      :disabled="title && title.length === 0"
-      class="btn button-default"
-      @click="updateList"
-    >
-      {{ $t('lists.save') }}
-    </button>
-    <button
-      class="btn button-default"
-      @click="deleteList"
-    >
-      {{ $t('lists.delete') }}
-    </button>
   </div>
 </template>
 
@@ -69,28 +144,43 @@
 <style lang="scss">
 @import '../../_variables.scss';
 
-.list-edit {
-  .input-wrap {
+.ListEdit {
+  --panel-body-padding: 0.5em;
+
+  height: calc(100vh - var(--navbar-height));
+  overflow: hidden;
+  display: flex;
+  flex-direction: column;
+
+  .list-edit-heading {
+    grid-template-columns: auto minmax(50%, 1fr);
+  }
+
+  .panel-body {
     display: flex;
-    margin: 0.7em 0.5em 0.7em 0.5em;
+    flex: 1;
+    flex-direction: column;
+    overflow: hidden;
+  }
 
-    input {
-      width: 100%;
-    }
+  .list-member-management {
+    flex: 1 0 auto;
   }
 
   .search-icon {
     margin-right: 0.3em;
   }
 
-  .member-list {
+  .users-list {
     padding-bottom: 0.7rem;
+    overflow-y: auto;
   }
 
-  .basic-user-card:hover,
-  .basic-user-card.selected {
-    cursor: pointer;
-    background-color: var(--selectedPost, $fallback--lightBg);
+  & .search-list,
+  & .members-list {
+    overflow: hidden;
+    flex-direction: column;
+    min-height: 0;
   }
 
   .go-back-button {
@@ -102,7 +192,15 @@
   }
 
   .btn {
-    margin: 0.5em;
+    margin: 0 0.5em;
+  }
+
+  .panel-footer {
+    grid-template-columns: minmax(10%, 1fr);
+
+    .delete-button {
+      min-width: 9em;
+    }
   }
 }
 </style>
diff --git a/src/components/lists_user_search/lists_user_search.js b/src/components/lists_user_search/lists_user_search.js
index 5798841a..c92ec0ee 100644
--- a/src/components/lists_user_search/lists_user_search.js
+++ b/src/components/lists_user_search/lists_user_search.js
@@ -15,6 +15,7 @@ const ListsUserSearch = {
   components: {
     Checkbox
   },
+  emits: ['loading', 'loadingDone', 'results'],
   data () {
     return {
       loading: false,
@@ -33,12 +34,16 @@ const ListsUserSearch = {
       }
 
       this.loading = true
+      this.$emit('loading')
       this.userIds = []
       this.$store.dispatch('search', { q: query, resolve: true, type: 'accounts', following: this.followingOnly })
         .then(data => {
-          this.loading = false
           this.$emit('results', data.accounts.map(a => a.id))
         })
+        .finally(() => {
+          this.loading = false
+          this.$emit('loadingDone')
+        })
     }
   }
 }
diff --git a/src/components/lists_user_search/lists_user_search.vue b/src/components/lists_user_search/lists_user_search.vue
index 03fb3ba6..8633170c 100644
--- a/src/components/lists_user_search/lists_user_search.vue
+++ b/src/components/lists_user_search/lists_user_search.vue
@@ -1,5 +1,5 @@
 <template>
-  <div>
+  <div class="ListsUserSearch">
     <div class="input-wrap">
       <div class="input-search">
         <FAIcon
@@ -29,17 +29,19 @@
 <style lang="scss">
 @import '../../_variables.scss';
 
-.input-wrap {
-  display: flex;
-  margin: 0.7em 0.5em 0.7em 0.5em;
+.ListsUserSearch {
+  .input-wrap {
+    display: flex;
+    margin: 0.7em 0.5em 0.7em 0.5em;
 
-  input {
-    width: 100%;
+    input {
+      width: 100%;
+    }
   }
-}
 
-.search-icon {
-  margin-right: 0.3em;
+  .search-icon {
+    margin-right: 0.3em;
+  }
 }
 
 </style>
diff --git a/src/components/mobile_post_status_button/mobile_post_status_button.js b/src/components/mobile_post_status_button/mobile_post_status_button.js
index ecf79b64..f7f96cd6 100644
--- a/src/components/mobile_post_status_button/mobile_post_status_button.js
+++ b/src/components/mobile_post_status_button/mobile_post_status_button.js
@@ -10,7 +10,8 @@ library.add(
 
 const HIDDEN_FOR_PAGES = new Set([
   'chats',
-  'chat'
+  'chat',
+  'lists-edit'
 ])
 
 const MobilePostStatusButton = {
diff --git a/src/components/tab_switcher/tab_switcher.scss b/src/components/tab_switcher/tab_switcher.scss
index 7a086b26..d930368c 100644
--- a/src/components/tab_switcher/tab_switcher.scss
+++ b/src/components/tab_switcher/tab_switcher.scss
@@ -17,6 +17,7 @@
       overflow-x: auto;
       padding-top: 5px;
       flex-direction: row;
+      flex: 0 0 auto;
 
       &::after, &::before {
         content: '';
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 7352b75c..733bd7ac 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -80,6 +80,9 @@
     "confirm": "Confirm",
     "verify": "Verify",
     "close": "Close",
+    "undo": "Undo",
+    "yes": "Yes",
+    "no": "No",
     "peek": "Peek",
     "role": {
       "admin": "Admin",
@@ -981,7 +984,15 @@
     "save": "Save changes",
     "delete": "Delete list",
     "following_only": "Limit to Following",
-    "manage_lists": "Manage lists"
+    "manage_lists": "Manage lists",
+    "manage_members": "Manage list members",
+    "add_members": "Search for more users",
+    "remove_from_list": "Remove from list",
+    "add_to_list": "Add to list",
+    "is_in_list": "Already in list",
+    "editing_list": "Editing list {listTitle}",
+    "update_title": "Save Title",
+    "really_delete": "Really delete list?"
   },
   "file_type": {
     "audio": "Audio",
-- 
cgit v1.2.3-70-g09d2


From a29835375a62549410a7df7922f8eb3f9b391487 Mon Sep 17 00:00:00 2001
From: Alexander Tumin <iamtakingiteasy@eientei.org>
Date: Wed, 17 Aug 2022 02:33:39 +0300
Subject: Allow column width configuration: allow stretching navbar with
 columns

---
 src/App.js                                         |  7 +++++++
 src/App.scss                                       | 15 ++++++++-------
 src/App.vue                                        |  5 ++++-
 src/components/desktop_nav/desktop_nav.scss        | 20 ++++++++++++++++++++
 src/components/settings_modal/tabs/general_tab.vue |  5 +++++
 src/i18n/en.json                                   |  1 +
 src/modules/config.js                              |  1 +
 7 files changed, 46 insertions(+), 8 deletions(-)

(limited to 'src/App.vue')

diff --git a/src/App.js b/src/App.js
index f5bd7e2e..d1ad16d5 100644
--- a/src/App.js
+++ b/src/App.js
@@ -60,6 +60,13 @@ export default {
         '-' + this.layoutType
       ]
     },
+    navClasses () {
+      const { navbarColumnStretch } = this.$store.getters.mergedConfig
+      return [
+        '-' + this.layoutType,
+        ...(navbarColumnStretch ? ['-column-stretch'] : [])
+      ]
+    },
     currentUser () { return this.$store.state.users.currentUser },
     userBackground () { return this.currentUser.background_image },
     instanceBackground () {
diff --git a/src/App.scss b/src/App.scss
index 3c16007e..02f5e049 100644
--- a/src/App.scss
+++ b/src/App.scss
@@ -185,13 +185,14 @@ nav {
   --maxiColumn: 45rem;
   --columnGap: 1em;
   --status-margin: 0.75em;
-
+  --effectiveSidebarColumnWidth: minmax(var(--miniColumn), var(--sidebarColumnWidth, var(--miniColumn)));
+  --effectiveNotifsColumnWidth: minmax(var(--miniColumn), var(--notifsColumnWidth, var(--miniColumn)));
   --effectiveContentColumnWidth: minmax(var(--miniColumn), var(--contentColumnWidth, var(--maxiColumn)));
 
   position: relative;
   display: grid;
   grid-template-columns:
-    minmax(var(--miniColumn), var(--sidebarColumnWidth, var(--miniColumn)))
+    var(--effectiveSidebarColumnWidth)
     var(--effectiveContentColumnWidth);
   grid-template-areas: "sidebar content";
   grid-template-rows: 1fr;
@@ -288,22 +289,22 @@ nav {
   &.-reverse:not(.-wide):not(.-mobile) {
     grid-template-columns:
       var(--effectiveContentColumnWidth)
-      minmax(var(--miniColumn), var(--sidebarColumnWidth, var(--miniColumn)));
+      var(--effectiveSidebarColumnWidth);
     grid-template-areas: "content sidebar";
   }
 
   &.-wide {
     grid-template-columns:
-      minmax(var(--miniColumn), var(--sidebarColumnWidth, var(--miniColumn)))
+      var(--effectiveSidebarColumnWidth)
       var(--effectiveContentColumnWidth)
-      minmax(var(--miniColumn), var(--notifsColumnWidth, var(--miniColumn)));
+      var(--effectiveNotifsColumnWidth);
     grid-template-areas: "sidebar content notifs";
 
     &.-reverse {
       grid-template-columns:
-        minmax(var(--miniColumn), var(--notifsColumnWidth, var(--miniColumn)))
+        var(--effectiveNotifsColumnWidth)
         var(--effectiveContentColumnWidth)
-        minmax(var(--miniColumn), var(--sidebarColumnWidth, var(--miniColumn)));
+        var(--effectiveSidebarColumnWidth);
       grid-template-areas: "notifs content sidebar";
     }
   }
diff --git a/src/App.vue b/src/App.vue
index c741aa70..1f96efe8 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -8,7 +8,10 @@
       class="app-bg-wrapper"
     />
     <MobileNav v-if="layoutType === 'mobile'" />
-    <DesktopNav v-else />
+    <DesktopNav
+      v-else
+      :class="navClasses"
+    />
     <Notifications v-if="currentUser" />
     <div
       id="content"
diff --git a/src/components/desktop_nav/desktop_nav.scss b/src/components/desktop_nav/desktop_nav.scss
index 71202244..f6c7c43d 100644
--- a/src/components/desktop_nav/desktop_nav.scss
+++ b/src/components/desktop_nav/desktop_nav.scss
@@ -23,6 +23,26 @@
     max-width: 980px;
   }
 
+  &.-column-stretch .inner-nav {
+    --miniColumn: 25rem;
+    --maxiColumn: 45rem;
+    --columnGap: 1em;
+    max-width: calc(
+      var(--sidebarColumnWidth, var(--miniColumn)) +
+      var(--contentColumnWidth, var(--maxiColumn)) +
+      var(--columnGap)
+    );
+  }
+
+  &.-column-stretch.-wide .inner-nav {
+    max-width: calc(
+      var(--sidebarColumnWidth, var(--miniColumn)) +
+      var(--contentColumnWidth, var(--maxiColumn)) +
+      var(--notifsColumnWidth, var(--miniColumn)) +
+      var(--columnGap)
+    );
+  }
+
   &.-logoLeft .inner-nav {
     grid-template-columns: auto 2fr 2fr;
     grid-template-areas: "logo sitename actions";
diff --git a/src/components/settings_modal/tabs/general_tab.vue b/src/components/settings_modal/tabs/general_tab.vue
index db321363..333b5493 100644
--- a/src/components/settings_modal/tabs/general_tab.vue
+++ b/src/components/settings_modal/tabs/general_tab.vue
@@ -122,6 +122,11 @@
             {{ $t('settings.right_sidebar') }}
           </BooleanSetting>
         </li>
+        <li>
+          <BooleanSetting path="navbarColumnStretch">
+            {{ $t('settings.navbar_column_stretch') }}
+          </BooleanSetting>
+        </li>
         <li>
           <ChoiceSetting
             v-if="user"
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 7e957ffd..a5d3cec6 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -412,6 +412,7 @@
     "hide_isp": "Hide instance-specific panel",
     "hide_shoutbox": "Hide instance shoutbox",
     "right_sidebar": "Reverse order of columns",
+    "navbar_column_stretch": "Stretch navbar to columns width",
     "always_show_post_button": "Always show floating New Post button",
     "hide_wallpaper": "Hide instance wallpaper",
     "preload_images": "Preload images",
diff --git a/src/modules/config.js b/src/modules/config.js
index 2918f865..1c2a45c2 100644
--- a/src/modules/config.js
+++ b/src/modules/config.js
@@ -87,6 +87,7 @@ export const defaultState = {
   sidebarColumnWidth: '25rem',
   contentColumnWidth: '45rem',
   notifsColumnWidth: '25rem',
+  navbarColumnStretch: false,
   listsNavigation: false,
   greentext: undefined, // instance default
   useAtIcon: undefined, // instance default
-- 
cgit v1.2.3-70-g09d2


From 3dd9f6f68ce5625018a711ca78aa5a2a31441433 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Sun, 9 Oct 2022 23:01:49 +0300
Subject: moved popovers space outside app because otherwise it causes weird
 issues A LOT

---
 index.html  | 1 +
 src/App.vue | 1 -
 2 files changed, 1 insertion(+), 1 deletion(-)

(limited to 'src/App.vue')

diff --git a/index.html b/index.html
index ba072eda..4af84a59 100644
--- a/index.html
+++ b/index.html
@@ -10,5 +10,6 @@
     <noscript>To use Pleroma, please enable JavaScript.</noscript>
     <div id="app"></div>
     <!-- built files will be auto injected -->
+    <div id="popovers" />
   </body>
 </html>
diff --git a/src/App.vue b/src/App.vue
index e0d709f7..060fa70a 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -73,7 +73,6 @@
     <UpdateNotification />
     <div id="modal" />
     <GlobalNoticeList />
-    <div id="popovers" />
   </div>
 </template>
 
-- 
cgit v1.2.3-70-g09d2


From f0ba0e68559b3665b76f0022c5ad3b8f457c37a5 Mon Sep 17 00:00:00 2001
From: tusooa <tusooa@kazv.moe>
Date: Mon, 7 Nov 2022 12:49:41 -0500
Subject: Use <main> for main content

---
 src/App.vue | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'src/App.vue')

diff --git a/src/App.vue b/src/App.vue
index e0d709f7..8dad8ce9 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -33,7 +33,7 @@
           <div id="notifs-sidebar" />
         </template>
       </div>
-      <div
+      <main
         id="main-scroller"
         class="column main"
         :class="{ '-full-height': isChats || isListEdit }"
@@ -50,7 +50,7 @@
           </router-link>
         </div>
         <router-view />
-      </div>
+      </main>
       <div
         id="notifs-column"
         class="column -scrollable"
-- 
cgit v1.2.3-70-g09d2


From 771933183be07d84f06103338f8b6b7c4ed282da Mon Sep 17 00:00:00 2001
From: tusooa <tusooa@kazv.moe>
Date: Tue, 8 Nov 2022 00:23:08 -0500
Subject: Make user panel and notification <aside>

---
 src/App.vue                              | 2 +-
 src/components/mobile_nav/mobile_nav.vue | 4 ++--
 src/components/user_panel/user_panel.vue | 4 ++--
 3 files changed, 5 insertions(+), 5 deletions(-)

(limited to 'src/App.vue')

diff --git a/src/App.vue b/src/App.vue
index 8dad8ce9..12b4f61b 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -30,7 +30,7 @@
           <instance-specific-panel v-if="showInstanceSpecificPanel" />
           <features-panel v-if="!currentUser && showFeaturesPanel" />
           <who-to-follow-panel v-if="currentUser && suggestionsEnabled" />
-          <div id="notifs-sidebar" />
+          <aside id="notifs-sidebar" />
         </template>
       </div>
       <main
diff --git a/src/components/mobile_nav/mobile_nav.vue b/src/components/mobile_nav/mobile_nav.vue
index ee360f80..6e732d1f 100644
--- a/src/components/mobile_nav/mobile_nav.vue
+++ b/src/components/mobile_nav/mobile_nav.vue
@@ -42,7 +42,7 @@
         </button>
       </div>
     </nav>
-    <div
+    <aside
       v-if="currentUser"
       class="mobile-notifications-drawer"
       :class="{ '-closed': !notificationsOpen }"
@@ -83,7 +83,7 @@
         ref="mobileNotifications"
         @scroll="onScroll"
       />
-    </div>
+    </aside>
     <SideDrawer
       ref="sideDrawer"
       :logout="logout"
diff --git a/src/components/user_panel/user_panel.vue b/src/components/user_panel/user_panel.vue
index 243de387..95ec97af 100644
--- a/src/components/user_panel/user_panel.vue
+++ b/src/components/user_panel/user_panel.vue
@@ -1,5 +1,5 @@
 <template>
-  <div class="user-panel">
+  <aside class="user-panel">
     <div
       v-if="signedIn"
       key="user-panel-signed"
@@ -16,7 +16,7 @@
       v-else
       key="user-panel"
     />
-  </div>
+  </aside>
 </template>
 
 <script src="./user_panel.js"></script>
-- 
cgit v1.2.3-70-g09d2


From a34bea75a808de9841f616896ebb630972475707 Mon Sep 17 00:00:00 2001
From: tusooa <tusooa@kazv.moe>
Date: Tue, 8 Nov 2022 00:37:22 -0500
Subject: Handle properly 2-col and 3-col desktop notifications

---
 src/App.vue                                    | 2 +-
 src/components/notifications/notifications.vue | 5 +++--
 2 files changed, 4 insertions(+), 3 deletions(-)

(limited to 'src/App.vue')

diff --git a/src/App.vue b/src/App.vue
index 12b4f61b..8dad8ce9 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -30,7 +30,7 @@
           <instance-specific-panel v-if="showInstanceSpecificPanel" />
           <features-panel v-if="!currentUser && showFeaturesPanel" />
           <who-to-follow-panel v-if="currentUser && suggestionsEnabled" />
-          <aside id="notifs-sidebar" />
+          <div id="notifs-sidebar" />
         </template>
       </div>
       <main
diff --git a/src/components/notifications/notifications.vue b/src/components/notifications/notifications.vue
index f9c90a7e..7ed419d1 100644
--- a/src/components/notifications/notifications.vue
+++ b/src/components/notifications/notifications.vue
@@ -3,7 +3,8 @@
     :disabled="minimalMode || disableTeleport"
     :to="teleportTarget"
   >
-    <div
+    <component
+      :is="noHeading ? 'div' : 'aside'"
       ref="root"
       :class="{ minimal: minimalMode }"
       class="Notifications"
@@ -88,7 +89,7 @@
           </div>
         </div>
       </div>
-    </div>
+    </component>
   </teleport>
 </template>
 
-- 
cgit v1.2.3-70-g09d2

