Compare commits
1 Commits
develop
...
tusooa/mul
Author | SHA1 | Date |
---|---|---|
tusooa | b2cd38f603 |
|
@ -320,7 +320,8 @@ const conversation = {
|
|||
expandingSubject: false,
|
||||
showingLongSubject: false,
|
||||
isReplying: false,
|
||||
mediaPlaying: []
|
||||
mediaPlaying: [],
|
||||
currentLanguage: undefined
|
||||
}
|
||||
|
||||
if (this.statusContentPropertiesObject[id]) {
|
||||
|
|
|
@ -94,11 +94,13 @@
|
|||
:controlled-showing-long-subject="statusContentProperties[status.id].showingLongSubject"
|
||||
:controlled-replying="statusContentProperties[status.id].replying"
|
||||
:controlled-media-playing="statusContentProperties[status.id].mediaPlaying"
|
||||
:controlled-current-language="statusContentProperties[status.id].currentLanguage"
|
||||
:controlled-toggle-showing-tall="() => toggleStatusContentProperty(status.id, 'showingTall')"
|
||||
:controlled-toggle-expanding-subject="() => toggleStatusContentProperty(status.id, 'expandingSubject')"
|
||||
:controlled-toggle-showing-long-subject="() => toggleStatusContentProperty(status.id, 'showingLongSubject')"
|
||||
:controlled-toggle-replying="() => toggleStatusContentProperty(status.id, 'replying')"
|
||||
:controlled-set-media-playing="(newVal) => toggleStatusContentProperty(status.id, 'mediaPlaying', newVal)"
|
||||
:controlled-set-current-language="(newVal) => setStatusContentProperty(status.id, 'currentLanguage', newVal)"
|
||||
|
||||
@goto="setHighlight"
|
||||
@toggleExpanded="toggleExpanded"
|
||||
|
|
|
@ -19,6 +19,7 @@ import MentionLink from 'src/components/mention_link/mention_link.vue'
|
|||
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
|
||||
import { highlightClass, highlightStyle } from '../../services/user_highlighter/user_highlighter.js'
|
||||
import { muteWordHits } from '../../services/status_parser/status_parser.js'
|
||||
import { controlledOrUncontrolledGetters, controlledOrUncontrolledSet, controlledOrUncontrolledToggle } from 'src/services/control/control.service.js'
|
||||
import { unescape, uniqBy } from 'lodash'
|
||||
|
||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||
|
@ -62,41 +63,6 @@ library.add(
|
|||
faAngleDoubleRight
|
||||
)
|
||||
|
||||
const camelCase = name => name.charAt(0).toUpperCase() + name.slice(1)
|
||||
|
||||
const controlledOrUncontrolledGetters = list => list.reduce((res, name) => {
|
||||
const camelized = camelCase(name)
|
||||
const toggle = `controlledToggle${camelized}`
|
||||
const controlledName = `controlled${camelized}`
|
||||
const uncontrolledName = `uncontrolled${camelized}`
|
||||
res[name] = function () {
|
||||
return ((this.$data[toggle] !== undefined || this.$props[toggle] !== undefined) && this[toggle]) ? this[controlledName] : this[uncontrolledName]
|
||||
}
|
||||
return res
|
||||
}, {})
|
||||
|
||||
const controlledOrUncontrolledToggle = (obj, name) => {
|
||||
const camelized = camelCase(name)
|
||||
const toggle = `controlledToggle${camelized}`
|
||||
const uncontrolledName = `uncontrolled${camelized}`
|
||||
if (obj[toggle]) {
|
||||
obj[toggle]()
|
||||
} else {
|
||||
obj[uncontrolledName] = !obj[uncontrolledName]
|
||||
}
|
||||
}
|
||||
|
||||
const controlledOrUncontrolledSet = (obj, name, val) => {
|
||||
const camelized = camelCase(name)
|
||||
const set = `controlledSet${camelized}`
|
||||
const uncontrolledName = `uncontrolled${camelized}`
|
||||
if (obj[set]) {
|
||||
obj[set](val)
|
||||
} else {
|
||||
obj[uncontrolledName] = val
|
||||
}
|
||||
}
|
||||
|
||||
const Status = {
|
||||
name: 'Status',
|
||||
components: {
|
||||
|
@ -149,6 +115,8 @@ const Status = {
|
|||
'controlledToggleReplying',
|
||||
'controlledMediaPlaying',
|
||||
'controlledSetMediaPlaying',
|
||||
'controlledCurrentLanguage',
|
||||
'controlledSetCurrentLanguage',
|
||||
'dive'
|
||||
],
|
||||
data () {
|
||||
|
@ -157,13 +125,14 @@ const Status = {
|
|||
unmuted: false,
|
||||
userExpanded: false,
|
||||
uncontrolledMediaPlaying: [],
|
||||
uncontrolledCurrentLanguage: undefined,
|
||||
suspendable: true,
|
||||
error: null,
|
||||
headTailLinks: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...controlledOrUncontrolledGetters(['replying', 'mediaPlaying']),
|
||||
...controlledOrUncontrolledGetters(['replying', 'mediaPlaying', 'currentLanguage']),
|
||||
muteWords () {
|
||||
return this.mergedConfig.muteWords
|
||||
},
|
||||
|
@ -448,6 +417,9 @@ const Status = {
|
|||
removeMediaPlaying (id) {
|
||||
controlledOrUncontrolledSet(this, 'mediaPlaying', this.mediaPlaying.filter(mediaId => mediaId !== id))
|
||||
},
|
||||
setCurrentLanguage (language) {
|
||||
controlledOrUncontrolledSet(this, 'currentLanguage', language)
|
||||
},
|
||||
setHeadTailLinks (headTailLinks) {
|
||||
this.headTailLinks = headTailLinks
|
||||
},
|
||||
|
|
|
@ -356,9 +356,11 @@
|
|||
:controlled-showing-tall="controlledShowingTall"
|
||||
:controlled-expanding-subject="controlledExpandingSubject"
|
||||
:controlled-showing-long-subject="controlledShowingLongSubject"
|
||||
:controlled-current-language="controlledCurrentLanguage"
|
||||
:controlled-toggle-showing-tall="controlledToggleShowingTall"
|
||||
:controlled-toggle-expanding-subject="controlledToggleExpandingSubject"
|
||||
:controlled-toggle-showing-long-subject="controlledToggleShowingLongSubject"
|
||||
:controlled-set-current-language="controlledSetCurrentLanguage"
|
||||
@mediaplay="addMediaPlaying($event)"
|
||||
@mediapause="removeMediaPlaying($event)"
|
||||
@parseReady="setHeadTailLinks"
|
||||
|
|
|
@ -32,7 +32,9 @@ const StatusContent = {
|
|||
'showingLongSubject',
|
||||
'toggleShowingTall',
|
||||
'toggleExpandingSubject',
|
||||
'toggleShowingLongSubject'
|
||||
'toggleShowingLongSubject',
|
||||
'currentLanguage',
|
||||
'setCurrentLanguage'
|
||||
],
|
||||
data () {
|
||||
return {
|
||||
|
@ -78,6 +80,18 @@ const StatusContent = {
|
|||
attachmentTypes () {
|
||||
return this.status.attachments.map(file => fileType.fileType(file.mimetype))
|
||||
},
|
||||
languages () {
|
||||
return this.status.languages
|
||||
},
|
||||
currentLanguageOrDefault () {
|
||||
return this.currentLanguage || this.languages[0]
|
||||
},
|
||||
summary () {
|
||||
return this.currentLanguageOrDefault ? this.status.summary_raw_html_map[this.currentLanguageOrDefault] : this.status.summary_raw_html
|
||||
},
|
||||
content () {
|
||||
return this.currentLanguageOrDefault ? this.status.raw_html_map[this.currentLanguageOrDefault] : this.status.raw_html
|
||||
},
|
||||
...mapGetters(['mergedConfig'])
|
||||
},
|
||||
components: {
|
||||
|
|
|
@ -4,6 +4,12 @@
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.language-selector {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.emoji {
|
||||
--_still_image-label-scale: 0.5;
|
||||
}
|
||||
|
|
|
@ -5,13 +5,27 @@
|
|||
>
|
||||
<div class="body">
|
||||
<div
|
||||
v-if="status.summary_raw_html"
|
||||
v-if="languages"
|
||||
class="language-selector"
|
||||
>
|
||||
<button
|
||||
v-for="language in languages"
|
||||
:key="language"
|
||||
class="language-selector-item tab button-default"
|
||||
:class="{ active: language === currentLanguageOrDefault }"
|
||||
@click="setCurrentLanguage(language)"
|
||||
>
|
||||
{{ language }}
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
v-if="summary"
|
||||
class="summary-wrapper"
|
||||
:class="{ '-tall': (longSubject && !showingLongSubject) }"
|
||||
>
|
||||
<RichContent
|
||||
class="media-body summary"
|
||||
:html="status.summary_raw_html"
|
||||
:html="summary"
|
||||
:emoji="status.emojis"
|
||||
/>
|
||||
<button
|
||||
|
@ -42,10 +56,10 @@
|
|||
{{ $t("general.show_more") }}
|
||||
</button>
|
||||
<RichContent
|
||||
v-if="!hideSubjectStatus && !(singleLine && status.summary_raw_html)"
|
||||
v-if="!hideSubjectStatus && !(singleLine && summary)"
|
||||
:class="{ '-single-line': singleLine }"
|
||||
class="text media-body"
|
||||
:html="status.raw_html"
|
||||
:html="content"
|
||||
:emoji="status.emojis"
|
||||
:handle-links="true"
|
||||
:greentext="mergedConfig.greentext"
|
||||
|
|
|
@ -4,6 +4,7 @@ import Gallery from '../gallery/gallery.vue'
|
|||
import StatusBody from 'src/components/status_body/status_body.vue'
|
||||
import LinkPreview from '../link-preview/link-preview.vue'
|
||||
import { mapGetters, mapState } from 'vuex'
|
||||
import { controlledOrUncontrolledGetters, controlledOrUncontrolledSet, controlledOrUncontrolledToggle } from 'src/services/control/control.service.js'
|
||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||
import {
|
||||
faCircleNotch,
|
||||
|
@ -23,30 +24,6 @@ library.add(
|
|||
faPollH
|
||||
)
|
||||
|
||||
const camelCase = name => name.charAt(0).toUpperCase() + name.slice(1)
|
||||
|
||||
const controlledOrUncontrolledGetters = list => list.reduce((res, name) => {
|
||||
const camelized = camelCase(name)
|
||||
const toggle = `controlledToggle${camelized}`
|
||||
const controlledName = `controlled${camelized}`
|
||||
const uncontrolledName = `uncontrolled${camelized}`
|
||||
res[name] = function () {
|
||||
return ((this.$data[toggle] !== undefined || this.$props[toggle] !== undefined) && this[toggle]) ? this[controlledName] : this[uncontrolledName]
|
||||
}
|
||||
return res
|
||||
}, {})
|
||||
|
||||
const controlledOrUncontrolledToggle = (obj, name) => {
|
||||
const camelized = camelCase(name)
|
||||
const toggle = `controlledToggle${camelized}`
|
||||
const uncontrolledName = `uncontrolled${camelized}`
|
||||
if (obj[toggle]) {
|
||||
obj[toggle]()
|
||||
} else {
|
||||
obj[uncontrolledName] = !obj[uncontrolledName]
|
||||
}
|
||||
}
|
||||
|
||||
const StatusContent = {
|
||||
name: 'StatusContent',
|
||||
props: [
|
||||
|
@ -61,18 +38,21 @@ const StatusContent = {
|
|||
'controlledToggleShowingTall',
|
||||
'controlledToggleExpandingSubject',
|
||||
'controlledShowingLongSubject',
|
||||
'controlledToggleShowingLongSubject'
|
||||
'controlledToggleShowingLongSubject',
|
||||
'controlledCurrentLanguage',
|
||||
'controlledSetCurrentLanguage'
|
||||
],
|
||||
data () {
|
||||
return {
|
||||
uncontrolledShowingTall: this.fullContent || (this.inConversation && this.focused),
|
||||
uncontrolledShowingLongSubject: false,
|
||||
// not as computed because it sets the initial state which will be changed later
|
||||
uncontrolledExpandingSubject: !this.$store.getters.mergedConfig.collapseMessageWithSubject
|
||||
uncontrolledExpandingSubject: !this.$store.getters.mergedConfig.collapseMessageWithSubject,
|
||||
uncontrolledCurrentLanguage: undefined
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...controlledOrUncontrolledGetters(['showingTall', 'expandingSubject', 'showingLongSubject']),
|
||||
...controlledOrUncontrolledGetters(['showingTall', 'expandingSubject', 'showingLongSubject', 'currentLanguage']),
|
||||
hideAttachments () {
|
||||
return (this.mergedConfig.hideAttachments && !this.inConversation) ||
|
||||
(this.mergedConfig.hideAttachmentsInConv && this.inConversation)
|
||||
|
@ -121,6 +101,9 @@ const StatusContent = {
|
|||
toggleShowingLongSubject () {
|
||||
controlledOrUncontrolledToggle(this, 'showingLongSubject')
|
||||
},
|
||||
setCurrentLanguage (language) {
|
||||
controlledOrUncontrolledSet(this, 'currentLanguage', language)
|
||||
},
|
||||
setMedia () {
|
||||
const attachments = this.attachmentSize === 'hide' ? this.status.attachments : this.galleryAttachments
|
||||
return () => this.$store.dispatch('setMedia', attachments)
|
||||
|
|
|
@ -11,9 +11,11 @@
|
|||
:showing-tall="showingTall"
|
||||
:expanding-subject="expandingSubject"
|
||||
:showing-long-subject="showingLongSubject"
|
||||
:current-language="currentLanguage"
|
||||
:toggle-showing-tall="toggleShowingTall"
|
||||
:toggle-expanding-subject="toggleExpandingSubject"
|
||||
:toggle-showing-long-subject="toggleShowingLongSubject"
|
||||
:set-current-language="setCurrentLanguage"
|
||||
@parseReady="$emit('parseReady', $event)"
|
||||
>
|
||||
<div v-if="status.poll && status.poll.options && !compact">
|
||||
|
|
|
@ -82,7 +82,7 @@ const ThreadTree = {
|
|||
this.toggleStatusContentProperty(this.status.id, name)
|
||||
},
|
||||
setCurrentProp (name, newVal) {
|
||||
this.setStatusContentProperty(this.status.id, name)
|
||||
this.setStatusContentProperty(this.status.id, name, newVal)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,11 +24,13 @@
|
|||
:controlled-showing-long-subject="currentProp.showingLongSubject"
|
||||
:controlled-replying="currentProp.replying"
|
||||
:controlled-media-playing="currentProp.mediaPlaying"
|
||||
:controlled-current-language="currentProp.currentLanguage"
|
||||
:controlled-toggle-showing-tall="() => toggleCurrentProp('showingTall')"
|
||||
:controlled-toggle-expanding-subject="() => toggleCurrentProp('expandingSubject')"
|
||||
:controlled-toggle-showing-long-subject="() => toggleCurrentProp('showingLongSubject')"
|
||||
:controlled-toggle-replying="() => toggleCurrentProp('replying')"
|
||||
:controlled-set-media-playing="(newVal) => setCurrentProp('mediaPlaying', newVal)"
|
||||
:controlled-set-current-language="(newVal) => setCurrentProp('currentLanguage', newVal)"
|
||||
:dive="dive ? () => dive(status.id) : undefined"
|
||||
|
||||
@goto="setHighlight"
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
const camelCase = name => name.charAt(0).toUpperCase() + name.slice(1)
|
||||
|
||||
export const controlledOrUncontrolledGetters = list => list.reduce((res, name) => {
|
||||
const camelized = camelCase(name)
|
||||
const toggle = `controlledToggle${camelized}`
|
||||
const set = `controlledSet${camelized}`
|
||||
const controlledName = `controlled${camelized}`
|
||||
const uncontrolledName = `uncontrolled${camelized}`
|
||||
res[name] = function () {
|
||||
return (((this.$data[toggle] !== undefined || this.$props[toggle] !== undefined) && this[toggle]) ||
|
||||
((this.$data[set] !== undefined || this.$props[set] !== undefined) && this[set])
|
||||
)
|
||||
? this[controlledName]
|
||||
: this[uncontrolledName]
|
||||
}
|
||||
return res
|
||||
}, {})
|
||||
|
||||
export const controlledOrUncontrolledToggle = (obj, name) => {
|
||||
const camelized = camelCase(name)
|
||||
const toggle = `controlledToggle${camelized}`
|
||||
const uncontrolledName = `uncontrolled${camelized}`
|
||||
if (obj[toggle]) {
|
||||
obj[toggle]()
|
||||
} else {
|
||||
obj[uncontrolledName] = !obj[uncontrolledName]
|
||||
}
|
||||
}
|
||||
|
||||
export const controlledOrUncontrolledSet = (obj, name, val) => {
|
||||
const camelized = camelCase(name)
|
||||
const set = `controlledSet${camelized}`
|
||||
const uncontrolledName = `uncontrolled${camelized}`
|
||||
if (obj[set]) {
|
||||
obj[set](val)
|
||||
} else {
|
||||
obj[uncontrolledName] = val
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ import escape from 'escape-html'
|
|||
import parseLinkHeader from 'parse-link-header'
|
||||
import { isStatusNotification } from '../notification_utils/notification_utils.js'
|
||||
import punycode from 'punycode.js'
|
||||
import { uniq } from 'lodash'
|
||||
|
||||
/** NOTICE! **
|
||||
* Do not initialize UI-generated data here.
|
||||
|
@ -309,6 +310,7 @@ export const parseStatus = (data) => {
|
|||
output.nsfw = data.sensitive
|
||||
|
||||
output.raw_html = data.content
|
||||
output.raw_html_map = data.content_map || {}
|
||||
output.emojis = data.emojis
|
||||
|
||||
output.tags = data.tags
|
||||
|
@ -339,6 +341,11 @@ export const parseStatus = (data) => {
|
|||
}
|
||||
|
||||
output.summary_raw_html = escape(data.spoiler_text)
|
||||
output.summary_raw_html_map = Object.entries(data.spoiler_text_map || {})
|
||||
.reduce((acc, [lang, txt]) => {
|
||||
acc[lang] = escape(txt)
|
||||
return acc
|
||||
}, {})
|
||||
output.external_url = data.url
|
||||
output.poll = data.poll
|
||||
if (output.poll) {
|
||||
|
@ -349,6 +356,7 @@ export const parseStatus = (data) => {
|
|||
}
|
||||
output.pinned = data.pinned
|
||||
output.muted = data.muted
|
||||
output.languages = uniq(Object.keys(output.raw_html_map).concat(Object.keys(output.summary_raw_html_map)))
|
||||
} else {
|
||||
output.favorited = data.favorited
|
||||
output.fave_num = data.fave_num
|
||||
|
|
Loading…
Reference in New Issue