Merge remote-tracking branch 'origin/develop' into shigusegubu-vue3

This commit is contained in:
Henry Jameson 2023-09-04 19:34:36 +03:00
commit 232c5528b5
16 changed files with 90 additions and 57 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -28,6 +28,7 @@
active: activeGroupView === group.id
}"
:title="group.text"
role="button"
@click.prevent="highlight(group.id)"
>
<span
@ -116,6 +117,7 @@
:key="group.id + emoji.displayText"
:title="maybeLocalizedEmojiName(emoji)"
class="emoji-item"
role="button"
@click.stop.prevent="onEmoji(emoji)"
>
<span
@ -126,6 +128,7 @@
v-else
class="emoji-picker-emoji -custom"
loading="lazy"
:alt="maybeLocalizedEmojiName(emoji)"
:src="emoji.imageUrl"
:data-emoji-name="group.id + emoji.displayText"
/>

View file

@ -129,44 +129,32 @@
<div
v-if="quotable"
role="radiogroup"
class="reply-or-quote-selector"
class="btn-group reply-or-quote-selector"
>
<div
class="reply-or-quote-option"
<button
:id="`reply-or-quote-option-${randomSeed}-reply`"
class="btn button-default reply-or-quote-option"
:class="{ toggled: !newStatus.quoting }"
tabindex="0"
role="radio"
:aria-labelledby="`reply-or-quote-option-${randomSeed}-reply`"
:aria-checked="!newStatus.quoting"
@click="newStatus.quoting = false"
>
<input
type="radio"
:checked="!newStatus.quoting"
>
<label class="reply-or-quote-option-text">
<span :id="`reply-or-quote-option-${randomSeed}-reply`">
{{ $t('post_status.reply_option') }}
</span>
</label>
</div>
<div
class="reply-or-quote-option"
{{ $t('post_status.reply_option') }}
</button>
<button
:id="`reply-or-quote-option-${randomSeed}-quote`"
class="btn button-default reply-or-quote-option"
:class="{ toggled: newStatus.quoting }"
tabindex="0"
role="radio"
:aria-labelledby="`reply-or-quote-option-${randomSeed}-quote`"
:aria-checked="newStatus.quoting"
@click="newStatus.quoting = true"
>
<input
type="radio"
:checked="newStatus.quoting"
>
<label class="reply-or-quote-option-text">
<span :id="`reply-or-quote-option-${randomSeed}-quote`">
{{ $t('post_status.quote_option') }}
</span>
</label>
</div>
{{ $t('post_status.quote_option') }}
</button>
</div>
<EmojiInput
v-if="!disableSubject && (newStatus.spoilerText || alwaysShowSubject)"
@ -463,17 +451,7 @@
}
.reply-or-quote-selector {
display: flex;
flex-direction: column;
.reply-or-quote-option {
display: flex;
align-items: center;
.reply-or-quote-option-text::before {
vertical-align: middle;
}
}
margin-bottom: 0.5em;
}
.text-format {

View file

@ -44,6 +44,10 @@ const PostStatusModal = {
methods: {
closeModal () {
this.$store.dispatch('closePostStatusModal')
},
resetAndClose () {
this.$store.dispatch('resetPostStatusModal')
this.$store.dispatch('closePostStatusModal')
}
}
}

View file

@ -12,7 +12,7 @@
<PostStatusForm
class="panel-body"
v-bind="params"
@posted="closeModal"
@posted="resetAndClose"
/>
</div>
</Modal>

View file

@ -8,6 +8,27 @@ import HashtagLink from 'src/components/hashtag_link/hashtag_link.vue'
import './rich_content.scss'
const MAYBE_LINE_BREAKING_ELEMENTS = [
'blockquote',
'br',
'hr',
'ul',
'ol',
'li',
'p',
'table',
'tbody',
'td',
'th',
'thead',
'tr',
'h1',
'h2',
'h3',
'h4',
'h5'
]
/**
* RichContent, The Über-powered component for rendering Post HTML.
*
@ -166,25 +187,22 @@ export default {
!(children && typeof children[0] === 'string' && children[0].match(/^\s/))
? lastSpacing
: ''
switch (Tag) {
case 'br':
if (MAYBE_LINE_BREAKING_ELEMENTS.includes(Tag)) {
// all the elements that can cause a line change
currentMentions = null
} else if (Tag === 'img') { // replace images with StillImage
return ['', [mentionsLinePadding, renderImage(opener)], '']
} else if (Tag === 'a' && this.handleLinks) { // replace mentions with MentionLink
if (fullAttrs.class && fullAttrs.class.includes('mention')) {
// Handling mentions here
return renderMention(attrs, children)
} else {
currentMentions = null
break
case 'img': // replace images with StillImage
return ['', [mentionsLinePadding, renderImage(opener)], '']
case 'a': // replace mentions with MentionLink
if (!this.handleLinks) break
if (fullAttrs.class && fullAttrs.class.includes('mention')) {
// Handling mentions here
return renderMention(attrs, children)
} else {
currentMentions = null
break
}
case 'span':
if (this.handleLinks && fullAttrs.class && fullAttrs.class.includes('h-card')) {
return ['', children.map(processItem), '']
}
}
} else if (Tag === 'span') {
if (this.handleLinks && fullAttrs.class && fullAttrs.class.includes('h-card')) {
return ['', children.map(processItem), '']
}
}
if (children !== undefined) {

View file

@ -160,6 +160,9 @@ const Timeline = {
if (this.timeline.flushMarker !== 0) {
this.$store.commit('clearTimeline', { timeline: this.timelineName, excludeUserId: true })
this.$store.commit('queueFlush', { timeline: this.timelineName, id: 0 })
if (this.timelineName === 'user') {
this.$store.dispatch('fetchPinnedStatuses', this.userId)
}
this.fetchOlderStatuses()
} else {
this.blockClicksTemporarily()

View file

@ -10,6 +10,9 @@ const postStatus = {
},
closePostStatusModal (state) {
state.modalActivated = false
},
resetPostStatusModal (state) {
state.params = null
}
},
actions: {
@ -18,6 +21,9 @@ const postStatus = {
},
closePostStatusModal ({ commit }) {
commit('closePostStatusModal')
},
resetPostStatusModal ({ commit }) {
commit('resetPostStatusModal')
}
}
}

View file

@ -651,6 +651,12 @@ const users = {
const response = data.error
// Authentication failed
commit('endLogin')
// remove authentication token on client/authentication errors
if ([400, 401, 403, 422].includes(response.status)) {
commit('clearToken')
}
if (response.status === 401) {
reject(new Error('Wrong username or password'))
} else {

View file

@ -14,8 +14,11 @@ export const mentionMatchesUrl = (attention, url) => {
* @param {string} url
*/
export const extractTagFromUrl = (url) => {
const regex = /tag[s]*\/(\w+)$/g
const result = regex.exec(url)
const decoded = decodeURI(url)
// https://git.pleroma.social/pleroma/elixir-libraries/linkify/-/blob/master/lib/linkify/parser.ex
// https://www.pcre.org/original/doc/html/pcrepattern.html
const regex = /tag[s]*\/([\p{L}\p{N}_]*[\p{Alphabetic}_·\u{200c}][\p{L}\p{N}_·\p{M}\u{200c}]*)$/ug
const result = regex.exec(decoded)
if (!result) {
return false
}

View file

@ -78,5 +78,11 @@ describe('MatcherService', () => {
expect(MatcherService.extractTagFromUrl(url)).to.eql(false)
})
it('should return tag name from non-ascii tags', () => {
const url = encodeURI('https://website.com/tag/喵喵喵')
expect(MatcherService.extractTagFromUrl(url)).to.eql('喵喵喵')
})
})
})