浏览代码

Merge branch 'release/2.6.x' into 'master'

merge 2.6.x to master since 2.6.1 release

See merge request pleroma/pleroma-fe!1874
HJ 1 年之前
父节点
当前提交
83acbf953a
共有 43 个文件被更改,包括 236 次插入52 次删除
  1. 31 0
      CHANGELOG.md
  2. 0 1
      changelog.d/add-taiwanese-aka-hokkien-i18n-support.add
  3. 0 1
      changelog.d/adminfe.add
  4. 0 0
      changelog.d/check-changelog.skip
  5. 0 1
      changelog.d/custom-emoji-notif-width.fix
  6. 0 1
      changelog.d/edit-profile-button.fix
  7. 0 1
      changelog.d/emoji-picker-button-accessible.fix
  8. 0 1
      changelog.d/export-subst-hash.fix
  9. 0 1
      changelog.d/fix-reports.fix
  10. 0 1
      changelog.d/html-attribute-parsing.fix
  11. 0 1
      changelog.d/mention-twice.fix
  12. 0 1
      changelog.d/mentionsline-shouldbreak.fix
  13. 0 1
      changelog.d/nonascii-tags.fix
  14. 0 1
      changelog.d/oauth2-token-linger.fix
  15. 0 1
      changelog.d/parser.fix
  16. 0 1
      changelog.d/quote-hide-oops.fix
  17. 0 1
      changelog.d/quote-hide.fix
  18. 0 1
      changelog.d/quote.add
  19. 0 1
      changelog.d/react-button-safari.fix
  20. 0 1
      changelog.d/react-button.fix
  21. 0 1
      changelog.d/reload-user-pinned.fix
  22. 0 1
      changelog.d/scroll-emoji-selector-safari.fix
  23. 1 1
      index.html
  24. 1 1
      package.json
  25. 2 1
      src/components/emoji_input/emoji_input.js
  26. 1 1
      src/components/emoji_picker/emoji_picker.vue
  27. 12 1
      src/components/extra_buttons/extra_buttons.js
  28. 18 1
      src/components/extra_buttons/extra_buttons.vue
  29. 1 1
      src/components/global_notice_list/global_notice_list.vue
  30. 2 1
      src/components/poll/poll.js
  31. 2 1
      src/components/post_status_form/post_status_form.js
  32. 2 0
      src/components/react_button/react_button.vue
  33. 48 3
      src/components/settings_modal/admin_tabs/frontends_tab.js
  34. 16 0
      src/components/settings_modal/admin_tabs/frontends_tab.scss
  35. 23 11
      src/components/settings_modal/admin_tabs/frontends_tab.vue
  36. 5 1
      src/components/settings_modal/admin_tabs/instance_tab.vue
  37. 1 0
      src/components/settings_modal/helpers/attachment_setting.js
  38. 34 4
      src/components/settings_modal/helpers/attachment_setting.vue
  39. 5 3
      src/i18n/en.json
  40. 0 1
      src/i18n/zh.json
  41. 1 0
      src/modules/adminSettings.js
  42. 3 0
      src/services/random_seed/random_seed.service.js
  43. 27 0
      tools/collect-changelog

+ 31 - 0
CHANGELOG.md

@@ -3,6 +3,37 @@ All notable changes to this project will be documented in this file.
 
 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
 
+## 2.6.1
+### Fixed
+- fix admin dashboard not having any feedback on frontend installation
+- Fix frontend admin tab crashing when no primary frontend is set
+- Add aria attributes to react and extra buttons
+
+## 2.6.0
+### Added
+- add the initial i18n translation file for Taiwanese (Hokkien), and modify some related files.
+- Implemented a very basic instance administration screen
+- Implement quoting
+
+### Fixed
+- Keep aspect ratio of custom emoji reaction in notification
+- Fix openSettingsModalTab so that it correctly opens Settings modal instead of Admin modal
+- Add alt text to emoji picker buttons
+- Use export-subst gitattribute to allow tarball builds
+- fix reports now showing reason/content
+- Fix HTML attribute parsing, discard attributes not strating with a letter
+- Make MentionsLine aware of line breaking by non-br elements
+- Fix a bug where mentioning a user twice will not fill the mention into the textarea
+- Fix parsing non-ascii tags
+- Fix OAuth2 token lingering after revocation
+- fix regex issue in HTML parser/renderer
+- don't display quoted status twice
+- fix typo in code that prevented cards from showing at all
+- Fix react button not working if reaction accounts are not loaded
+- Fix react button misalignment on safari ios
+- Fix pinned statuses gone when reloading user timeline
+- Fix scrolling emoji selector in modal in safari ios
+
 ## 2.5.1
 ### Fixed
 - Checkboxes in settings can now work with screenreaders

+ 0 - 1
changelog.d/add-taiwanese-aka-hokkien-i18n-support.add

@@ -1 +0,0 @@
-add the initial i18n translation file for Taiwanese (Hokkien), and modify some related files.

+ 0 - 1
changelog.d/adminfe.add

@@ -1 +0,0 @@
-Implemented a very basic instance administration screen

+ 0 - 0
changelog.d/check-changelog.skip


+ 0 - 1
changelog.d/custom-emoji-notif-width.fix

@@ -1 +0,0 @@
-Keep aspect ratio of custom emoji reaction in notification

+ 0 - 1
changelog.d/edit-profile-button.fix

@@ -1 +0,0 @@
-Fix openSettingsModalTab so that it correctly opens Settings modal instead of Admin modal

+ 0 - 1
changelog.d/emoji-picker-button-accessible.fix

@@ -1 +0,0 @@
-Add alt text to emoji picker buttons

+ 0 - 1
changelog.d/export-subst-hash.fix

@@ -1 +0,0 @@
-Use export-subst gitattribute to allow tarball builds

+ 0 - 1
changelog.d/fix-reports.fix

@@ -1 +0,0 @@
-fix reports now showing reason/content:w

+ 0 - 1
changelog.d/html-attribute-parsing.fix

@@ -1 +0,0 @@
-Fix HTML attribute parsing, discard attributes not strating with a letter

+ 0 - 1
changelog.d/mention-twice.fix

@@ -1 +0,0 @@
-Fix a bug where mentioning a user twice will not fill the mention into the textarea

+ 0 - 1
changelog.d/mentionsline-shouldbreak.fix

@@ -1 +0,0 @@
-Make MentionsLine aware of line breaking by non-br elements

+ 0 - 1
changelog.d/nonascii-tags.fix

@@ -1 +0,0 @@
-Fix parsing non-ascii tags

+ 0 - 1
changelog.d/oauth2-token-linger.fix

@@ -1 +0,0 @@
-Fix OAuth2 token lingering after revocation

+ 0 - 1
changelog.d/parser.fix

@@ -1 +0,0 @@
-fix regex issue in HTML parser/renderer

+ 0 - 1
changelog.d/quote-hide-oops.fix

@@ -1 +0,0 @@
-fix typo in code that prevented cards from showing at all

+ 0 - 1
changelog.d/quote-hide.fix

@@ -1 +0,0 @@
-don't display quoted status twice

+ 0 - 1
changelog.d/quote.add

@@ -1 +0,0 @@
-Implement quoting

+ 0 - 1
changelog.d/react-button-safari.fix

@@ -1 +0,0 @@
-Fix react button misalignment on safari ios

+ 0 - 1
changelog.d/react-button.fix

@@ -1 +0,0 @@
-Fix react button not working if reaction accounts are not loaded

+ 0 - 1
changelog.d/reload-user-pinned.fix

@@ -1 +0,0 @@
-Fix pinned statuses gone when reloading user timeline

+ 0 - 1
changelog.d/scroll-emoji-selector-safari.fix

@@ -1 +0,0 @@
-Fix scrolling emoji selector in modal in safari ios

+ 1 - 1
index.html

@@ -3,8 +3,8 @@
   <head>
     <meta charset="utf-8">
     <meta name="viewport" content="width=device-width, initial-scale=1,user-scalable=no">
-    <!--server-generated-meta-->
     <link rel="icon" type="image/png" href="/favicon.png">
+    <!--server-generated-meta-->
   </head>
   <body class="hidden">
     <noscript>To use Pleroma, please enable JavaScript.</noscript>

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "pleroma_fe",
-  "version": "2.5.0",
+  "version": "2.6.1",
   "description": "Pleroma frontend, the default frontend of Pleroma social network server",
   "author": "Pleroma contributors <https://git.pleroma.social/pleroma/pleroma-fe/-/blob/develop/CONTRIBUTORS.md>",
   "private": false,

+ 2 - 1
src/components/emoji_input/emoji_input.js

@@ -1,4 +1,5 @@
 import Completion from '../../services/completion/completion.js'
+import genRandomSeed from '../../services/random_seed/random_seed.service.js'
 import EmojiPicker from '../emoji_picker/emoji_picker.vue'
 import Popover from 'src/components/popover/popover.vue'
 import ScreenReaderNotice from 'src/components/screen_reader_notice/screen_reader_notice.vue'
@@ -110,7 +111,7 @@ const EmojiInput = {
   },
   data () {
     return {
-      randomSeed: `${Math.random()}`.replace('.', '-'),
+      randomSeed: genRandomSeed(),
       input: undefined,
       caretEl: undefined,
       highlighted: -1,

+ 1 - 1
src/components/emoji_picker/emoji_picker.vue

@@ -3,7 +3,7 @@
     ref="popover"
     trigger="click"
     popover-class="emoji-picker popover-default"
-    :trigger-attrs="{ 'aria-hidden': true }"
+    :trigger-attrs="{ 'aria-hidden': true, tabindex: -1 }"
     @show="onPopoverShown"
     @close="onPopoverClosed"
   >

+ 12 - 1
src/components/extra_buttons/extra_buttons.js

@@ -1,4 +1,5 @@
 import Popover from '../popover/popover.vue'
+import genRandomSeed from '../../services/random_seed/random_seed.service.js'
 import ConfirmModal from '../confirm_modal/confirm_modal.vue'
 import { library } from '@fortawesome/fontawesome-svg-core'
 import {
@@ -40,7 +41,8 @@ const ExtraButtons = {
   data () {
     return {
       expanded: false,
-      showingDeleteDialog: false
+      showingDeleteDialog: false,
+      randomSeed: genRandomSeed()
     }
   },
   methods: {
@@ -152,6 +154,15 @@ const ExtraButtons = {
     editingAvailable () { return this.$store.state.instance.editingAvailable },
     shouldConfirmDelete () {
       return this.$store.getters.mergedConfig.modalOnDelete
+    },
+    triggerAttrs () {
+      return {
+        title: this.$t('status.more_actions'),
+        id: `popup-trigger-${this.randomSeed}`,
+        'aria-controls': `popup-menu-${this.randomSeed}`,
+        'aria-expanded': this.expanded,
+        'aria-haspopup': 'menu'
+      }
     }
   }
 }

+ 18 - 1
src/components/extra_buttons/extra_buttons.vue

@@ -2,6 +2,7 @@
   <Popover
     class="ExtraButtons"
     trigger="click"
+    :trigger-attrs="triggerAttrs"
     placement="top"
     :offset="{ y: 5 }"
     :bound-to="{ x: 'container' }"
@@ -10,10 +11,15 @@
     @close="onClose"
   >
     <template #content="{close}">
-      <div class="dropdown-menu">
+      <div
+        class="dropdown-menu"
+        role="menu"
+        :id="`popup-menu-${randomSeed}`"
+      >
         <button
           v-if="canMute && !status.thread_muted"
           class="button-default dropdown-item dropdown-item-icon"
+          role="menuitem"
           @click.prevent="muteConversation"
         >
           <FAIcon
@@ -24,6 +30,7 @@
         <button
           v-if="canMute && status.thread_muted"
           class="button-default dropdown-item dropdown-item-icon"
+          role="menuitem"
           @click.prevent="unmuteConversation"
         >
           <FAIcon
@@ -34,6 +41,7 @@
         <button
           v-if="!status.pinned && canPin"
           class="button-default dropdown-item dropdown-item-icon"
+          role="menuitem"
           @click.prevent="pinStatus"
           @click="close"
         >
@@ -45,6 +53,7 @@
         <button
           v-if="status.pinned && canPin"
           class="button-default dropdown-item dropdown-item-icon"
+          role="menuitem"
           @click.prevent="unpinStatus"
           @click="close"
         >
@@ -57,6 +66,7 @@
           <button
             v-if="!status.bookmarked"
             class="button-default dropdown-item dropdown-item-icon"
+            role="menuitem"
             @click.prevent="bookmarkStatus"
             @click="close"
           >
@@ -68,6 +78,7 @@
           <button
             v-if="status.bookmarked"
             class="button-default dropdown-item dropdown-item-icon"
+            role="menuitem"
             @click.prevent="unbookmarkStatus"
             @click="close"
           >
@@ -80,6 +91,7 @@
         <button
           v-if="ownStatus && editingAvailable"
           class="button-default dropdown-item dropdown-item-icon"
+          role="menuitem"
           @click.prevent="editStatus"
           @click="close"
         >
@@ -91,6 +103,7 @@
         <button
           v-if="isEdited && editingAvailable"
           class="button-default dropdown-item dropdown-item-icon"
+          role="menuitem"
           @click.prevent="showStatusHistory"
           @click="close"
         >
@@ -102,6 +115,7 @@
         <button
           v-if="canDelete"
           class="button-default dropdown-item dropdown-item-icon"
+          role="menuitem"
           @click.prevent="deleteStatus"
           @click="close"
         >
@@ -112,6 +126,7 @@
         </button>
         <button
           class="button-default dropdown-item dropdown-item-icon"
+          role="menuitem"
           @click.prevent="copyLink"
           @click="close"
         >
@@ -123,6 +138,7 @@
         <a
           v-if="!status.is_local"
           class="button-default dropdown-item dropdown-item-icon"
+          role="menuitem"
           title="Source"
           :href="status.external_url"
           target="_blank"
@@ -134,6 +150,7 @@
         </a>
         <button
           class="button-default dropdown-item dropdown-item-icon"
+          role="menuitem"
           @click.prevent="reportStatus"
           @click="close"
         >

+ 1 - 1
src/components/global_notice_list/global_notice_list.vue

@@ -32,7 +32,7 @@
   top: calc(var(--navbar-height) + 0.5em);
   width: 100%;
   pointer-events: none;
-  z-index: var(--ZI_navbar_popovers);
+  z-index: var(--ZI_modals_popovers);
   display: flex;
   flex-direction: column;
   align-items: center;

+ 2 - 1
src/components/poll/poll.js

@@ -1,4 +1,5 @@
 import Timeago from 'components/timeago/timeago.vue'
+import genRandomSeed from '../../services/random_seed/random_seed.service.js'
 import RichContent from 'components/rich_content/rich_content.jsx'
 import { forEach, map } from 'lodash'
 
@@ -13,7 +14,7 @@ export default {
     return {
       loading: false,
       choices: [],
-      randomSeed: `${Math.random()}`.replace('.', '-')
+      randomSeed: genRandomSeed()
     }
   },
   created () {

+ 2 - 1
src/components/post_status_form/post_status_form.js

@@ -1,4 +1,5 @@
 import statusPoster from '../../services/status_poster/status_poster.service.js'
+import genRandomSeed from '../../services/random_seed/random_seed.service.js'
 import MediaUpload from '../media_upload/media_upload.vue'
 import ScopeSelector from '../scope_selector/scope_selector.vue'
 import EmojiInput from '../emoji_input/emoji_input.vue'
@@ -162,7 +163,7 @@ const PostStatusForm = {
     }
 
     return {
-      randomSeed: `${Math.random()}`.replace('.', '-'),
+      randomSeed: genRandomSeed(),
       dropFiles: [],
       uploadingFiles: false,
       error: null,

+ 2 - 0
src/components/react_button/react_button.vue

@@ -11,6 +11,8 @@
     />
     <span
       class="button-unstyled popover-trigger"
+      role="button"
+      :tabindex="0"
       :title="$t('tool_tip.add_reaction')"
       @click.stop.prevent="show"
     >

+ 48 - 3
src/components/settings_modal/admin_tabs/frontends_tab.js

@@ -4,6 +4,7 @@ import IntegerSetting from '../helpers/integer_setting.vue'
 import StringSetting from '../helpers/string_setting.vue'
 import GroupSetting from '../helpers/group_setting.vue'
 import Popover from 'src/components/popover/popover.vue'
+import PanelLoading from 'src/components/panel_loading/panel_loading.vue'
 
 import SharedComputedObject from '../helpers/shared_computed_object.js'
 import { library } from '@fortawesome/fontawesome-svg-core'
@@ -22,12 +23,18 @@ const FrontendsTab = {
       defaultSource: 'admin'
     }
   },
+  data () {
+    return {
+      working: false
+    }
+  },
   components: {
     BooleanSetting,
     ChoiceSetting,
     IntegerSetting,
     StringSetting,
     GroupSetting,
+    PanelLoading,
     Popover
   },
   created () {
@@ -42,18 +49,56 @@ const FrontendsTab = {
     ...SharedComputedObject()
   },
   methods: {
+    canInstall (frontend) {
+      const fe = this.frontends.find(f => f.name === frontend.name)
+      if (!fe) return false
+      return fe.refs.includes(frontend.ref)
+    },
+    getSuggestedRef (frontend) {
+      const defaultFe = this.adminDraft[':pleroma'][':frontends'][':primary']
+      if (defaultFe?.name === frontend.name && this.canInstall(defaultFe)) {
+        return defaultFe.ref
+      } else {
+        return frontend.refs[0]
+      }
+    },
     update (frontend, suggestRef) {
-      const ref = suggestRef || frontend.refs[0]
+      const ref = suggestRef || this.getSuggestedRef(frontend)
       const { name } = frontend
       const payload = { name, ref }
 
+      this.working = true
       this.$store.state.api.backendInteractor.installFrontend({ payload })
-        .then((externalUser) => {
+        .finally(() => {
+          this.working = false
+        })
+        .then(async (response) => {
           this.$store.dispatch('loadFrontendsStuff')
+          if (response.error) {
+            const reason = await response.error.json()
+            this.$store.dispatch('pushGlobalNotice', {
+              level: 'error',
+              messageKey: 'admin_dash.frontend.failure_installing_frontend',
+              messageArgs: {
+                version: name + '/' + ref,
+                reason: reason.error
+              },
+              timeout: 5000
+            })
+          } else {
+            this.$store.dispatch('pushGlobalNotice', {
+              level: 'success',
+              messageKey: 'admin_dash.frontend.success_installing_frontend',
+              messageArgs: {
+                version: name + '/' + ref
+              },
+              timeout: 2000
+            })
+          }
         })
     },
     setDefault (frontend, suggestRef) {
-      const ref = suggestRef || frontend.refs[0]
+      const ref = suggestRef || this.getSuggestedRef(frontend)
       const { name } = frontend
 
       this.$store.commit('updateAdminDraft', { path: [':pleroma', ':frontends', ':primary'], value: { name, ref } })

+ 16 - 0
src/components/settings_modal/admin_tabs/frontends_tab.scss

@@ -3,6 +3,22 @@
     padding: 0;
   }
 
+  .relative {
+    position: relative;
+  }
+
+  .overlay {
+    position: absolute;
+    background: var(--bg);
+    // fix buttons showing through
+    z-index: 2;
+    opacity: 0.9;
+    top: 0;
+    bottom: 0;
+    left: 0;
+    right: 0;
+  }
+
   dd {
     text-overflow: ellipsis;
     word-wrap: nowrap;

+ 23 - 11
src/components/settings_modal/admin_tabs/frontends_tab.vue

@@ -10,7 +10,6 @@
         <li>
           <h3>{{ $t('admin_dash.frontend.default_frontend') }}</h3>
           <p>{{ $t('admin_dash.frontend.default_frontend_tip') }}</p>
-          <p>{{ $t('admin_dash.frontend.default_frontend_tip2') }}</p>
           <ul class="setting-list">
             <li>
               <StringSetting path=":pleroma.:frontends.:primary.name" />
@@ -24,7 +23,8 @@
           </ul>
         </li>
       </ul>
-      <div class="setting-list">
+      <div class="setting-list relative">
+        <PanelLoading class="overlay" v-if="working"/>
         <h3>{{ $t('admin_dash.frontend.available_frontends') }}</h3>
         <ul class="cards-list">
           <li
@@ -33,9 +33,9 @@
           >
             <strong>{{ frontend.name }}</strong>
             {{ ' ' }}
-            <span v-if="adminDraft[':pleroma'][':frontends'][':primary'].name === frontend.name">
+            <span v-if="adminDraft[':pleroma'][':frontends'][':primary']?.name === frontend.name">
               <i18n-t
-                v-if="adminDraft[':pleroma'][':frontends'][':primary'].ref === frontend.refs[0]"
+                v-if="adminDraft[':pleroma'][':frontends'][':primary']?.ref === frontend.refs[0]"
                 keypath="admin_dash.frontend.is_default"
               />
               <i18n-t
@@ -86,6 +86,11 @@
                       ? $t('admin_dash.frontend.reinstall')
                       : $t('admin_dash.frontend.install')
                   }}
+                  <code>
+                    {{
+                      getSuggestedRef(frontend)
+                    }}
+                  </code>
                 </button>
                 <Popover
                   v-if="frontend.refs.length > 1"
@@ -93,13 +98,14 @@
                   class="button-dropdown"
                   placement="bottom"
                 >
-                  <template #content>
+                  <template #content="{close}">
                     <div class="dropdown-menu">
                       <button
                         v-for="ref in frontend.refs"
                         :key="ref"
                         class="button-default dropdown-item"
-                        @click="update(frontend, ref)"
+                        @click.prevent="update(frontend, ref)"
+                        @click="close"
                       >
                         <i18n-t keypath="admin_dash.frontend.install_version">
                           <template #version>
@@ -128,14 +134,19 @@
                   class="button button-default btn"
                   type="button"
                   :disabled="
-                    adminDraft[':pleroma'][':frontends'][':primary'].name === frontend.name &&
-                      adminDraft[':pleroma'][':frontends'][':primary'].ref === frontend.refs[0]
+                    adminDraft[':pleroma'][':frontends'][':primary']?.name === frontend.name &&
+                      adminDraft[':pleroma'][':frontends'][':primary']?.ref === frontend.refs[0]
                   "
                   @click="setDefault(frontend)"
                 >
                   {{
                     $t('admin_dash.frontend.set_default')
                   }}
+                  <code>
+                    {{
+                      getSuggestedRef(frontend)
+                    }}
+                  </code>
                 </button>
                 {{ ' ' }}
                 <Popover
@@ -144,13 +155,14 @@
                   class="button-dropdown"
                   placement="bottom"
                 >
-                  <template #content>
+                  <template #content="{close}">
                     <div class="dropdown-menu">
                       <button
-                        v-for="ref in frontend.refs.slice(1)"
+                        v-for="ref in frontend.installedRefs || frontend.refs"
                         :key="ref"
                         class="button-default dropdown-item"
-                        @click="setDefault(frontend, ref)"
+                        @click.prevent="setDefault(frontend, ref)"
+                        @click="close"
                       >
                         <i18n-t keypath="admin_dash.frontend.set_default_version">
                           <template #version>

+ 5 - 1
src/components/settings_modal/admin_tabs/instance_tab.vue

@@ -6,6 +6,10 @@
         <li>
           <StringSetting path=":pleroma.:instance.:name" />
         </li>
+        <!-- See https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3963 -->
+        <li v-if="adminDraft[':pleroma'][':instance'][':favicon'] !== undefined">
+          <AttachmentSetting compact path=":pleroma.:instance.:favicon" />
+        </li>
         <li>
           <StringSetting path=":pleroma.:instance.:email" />
         </li>
@@ -16,7 +20,7 @@
           <StringSetting path=":pleroma.:instance.:short_description" />
         </li>
         <li>
-          <AttachmentSetting path=":pleroma.:instance.:instance_thumbnail" />
+          <AttachmentSetting compact path=":pleroma.:instance.:instance_thumbnail" />
         </li>
         <li>
           <AttachmentSetting path=":pleroma.:instance.:background_image" />

+ 1 - 0
src/components/settings_modal/helpers/attachment_setting.js

@@ -7,6 +7,7 @@ export default {
   ...Setting,
   props: {
     ...Setting.props,
+    compact: Boolean,
     acceptTypes: {
       type: String,
       required: false,

+ 34 - 4
src/components/settings_modal/helpers/attachment_setting.vue

@@ -2,6 +2,7 @@
   <span
     v-if="matchesExpertLevel"
     class="AttachmentSetting"
+    :class="{ '-compact': compact }"
   >
     <label
       :for="path"
@@ -24,8 +25,8 @@
       {{ backendDescriptionDescription + ' ' }}
     </p>
     <div class="attachment-input">
-      <div>{{ $t('settings.url') }}</div>
-      <div class="controls">
+      <div class="controls control-field">
+        <label for="path">{{ $t('settings.url') }}</label>
         <input
           :id="path"
           class="string-input"
@@ -40,7 +41,7 @@
         />
         <ProfileSettingIndicator :is-profile="isProfileSetting" />
       </div>
-      <div>{{ $t('settings.preview') }}</div>
+      <div v-if="!compact">{{ $t('settings.preview') }}</div>
       <Attachment
         class="attachment"
         :compact="compact"
@@ -50,7 +51,7 @@
         @setMedia="onMedia"
         @naturalSizeLoad="onNaturalSizeLoad"
       />
-      <div class="controls">
+      <div class="controls control-upload">
         <MediaUpload
           ref="mediaUpload"
           class="media-upload-icon"
@@ -84,6 +85,35 @@
     width: 20em;
   }
 
+  &.-compact {
+    .attachment-input {
+      flex-direction: row;
+      align-items: flex-end;
+    }
+
+    .attachment {
+      flex: 0;
+      order: 0;
+      display: block;
+      min-width: 4em;
+      height: 4em;
+      align-self: center;
+      margin-bottom: 0;
+    }
+
+    .control-field {
+      order: 1;
+      min-width: 12em;
+      margin-left: 0.5em;
+    }
+
+    .control-upload {
+      order: 2;
+      min-width: 12em;
+      padding: 0 0.5em;
+    }
+  }
+
   .controls {
     margin-bottom: 0.5em;
 

+ 5 - 3
src/i18n/en.json

@@ -902,8 +902,9 @@
       "wip_notice": "Please note that this section is a WIP and lacks certain features as backend implementation of front-end management is incomplete.",
       "default_frontend": "Default front-end",
       "default_frontend_tip": "Default front-end will be shown to all users. Currently there's no way to for a user to select personal front-end. If you switch away from PleromaFE you'll most likely have to use old and buggy AdminFE to do instance configuration until we replace it.",
-      "default_frontend_tip2": "WIP: Since Pleroma backend doesn't properly list all installed frontends you'll have to enter name and reference manually. List below provides shortcuts to fill the values.",
-      "available_frontends": "Available for install"
+      "available_frontends": "Available for install",
+      "failure_installing_frontend": "Failed to install frontend {version}: {reason}",
+      "success_installing_frontend": "Frontend {version} successfully installed"
     },
     "temp_overrides": {
       ":pleroma": {
@@ -1033,7 +1034,8 @@
     "reaction_count_label": "{num} person reacted | {num} people reacted",
     "hide_quote": "Hide the quoted status",
     "display_quote": "Display the quoted status",
-    "invisible_quote": "Quoted status unavailable: {link}"
+    "invisible_quote": "Quoted status unavailable: {link}",
+    "more_actions": "More actions on this status"
   },
   "user_card": {
     "approve": "Approve",

+ 0 - 1
src/i18n/zh.json

@@ -1266,7 +1266,6 @@
       "wip_notice": "请注意,此部分是一个WIP,缺乏某些功能,因为前端管理的后台实现并不完整。",
       "default_frontend": "默认前端",
       "default_frontend_tip": "默认的前端将显示给所有用户。目前还没有办法让用户选择个人的前端。如果你不使用 PleromaFE,你很可能不得不使用旧的和有问题的 AdminFE 来进行实例配置,直到我们替换它。",
-      "default_frontend_tip2": "WIP: 由于 Pleroma 后端没有正确列出所有已安装的前端,你必须手动输入名称和引用。下面的列表提供了填写这些值的快捷方式。",
       "available_frontends": "可供安装"
     },
     "temp_overrides": {

+ 1 - 0
src/modules/adminSettings.js

@@ -26,6 +26,7 @@ const adminSettingsStorage = {
     },
     setAvailableFrontends (state, { frontends }) {
       state.frontends = frontends.map(f => {
+        f.installedRefs = f.installed_refs
         if (f.name === 'pleroma-fe') {
           f.refs = ['master', 'develop']
         } else {

+ 3 - 0
src/services/random_seed/random_seed.service.js

@@ -0,0 +1,3 @@
+const genRandomSeed = () => `${Math.random()}`.replace('.', '-')
+
+export default genRandomSeed

+ 27 - 0
tools/collect-changelog

@@ -0,0 +1,27 @@
+#!/bin/sh
+
+collectType() {
+    local suffix="$1"
+    local header="$2"
+    local printed=0
+    for file in changelog.d/*."$suffix"; do
+        if [ '!' -f "$file" ]; then
+            continue
+        fi
+        if [ "$printed" = 0 ]; then
+            echo
+            echo "### $header"
+            printed=1
+        fi
+        # Normalize any trailing newlines/spaces, etc.
+        echo "- $(cat "$file")"
+    done
+}
+
+collectType security Security
+collectType change Changed
+collectType add Added
+collectType fix Fixed
+collectType remove Removed
+
+rm changelog.d/*