Browse Source

Merge branch 'tusooa/group-actor' into 'develop'

Support group actors

See merge request pleroma/pleroma-fe!1882
tusooa 1 year ago
parent
commit
9042792133

+ 1 - 0
changelog.d/group-actor.add

@@ -0,0 +1 @@
+Support group actors

+ 1 - 0
src/boot/after_store.js

@@ -261,6 +261,7 @@ const getNodeInfo = async ({ store }) => {
       store.dispatch('setInstanceOption', { name: 'pollLimits', value: metadata.pollLimits })
       store.dispatch('setInstanceOption', { name: 'mailerEnabled', value: metadata.mailerEnabled })
       store.dispatch('setInstanceOption', { name: 'quotingAvailable', value: features.includes('quote_posting') })
+      store.dispatch('setInstanceOption', { name: 'groupActorAvailable', value: features.includes('pleroma:group_actors') })
 
       const uploadLimits = metadata.uploadLimits
       store.dispatch('setInstanceOption', { name: 'uploadlimit', value: parseInt(uploadLimits.general) })

+ 1 - 1
src/components/settings_modal/tabs/filtering_tab.vue

@@ -51,7 +51,7 @@
         </li>
         <li>
           <BooleanSetting path="hideBotIndication">
-            {{ $t('settings.hide_bot_indication') }}
+            {{ $t('settings.hide_actor_type_indication') }}
           </BooleanSetting>
         </li>
         <ChoiceSetting

+ 11 - 2
src/components/settings_modal/tabs/profile_tab.js

@@ -9,6 +9,7 @@ import suggestor from 'src/components/emoji_input/suggestor.js'
 import Autosuggest from 'src/components/autosuggest/autosuggest.vue'
 import Checkbox from 'src/components/checkbox/checkbox.vue'
 import InterfaceLanguageSwitcher from 'src/components/interface_language_switcher/interface_language_switcher.vue'
+import Select from 'src/components/select/select.vue'
 import BooleanSetting from '../helpers/boolean_setting.vue'
 import SharedComputedObject from '../helpers/shared_computed_object.js'
 import localeService from 'src/services/locale/locale.service.js'
@@ -39,6 +40,7 @@ const ProfileTab = {
       showRole: this.$store.state.users.currentUser.show_role,
       role: this.$store.state.users.currentUser.role,
       bot: this.$store.state.users.currentUser.bot,
+      actorType: this.$store.state.users.currentUser.actor_type,
       pickAvatarBtnVisible: true,
       bannerUploading: false,
       backgroundUploading: false,
@@ -57,7 +59,8 @@ const ProfileTab = {
     ProgressButton,
     Checkbox,
     BooleanSetting,
-    InterfaceLanguageSwitcher
+    InterfaceLanguageSwitcher,
+    Select
   },
   computed: {
     user () {
@@ -116,6 +119,12 @@ const ProfileTab = {
     bannerImgSrc () {
       const src = this.$store.state.users.currentUser.cover_photo
       return (!src) ? this.defaultBanner : src
+    },
+    groupActorAvailable () {
+      return this.$store.state.instance.groupActorAvailable
+    },
+    availableActorTypes () {
+      return this.groupActorAvailable ? ['Person', 'Service', 'Group'] : ['Person', 'Service']
     }
   },
   methods: {
@@ -127,7 +136,7 @@ const ProfileTab = {
         /* eslint-disable camelcase */
         display_name: this.newName,
         fields_attributes: this.newFields.filter(el => el != null),
-        bot: this.bot,
+        actor_type: this.actorType,
         show_role: this.showRole,
         birthday: this.newBirthday || '',
         show_birthday: this.showBirthday

+ 17 - 3
src/components/settings_modal/tabs/profile_tab.vue

@@ -109,10 +109,24 @@
         </button>
       </div>
       <p>
-        <Checkbox v-model="bot">
-          {{ $t('settings.bot') }}
-        </Checkbox>
+        <label>
+          {{ $t('settings.actor_type') }}
+          <Select v-model="actorType">
+            <option
+              v-for="option in availableActorTypes"
+              :key="option"
+              :value="option"
+            >
+              {{ $t('settings.actor_type_' + option) }}
+            </option>
+          </Select>
+        </label>
       </p>
+      <div v-if="groupActorAvailable">
+        <small>
+          {{ $t('settings.actor_type_description') }}
+        </small>
+      </div>
       <p>
         <interface-language-switcher
           :prompt-text="$t('settings.email_language')"

+ 3 - 9
src/components/status/status.js

@@ -232,17 +232,11 @@ const Status = {
     muteWordHits () {
       return muteWordHits(this.status, this.muteWords)
     },
-    rtBotStatus () {
-      return this.statusoid.user.bot
-    },
     botStatus () {
-      return this.status.user.bot
-    },
-    botIndicator () {
-      return this.botStatus && !this.hideBotIndication
+      return this.status.user.actor_type === 'Service'
     },
-    rtBotIndicator () {
-      return this.rtBotStatus && !this.hideBotIndication
+    showActorTypeIndicator () {
+      return !this.hideBotIndication
     },
     mentionsLine () {
       if (!this.headTailLinks) return []

+ 3 - 3
src/components/status/status.vue

@@ -79,7 +79,7 @@
         <UserAvatar
           v-if="retweet"
           class="left-side repeater-avatar"
-          :bot="rtBotIndicator"
+          :show-actor-type-indicator="showActorTypeIndicator"
           :better-shadow="betterShadow"
           :user="statusoid.user"
         />
@@ -133,7 +133,7 @@
             >
               <UserAvatar
                 class="post-avatar"
-                :bot="botIndicator"
+                :show-actor-type-indicator="showActorTypeIndicator"
                 :compact="compact"
                 :better-shadow="betterShadow"
                 :user="status.user"
@@ -559,7 +559,7 @@
           <UserAvatar
             class="post-avatar"
             :compact="compact"
-            :bot="botIndicator"
+            :show-actor-type-indicator="showActorTypeIndicator"
           />
         </div>
         <div class="right-side">

+ 5 - 3
src/components/user_avatar/user_avatar.js

@@ -3,11 +3,13 @@ import StillImage from '../still-image/still-image.vue'
 import { library } from '@fortawesome/fontawesome-svg-core'
 
 import {
-  faRobot
+  faRobot,
+  faPeopleGroup
 } from '@fortawesome/free-solid-svg-icons'
 
 library.add(
-  faRobot
+  faRobot,
+  faPeopleGroup
 )
 
 const UserAvatar = {
@@ -15,7 +17,7 @@ const UserAvatar = {
     'user',
     'betterShadow',
     'compact',
-    'bot'
+    'showActorTypeIndicator'
   ],
   data () {
     return {

+ 8 - 3
src/components/user_avatar/user_avatar.vue

@@ -18,9 +18,14 @@
       :class="{ '-compact': compact }"
     />
     <FAIcon
-      v-if="bot"
+      v-if="showActorTypeIndicator && user?.actor_type === 'Service'"
       icon="robot"
-      class="bot-indicator"
+      class="actor-type-indicator"
+    />
+    <FAIcon
+      v-if="showActorTypeIndicator && user?.actor_type === 'Group'"
+      icon="people-group"
+      class="actor-type-indicator"
     />
   </span>
 </template>
@@ -79,7 +84,7 @@
     height: 100%;
   }
 
-  .bot-indicator {
+  .actor-type-indicator {
     position: absolute;
     bottom: 0;
     right: 0;

+ 7 - 1
src/components/user_card/user_card.vue

@@ -124,11 +124,17 @@
                   {{ $t(`general.role.${visibleRole}`) }}
                 </span>
                 <span
-                  v-if="user.bot"
+                  v-if="user.actor_type === 'Service'"
                   class="alert user-role"
                 >
                   {{ $t('user_card.bot') }}
                 </span>
+                <span
+                  v-if="user.actor_type === 'Group'"
+                  class="alert user-role"
+                >
+                  {{ $t('user_card.group') }}
+                </span>
               </template>
               <span v-if="user.locked">
                 <FAIcon

+ 7 - 2
src/i18n/en.json

@@ -360,6 +360,11 @@
     "remove_language": "Remove",
     "primary_language": "Primary language:",
     "fallback_language": "Fallback language {index}:",
+    "actor_type": "This account is:",
+    "actor_type_description": "Marking your account as a group will make it automatically repeat statuses that mention it.",
+    "actor_type_Person": "a normal user",
+    "actor_type_Service": "a bot",
+    "actor_type_Group": "a group",
     "app_name": "App name",
     "expert_mode": "Show advanced",
     "save": "Save changes",
@@ -424,7 +429,6 @@
     "added_backup": "Added a new backup.",
     "add_backup_error": "Error adding a new backup: {error}",
     "blocks_tab": "Blocks",
-    "bot": "This is a bot account",
     "btnRadius": "Buttons",
     "cBlue": "Blue (Reply, follow)",
     "cGreen": "Green (Retweet)",
@@ -496,7 +500,7 @@
     "hide_media_previews": "Hide media previews",
     "hide_muted_posts": "Hide posts of muted users",
     "mute_bot_posts": "Mute bot posts",
-    "hide_bot_indication": "Hide bot indication in posts",
+    "hide_actor_type_indication": "Hide actor type (bots, groups, etc.) indication in posts",
     "hide_scrobbles": "Hide scrobbles",
     "hide_all_muted_posts": "Hide muted posts",
     "max_thumbnails": "Maximum amount of thumbnails per post (empty = no limit)",
@@ -1128,6 +1132,7 @@
     "hide_repeats": "Hide repeats",
     "show_repeats": "Show repeats",
     "bot": "Bot",
+    "group": "Group",
     "birthday": "Born {birthday}",
     "admin_menu": {
       "moderation": "Moderation",

+ 1 - 0
src/modules/instance.js

@@ -137,6 +137,7 @@ const defaultState = {
   suggestionsEnabled: false,
   suggestionsWeb: '',
   quotingAvailable: false,
+  groupActorAvailable: false,
 
   // Html stuff
   instanceSpecificPanelContent: '',

+ 1 - 0
src/services/entity_normalizer/entity_normalizer.service.js

@@ -166,6 +166,7 @@ export const parseUser = (data) => {
         output.show_role = data.source.pleroma.show_role
         output.discoverable = data.source.pleroma.discoverable
         output.show_birthday = data.pleroma.show_birthday
+        output.actor_type = data.source.pleroma.actor_type
       }
     }