commit: 58d0f9678b749d1b2ef8aa7d6fb4a91da9cf947d
parent ddee8bb686fb18baf5212089653a8b4e40feedd6
Author: HJ <30-hj@users.noreply.git.pleroma.social>
Date: Sun, 20 Feb 2022 15:11:52 +0000
Merge branch 'fix-mentions-new-bugs' into 'develop'
Fix newfound bugs with rich mentions + user suggestions
See merge request pleroma/pleroma-fe!1430
Diffstat:
20 files changed, 171 insertions(+), 41 deletions(-)
diff --git a/src/components/chat_message/chat_message.scss b/src/components/chat_message/chat_message.scss
@@ -1,6 +1,7 @@
@import '../../_variables.scss';
.chat-message-wrapper {
+
&.hovered-message-chain {
.animated.Avatar {
canvas {
@@ -40,6 +41,12 @@
.chat-message {
display: flex;
padding-bottom: 0.5em;
+
+ .status-body:hover {
+ --_still-image-img-visibility: visible;
+ --_still-image-canvas-visibility: hidden;
+ --_still-image-label-visibility: hidden;
+ }
}
.avatar-wrapper {
diff --git a/src/components/chat_title/chat_title.vue b/src/components/chat_title/chat_title.vue
@@ -1,5 +1,4 @@
<template>
- <!-- eslint-disable vue/no-v-html -->
<div
class="chat-title"
:title="title"
@@ -14,12 +13,13 @@
height="23px"
/>
</router-link>
- <span
+ <RichContent
class="username"
- v-html="htmlTitle"
+ :title="'@'+user.screen_name_ui"
+ :html="htmlTitle"
+ :emoji="user.emoji"
/>
</div>
- <!-- eslint-enable vue/no-v-html -->
</template>
<script src="./chat_title.js"></script>
@@ -34,6 +34,8 @@
white-space: nowrap;
align-items: center;
+ --emoji-size: 14px;
+
.username {
max-width: 100%;
text-overflow: ellipsis;
@@ -41,14 +43,6 @@
display: inline;
word-wrap: break-word;
overflow: hidden;
- text-overflow: ellipsis;
-
- .emoji {
- width: 14px;
- height: 14px;
- vertical-align: middle;
- object-fit: contain
- }
}
.Avatar {
diff --git a/src/components/mention_link/mention_link.js b/src/components/mention_link/mention_link.js
@@ -87,7 +87,7 @@ const MentionLink = {
classnames () {
return [
{
- '-you': this.isYou,
+ '-you': this.isYou && this.shouldBoldenYou,
'-highlighted': this.highlight
},
this.highlightType
@@ -115,6 +115,12 @@ const MentionLink = {
shouldShowAvatar () {
return this.mergedConfig.mentionLinkShowAvatar
},
+ shouldShowYous () {
+ return this.mergedConfig.mentionLinkShowYous
+ },
+ shouldBoldenYou () {
+ return this.mergedConfig.mentionLinkBoldenYou
+ },
shouldFadeDomain () {
return this.mergedConfig.mentionLinkFadeDomain
},
diff --git a/src/components/mention_link/mention_link.scss b/src/components/mention_link/mention_link.scss
@@ -3,12 +3,13 @@
.MentionLink {
position: relative;
white-space: normal;
- display: inline-block;
+ display: inline;
color: var(--link);
+ word-break: normal;
& .new,
& .original {
- display: inline-block;
+ display: inline;
border-radius: 2px;
}
@@ -38,8 +39,8 @@
user-select: all;
}
- .short.-with-tooltip,
- .you {
+ & .short.-with-tooltip,
+ & .you {
user-select: none;
}
@@ -48,6 +49,10 @@
white-space: nowrap;
}
+ .shortName {
+ white-space: normal;
+ }
+
.new {
&.-you {
& .shortName,
diff --git a/src/components/mention_link/mention_link.vue b/src/components/mention_link/mention_link.vue
@@ -9,9 +9,7 @@
class="original"
target="_blank"
v-html="content"
- />
- <!-- eslint-enable vue/no-v-html -->
- <span
+ /><!-- eslint-enable vue/no-v-html --><span
v-if="user"
class="new"
:style="style"
@@ -43,14 +41,12 @@
class="serverName"
:class="{ '-faded': shouldFadeDomain }"
v-html="'@' + serverName"
- /></span>
- <span
- v-if="isYou"
- class="you"
- >{{ $t('status.you') }}</span>
+ /></span><span
+ v-if="isYou && shouldShowYous"
+ :class="{ '-you': shouldBoldenYou }"
+ > {{ $t('status.you') }}</span>
<!-- eslint-enable vue/no-v-html -->
- </a>
- <span
+ </a><span
v-if="shouldShowTooltip"
class="full popover-default"
:class="[highlightType]"
diff --git a/src/components/mentions_line/mentions_line.scss b/src/components/mentions_line/mentions_line.scss
@@ -1,11 +1,13 @@
.MentionsLine {
+ word-break: break-all;
+
+ .mention-link:not(:first-child)::before {
+ content: ' ';
+ }
+
.showMoreLess {
+ margin-left: 0.5em;
white-space: normal;
color: var(--link);
}
-
- .fullExtraMentions,
- .mention-link:not(:last-child) {
- margin-right: 0.25em;
- }
}
diff --git a/src/components/popover/popover.vue b/src/components/popover/popover.vue
@@ -33,7 +33,7 @@
@import '../../_variables.scss';
.popover-trigger-button {
- display: block;
+ display: inline-block;
}
.popover {
diff --git a/src/components/rich_content/rich_content.jsx b/src/components/rich_content/rich_content.jsx
@@ -120,7 +120,8 @@ export default Vue.component('RichContent', {
// don't include spaces when processing mentions - we'll include them
// in MentionsLine
lastSpacing = item
- return currentMentions !== null ? item.trim() : item
+ // Don't remove last space in a container (fixes poast mentions)
+ return (index !== array.length - 1) && (currentMentions !== null) ? item.trim() : item
}
currentMentions = null
diff --git a/src/components/settings_modal/tabs/general_tab.vue b/src/components/settings_modal/tabs/general_tab.vue
@@ -148,6 +148,11 @@
</BooleanSetting>
</li>
<li>
+ <BooleanSetting path="mentionLinkShowYous">
+ {{ $t('settings.show_yous') }}
+ </BooleanSetting>
+ </li>
+ <li>
<ChoiceSetting
id="mentionLinkDisplay"
path="mentionLinkDisplay"
@@ -181,6 +186,11 @@
{{ $t('settings.mention_link_fade_domain') }}
</BooleanSetting>
</li>
+ <li>
+ <BooleanSetting path="mentionLinkBoldenYou">
+ {{ $t('settings.mention_link_bolden_you') }}
+ </BooleanSetting>
+ </li>
</ul>
</ul>
</div>
diff --git a/src/components/status/status.scss b/src/components/status/status.scss
@@ -5,6 +5,8 @@ $status-margin: 0.75em;
.Status {
min-width: 0;
white-space: normal;
+ word-wrap: break-word;
+ word-break: break-word;
&:hover {
--_still-image-img-visibility: visible;
@@ -164,18 +166,24 @@ $status-margin: 0.75em;
position: relative;
align-content: baseline;
font-size: 12px;
- line-height: 160%;
+ margin-top: 0.2em;
+ line-height: 130%;
max-width: 100%;
align-items: stretch;
}
& .reply-to-popover,
- & .reply-to-no-popover {
+ & .reply-to-no-popover,
+ & .mentions {
min-width: 0;
margin-right: 0.4em;
flex-shrink: 0;
}
+ .reply-glued-label {
+ margin-right: 0.5em;
+ }
+
.reply-to-popover {
.reply-to:hover::before {
content: '';
@@ -209,7 +217,6 @@ $status-margin: 0.75em;
& .reply-to {
white-space: nowrap;
position: relative;
- padding-right: 0.25em;
}
& .mentions-text,
diff --git a/src/components/status/status.vue b/src/components/status/status.vue
@@ -227,7 +227,7 @@
>
<span
v-if="isReply"
- class="glued-label"
+ class="glued-label reply-glued-label"
>
<StatusPopover
v-if="!isPreview"
diff --git a/src/components/still-image/still-image.js b/src/components/still-image/still-image.js
@@ -5,7 +5,9 @@ const StillImage = {
'mimetype',
'imageLoadError',
'imageLoadHandler',
- 'alt'
+ 'alt',
+ 'height',
+ 'width'
],
data () {
return {
@@ -15,6 +17,13 @@ const StillImage = {
computed: {
animated () {
return this.stopGifs && (this.mimetype === 'image/gif' || this.src.endsWith('.gif'))
+ },
+ style () {
+ const appendPx = (str) => /\d$/.test(str) ? str + 'px' : str
+ return {
+ height: this.height ? appendPx(this.height) : null,
+ width: this.width ? appendPx(this.width) : null
+ }
}
},
methods: {
diff --git a/src/components/still-image/still-image.vue b/src/components/still-image/still-image.vue
@@ -2,6 +2,7 @@
<div
class="still-image"
:class="{ animated: animated }"
+ :style="style"
>
<canvas
v-if="animated"
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
@@ -275,6 +275,7 @@
class="user-card-bio"
:html="user.description_html"
:emoji="user.emoji"
+ :handle-links="true"
/>
</div>
</div>
diff --git a/src/components/user_list_popover/user_list_popover.vue b/src/components/user_list_popover/user_list_popover.vue
@@ -22,7 +22,12 @@
/>
<div class="user-list-names">
<!-- eslint-disable vue/no-v-html -->
- <span v-html="user.name_html" />
+ <RichContent
+ class="username"
+ :title="'@'+user.screen_name_ui"
+ :html="user.name_html"
+ :emoji="user.emoji"
+ />
<!-- eslint-enable vue/no-v-html -->
<span class="user-list-screen-name">{{ user.screen_name_ui }}</span>
</div>
@@ -48,6 +53,8 @@
.user-list-popover {
padding: 0.5em;
+ --emoji-size: 16px;
+
.user-list-row {
padding: 0.25em;
display: flex;
diff --git a/src/i18n/en.json b/src/i18n/en.json
@@ -493,8 +493,10 @@
"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)",
+ "mention_link_bolden_you": "Highlight mention of you when you are mentioned",
"fun": "Fun",
"greentext": "Meme arrows",
+ "show_yous": "Show (You)s",
"notifications": "Notifications",
"notification_setting_filters": "Filters",
"notification_setting_block_from_strangers": "Block notifications from users who you do not follow",
diff --git a/src/modules/config.js b/src/modules/config.js
@@ -76,6 +76,8 @@ export const defaultState = {
mentionLinkShowTooltip: undefined, // instance default
mentionLinkShowAvatar: undefined, // instance default
mentionLinkFadeDomain: undefined, // instance default
+ mentionLinkShowYous: undefined, // instance default
+ mentionLinkBoldenYou: undefined, // instance default
hidePostStats: undefined, // instance default
hideUserStats: undefined, // instance default
virtualScrolling: undefined, // instance default
diff --git a/src/modules/instance.js b/src/modules/instance.js
@@ -25,6 +25,8 @@ const defaultState = {
mentionLinkShowTooltip: true,
mentionLinkShowAvatar: false,
mentionLinkFadeDomain: true,
+ mentionLinkShowYous: false,
+ mentionLinkBoldenYou: true,
hideFilteredStatuses: false,
// bad name: actually hides posts of muted USERS
hideMutedPosts: false,
diff --git a/src/services/html_converter/html_tree_converter.service.js b/src/services/html_converter/html_tree_converter.service.js
@@ -1,4 +1,5 @@
import { getTagName } from './utility.service.js'
+import { unescape } from 'lodash'
/**
* This is a not-so-tiny purpose-built HTML parser/processor. This parses html
@@ -49,7 +50,7 @@ export const convertHtmlToTree = (html = '') => {
const handleOpen = (tag) => {
const curBuf = getCurrentBuffer()
- const newLevel = [tag, []]
+ const newLevel = [unescape(tag), []]
levels.push(newLevel)
curBuf.push(newLevel)
}
diff --git a/test/unit/specs/components/rich_content.spec.js b/test/unit/specs/components/rich_content.spec.js
@@ -350,12 +350,89 @@ describe('RichContent', () => {
'<span>',
'</span>',
'</a>',
+ '<!---->', // v-if placeholder, mentionlink's "new" (i.e. rich) display
+ '</span>',
+ '<!---->', // v-if placeholder, mentionsline's extra mentions and stuff
+ '</span>'
+ ),
+ p(
+ 'Testing'
+ )
+ ].join('')
+
+ const wrapper = mount(RichContent, {
+ localVue,
+ propsData: {
+ attentions,
+ handleLinks: true,
+ greentext: true,
+ emoji: [],
+ html
+ }
+ })
+
+ expect(wrapper.html()).to.eql(compwrap(expected))
+ })
+
+ it('rich contents of nested mentions are handled properly', () => {
+ attentions.push({ statusnet_profile_url: 'lol' })
+ const html = [
+ p(
+ '<span class="poast-style">',
+ '<a href="lol" class="mention">',
+ '<span>',
+ 'https://</span>',
+ '<span>',
+ 'lol.tld/</span>',
+ '<span>',
+ '</span>',
+ '</a>',
' ',
+ '<a href="lol" class="mention">',
+ '<span>',
+ 'https://</span>',
+ '<span>',
+ 'lol.tld/</span>',
+ '<span>',
+ '</span>',
+ '</a>',
+ '</span>'
+ ),
+ p(
+ 'Testing'
+ )
+ ].join('')
+ const expected = [
+ p(
+ '<span class="poast-style">',
+ '<span class="MentionsLine">',
+ '<span class="MentionLink mention-link">',
+ '<a href="lol" target="_blank" class="original">',
+ '<span>',
+ 'https://</span>',
+ '<span>',
+ 'lol.tld/</span>',
+ '<span>',
+ '</span>',
+ '</a>',
+ '<!---->', // v-if placeholder, mentionlink's "new" (i.e. rich) display
+ '</span>',
+ '<span class="MentionLink mention-link">',
+ '<a href="lol" target="_blank" class="original">',
+ '<span>',
+ 'https://</span>',
+ '<span>',
+ 'lol.tld/</span>',
+ '<span>',
+ '</span>',
+ '</a>',
'<!---->', // v-if placeholder, mentionlink's "new" (i.e. rich) display
'</span>',
'<!---->', // v-if placeholder, mentionsline's extra mentions and stuff
+ '</span>',
'</span>'
),
+ ' ',
p(
'Testing'
)