Merge branch 'from/develop/tusooa/1118-enhanced-mention-link' into 'develop'
Enhanced mention link Closes #1118 See merge request pleroma/pleroma-fe!1424
This commit is contained in:
		
						commit
						8ade11783a
					
				
					 8 changed files with 148 additions and 10 deletions
				
			
		| 
						 | 
				
			
			@ -1,6 +1,7 @@
 | 
			
		|||
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
 | 
			
		||||
import { mapGetters, mapState } from 'vuex'
 | 
			
		||||
import { highlightClass, highlightStyle } from '../../services/user_highlighter/user_highlighter.js'
 | 
			
		||||
import UserAvatar from '../user_avatar/user_avatar.vue'
 | 
			
		||||
import { library } from '@fortawesome/fontawesome-svg-core'
 | 
			
		||||
import {
 | 
			
		||||
  faAt
 | 
			
		||||
| 
						 | 
				
			
			@ -12,6 +13,9 @@ library.add(
 | 
			
		|||
 | 
			
		||||
const MentionLink = {
 | 
			
		||||
  name: 'MentionLink',
 | 
			
		||||
  components: {
 | 
			
		||||
    UserAvatar
 | 
			
		||||
  },
 | 
			
		||||
  props: {
 | 
			
		||||
    url: {
 | 
			
		||||
      required: true,
 | 
			
		||||
| 
						 | 
				
			
			@ -50,6 +54,10 @@ const MentionLink = {
 | 
			
		|||
    userName () {
 | 
			
		||||
      return this.user && this.userNameFullUi.split('@')[0]
 | 
			
		||||
    },
 | 
			
		||||
    serverName () {
 | 
			
		||||
      // XXX assumed that domain does not contain @
 | 
			
		||||
      return this.user && (this.userNameFullUi.split('@')[1] || this.$store.getters.instanceDomain)
 | 
			
		||||
    },
 | 
			
		||||
    userNameFull () {
 | 
			
		||||
      return this.user && this.user.screen_name
 | 
			
		||||
    },
 | 
			
		||||
| 
						 | 
				
			
			@ -85,6 +93,31 @@ const MentionLink = {
 | 
			
		|||
        this.highlightType
 | 
			
		||||
      ]
 | 
			
		||||
    },
 | 
			
		||||
    useAtIcon () {
 | 
			
		||||
      return this.mergedConfig.useAtIcon
 | 
			
		||||
    },
 | 
			
		||||
    isRemote () {
 | 
			
		||||
      return this.userName !== this.userNameFull
 | 
			
		||||
    },
 | 
			
		||||
    shouldShowFullUserName () {
 | 
			
		||||
      const conf = this.mergedConfig.mentionLinkDisplay
 | 
			
		||||
      if (conf === 'short') {
 | 
			
		||||
        return false
 | 
			
		||||
      } else if (conf === 'full') {
 | 
			
		||||
        return true
 | 
			
		||||
      } else { // full_for_remote
 | 
			
		||||
        return this.isRemote
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    shouldShowTooltip () {
 | 
			
		||||
      return this.mergedConfig.mentionLinkShowTooltip && this.mergedConfig.mentionLinkDisplay === 'short' && this.isRemote
 | 
			
		||||
    },
 | 
			
		||||
    shouldShowAvatar () {
 | 
			
		||||
      return this.mergedConfig.mentionLinkShowAvatar
 | 
			
		||||
    },
 | 
			
		||||
    shouldFadeDomain () {
 | 
			
		||||
      return this.mergedConfig.mentionLinkFadeDomain
 | 
			
		||||
    },
 | 
			
		||||
    ...mapGetters(['mergedConfig']),
 | 
			
		||||
    ...mapState({
 | 
			
		||||
      currentUser: state => state.users.currentUser
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,5 @@
 | 
			
		|||
@import '../../_variables.scss';
 | 
			
		||||
 | 
			
		||||
.MentionLink {
 | 
			
		||||
  position: relative;
 | 
			
		||||
  white-space: normal;
 | 
			
		||||
| 
						 | 
				
			
			@ -10,6 +12,15 @@
 | 
			
		|||
    border-radius: 2px;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .mention-avatar {
 | 
			
		||||
    border-radius: var(--avatarAltRadius, $fallback--avatarAltRadius);
 | 
			
		||||
    width: 1.5em;
 | 
			
		||||
    height: 1.5em;
 | 
			
		||||
    vertical-align: middle;
 | 
			
		||||
    user-select: none;
 | 
			
		||||
    margin-right: 0.2em;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .full {
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    display: inline-block;
 | 
			
		||||
| 
						 | 
				
			
			@ -27,7 +38,8 @@
 | 
			
		|||
    user-select: all;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .short {
 | 
			
		||||
  .short.-with-tooltip,
 | 
			
		||||
  .you {
 | 
			
		||||
    user-select: none;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -56,7 +68,7 @@
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    &.-striped {
 | 
			
		||||
      & .userName,
 | 
			
		||||
      & .shortName,
 | 
			
		||||
      & .full {
 | 
			
		||||
        background-image:
 | 
			
		||||
          repeating-linear-gradient(
 | 
			
		||||
| 
						 | 
				
			
			@ -70,14 +82,14 @@
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    &.-solid {
 | 
			
		||||
      & .userName,
 | 
			
		||||
      & .shortName,
 | 
			
		||||
      & .full {
 | 
			
		||||
        background-image: linear-gradient(var(--____highlight-tintColor2), var(--____highlight-tintColor2));
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    &.-side {
 | 
			
		||||
      & .userName,
 | 
			
		||||
      & .shortName,
 | 
			
		||||
      & .userNameFull {
 | 
			
		||||
        box-shadow: 0 -5px 3px -4px inset var(--____highlight-solidColor);
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			@ -88,4 +100,12 @@
 | 
			
		|||
    opacity: 1;
 | 
			
		||||
    pointer-events: initial;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .serverName.-faded {
 | 
			
		||||
    color: var(--faintLink, $fallback--link);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .full .-faded {
 | 
			
		||||
    color: var(--faint, $fallback--faint);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,17 +19,30 @@
 | 
			
		|||
    >
 | 
			
		||||
      <a
 | 
			
		||||
        class="short button-unstyled"
 | 
			
		||||
        :class="{ '-with-tooltip': shouldShowTooltip }"
 | 
			
		||||
        :href="url"
 | 
			
		||||
        @click.prevent="onClick"
 | 
			
		||||
      >
 | 
			
		||||
        <!-- eslint-disable vue/no-v-html -->
 | 
			
		||||
        <FAIcon
 | 
			
		||||
        <UserAvatar
 | 
			
		||||
          v-if="shouldShowAvatar"
 | 
			
		||||
          class="mention-avatar"
 | 
			
		||||
          :user="user"
 | 
			
		||||
        /><span
 | 
			
		||||
          class="shortName"
 | 
			
		||||
        ><FAIcon
 | 
			
		||||
          v-if="useAtIcon"
 | 
			
		||||
          size="sm"
 | 
			
		||||
          icon="at"
 | 
			
		||||
          class="at"
 | 
			
		||||
        /><span class="shortName"><span
 | 
			
		||||
        />{{ !useAtIcon ? '@' : '' }}<span
 | 
			
		||||
          class="userName"
 | 
			
		||||
          v-html="userName"
 | 
			
		||||
        /><span
 | 
			
		||||
          v-if="shouldShowFullUserName"
 | 
			
		||||
          class="serverName"
 | 
			
		||||
          :class="{ '-faded': shouldFadeDomain }"
 | 
			
		||||
          v-html="'@' + serverName"
 | 
			
		||||
        /></span>
 | 
			
		||||
        <span
 | 
			
		||||
          v-if="isYou"
 | 
			
		||||
| 
						 | 
				
			
			@ -38,14 +51,24 @@
 | 
			
		|||
        <!-- eslint-enable vue/no-v-html -->
 | 
			
		||||
      </a>
 | 
			
		||||
      <span
 | 
			
		||||
        v-if="userName !== userNameFull"
 | 
			
		||||
        v-if="shouldShowTooltip"
 | 
			
		||||
        class="full popover-default"
 | 
			
		||||
        :class="[highlightType]"
 | 
			
		||||
      >
 | 
			
		||||
        <span
 | 
			
		||||
          class="userNameFull"
 | 
			
		||||
          v-text="'@' + 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>
 | 
			
		||||
  </span>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,6 +20,11 @@ const GeneralTab = {
 | 
			
		|||
        value: mode,
 | 
			
		||||
        label: this.$t(`settings.subject_line_${mode === 'masto' ? 'mastodon' : mode}`)
 | 
			
		||||
      })),
 | 
			
		||||
      mentionLinkDisplayOptions: ['short', 'full_for_remote', 'full'].map(mode => ({
 | 
			
		||||
        key: mode,
 | 
			
		||||
        value: mode,
 | 
			
		||||
        label: this.$t(`settings.mention_link_display_${mode}`)
 | 
			
		||||
      })),
 | 
			
		||||
      loopSilentAvailable:
 | 
			
		||||
      // Firefox
 | 
			
		||||
      Object.getOwnPropertyDescriptor(HTMLVideoElement.prototype, 'mozHasAudio') ||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -147,6 +147,41 @@
 | 
			
		|||
            {{ $t('settings.greentext') }}
 | 
			
		||||
          </BooleanSetting>
 | 
			
		||||
        </li>
 | 
			
		||||
        <li>
 | 
			
		||||
          <ChoiceSetting
 | 
			
		||||
            id="mentionLinkDisplay"
 | 
			
		||||
            path="mentionLinkDisplay"
 | 
			
		||||
            :options="mentionLinkDisplayOptions"
 | 
			
		||||
          >
 | 
			
		||||
            {{ $t('settings.mention_link_display') }}
 | 
			
		||||
          </ChoiceSetting>
 | 
			
		||||
        </li>
 | 
			
		||||
        <ul
 | 
			
		||||
          class="setting-list suboptions"
 | 
			
		||||
        >
 | 
			
		||||
          <li
 | 
			
		||||
            v-if="mentionLinkDisplay === 'short'"
 | 
			
		||||
          >
 | 
			
		||||
            <BooleanSetting path="mentionLinkShowTooltip">
 | 
			
		||||
              {{ $t('settings.mention_link_show_tooltip') }}
 | 
			
		||||
            </BooleanSetting>
 | 
			
		||||
          </li>
 | 
			
		||||
          <li>
 | 
			
		||||
            <BooleanSetting path="useAtIcon">
 | 
			
		||||
              {{ $t('settings.use_at_icon') }}
 | 
			
		||||
            </BooleanSetting>
 | 
			
		||||
          </li>
 | 
			
		||||
          <li>
 | 
			
		||||
            <BooleanSetting path="mentionLinkShowAvatar">
 | 
			
		||||
              {{ $t('settings.mention_link_show_avatar') }}
 | 
			
		||||
            </BooleanSetting>
 | 
			
		||||
          </li>
 | 
			
		||||
          <li>
 | 
			
		||||
            <BooleanSetting path="mentionLinkFadeDomain">
 | 
			
		||||
              {{ $t('settings.mention_link_fade_domain') }}
 | 
			
		||||
            </BooleanSetting>
 | 
			
		||||
          </li>
 | 
			
		||||
        </ul>
 | 
			
		||||
      </ul>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -485,6 +485,14 @@
 | 
			
		|||
      "true": "yes"
 | 
			
		||||
    },
 | 
			
		||||
    "virtual_scrolling": "Optimize timeline rendering",
 | 
			
		||||
    "use_at_icon": "Display @ symbol as an icon instead of text",
 | 
			
		||||
    "mention_link_display": "Display mention links",
 | 
			
		||||
    "mention_link_display_short": "always as short names (e.g. @foo)",
 | 
			
		||||
    "mention_link_display_full_for_remote": "as full names only for remote users (e.g. @foo@example.org)",
 | 
			
		||||
    "mention_link_display_full": "always as full names (e.g. @foo@example.org)",
 | 
			
		||||
    "mention_link_show_tooltip": "Show full user names as tooltip for remote users",
 | 
			
		||||
    "mention_link_show_avatar": "Show user avatar beside the link",
 | 
			
		||||
    "mention_link_fade_domain": "Fade domains (e.g. @example.org in @foo@example.org)",
 | 
			
		||||
    "fun": "Fun",
 | 
			
		||||
    "greentext": "Meme arrows",
 | 
			
		||||
    "notifications": "Notifications",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,7 +11,8 @@ const browserLocale = (window.navigator.language || 'en').split('-')[0]
 | 
			
		|||
 */
 | 
			
		||||
export const multiChoiceProperties = [
 | 
			
		||||
  'postContentType',
 | 
			
		||||
  'subjectLineBehavior'
 | 
			
		||||
  'subjectLineBehavior',
 | 
			
		||||
  'mentionLinkDisplay' // short | full_for_remote | full
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
export const defaultState = {
 | 
			
		||||
| 
						 | 
				
			
			@ -70,6 +71,11 @@ export const defaultState = {
 | 
			
		|||
  useOneClickNsfw: false,
 | 
			
		||||
  useContainFit: false,
 | 
			
		||||
  greentext: undefined, // instance default
 | 
			
		||||
  useAtIcon: undefined, // instance default
 | 
			
		||||
  mentionLinkDisplay: undefined, // instance default
 | 
			
		||||
  mentionLinkShowTooltip: undefined, // instance default
 | 
			
		||||
  mentionLinkShowAvatar: undefined, // instance default
 | 
			
		||||
  mentionLinkFadeDomain: undefined, // instance default
 | 
			
		||||
  hidePostStats: undefined, // instance default
 | 
			
		||||
  hideUserStats: undefined, // instance default
 | 
			
		||||
  virtualScrolling: undefined, // instance default
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,6 +20,11 @@ const defaultState = {
 | 
			
		|||
  background: '/static/aurora_borealis.jpg',
 | 
			
		||||
  collapseMessageWithSubject: false,
 | 
			
		||||
  greentext: false,
 | 
			
		||||
  useAtIcon: false,
 | 
			
		||||
  mentionLinkDisplay: 'short',
 | 
			
		||||
  mentionLinkShowTooltip: true,
 | 
			
		||||
  mentionLinkShowAvatar: false,
 | 
			
		||||
  mentionLinkFadeDomain: true,
 | 
			
		||||
  hideFilteredStatuses: false,
 | 
			
		||||
  // bad name: actually hides posts of muted USERS
 | 
			
		||||
  hideMutedPosts: false,
 | 
			
		||||
| 
						 | 
				
			
			@ -100,6 +105,9 @@ const instance = {
 | 
			
		|||
      return instanceDefaultProperties
 | 
			
		||||
        .map(key => [key, state[key]])
 | 
			
		||||
        .reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {})
 | 
			
		||||
    },
 | 
			
		||||
    instanceDomain (state) {
 | 
			
		||||
      return new URL(state.server).hostname
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  actions: {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue