diff options
Diffstat (limited to 'src')
16 files changed, 244 insertions, 216 deletions
diff --git a/src/components/chat_list_item/chat_list_item.js b/src/components/chat_list_item/chat_list_item.js index bee1ad53..e01b9bd4 100644 --- a/src/components/chat_list_item/chat_list_item.js +++ b/src/components/chat_list_item/chat_list_item.js @@ -1,5 +1,5 @@ import { mapState } from 'vuex' -import StatusContent from '../status_content/status_content.vue' +import StatusBody from '../status_content/status_content.vue' import fileType from 'src/services/file_type/file_type.service' import UserAvatar from '../user_avatar/user_avatar.vue' import AvatarList from '../avatar_list/avatar_list.vue' @@ -16,7 +16,7 @@ const ChatListItem = { AvatarList, Timeago, ChatTitle, - StatusContent + StatusBody }, computed: { ...mapState({ @@ -38,12 +38,15 @@ const ChatListItem = { }, messageForStatusContent () { const message = this.chat.lastMessage + const messageEmojis = message ? message.emojis : [] const isYou = message && message.account_id === this.currentUser.id - const content = message ? (this.attachmentInfo || message.content) : '' + const content = message ? (this.attachmentInfo || message.content_raw) : '' const messagePreview = isYou ? `<i>${this.$t('chats.you')}</i> ${content}` : content return { summary: '', + emojis: messageEmojis, statusnet_html: messagePreview, + raw_html: messagePreview, text: messagePreview, attachments: [] } diff --git a/src/components/chat_list_item/chat_list_item.scss b/src/components/chat_list_item/chat_list_item.scss index 9e97b28e..57332bed 100644 --- a/src/components/chat_list_item/chat_list_item.scss +++ b/src/components/chat_list_item/chat_list_item.scss @@ -77,18 +77,15 @@ border-radius: var(--avatarAltRadius, $fallback--avatarAltRadius); } - .StatusContent { - img.emoji { - width: 1.4em; - height: 1.4em; - } + .chat-preview-body { + --emoji-size: 1.4em; } .time-wrapper { line-height: 1.4em; } - .single-line { + .chat-preview-body { padding-right: 1em; } } diff --git a/src/components/chat_list_item/chat_list_item.vue b/src/components/chat_list_item/chat_list_item.vue index cd3f436e..c7c0e878 100644 --- a/src/components/chat_list_item/chat_list_item.vue +++ b/src/components/chat_list_item/chat_list_item.vue @@ -29,7 +29,8 @@ </div> </div> <div class="chat-preview"> - <StatusContent + <StatusBody + class="chat-preview-body" :status="messageForStatusContent" :single-line="true" /> diff --git a/src/components/chat_message/chat_message.js b/src/components/chat_message/chat_message.js index bb380f87..d126d453 100644 --- a/src/components/chat_message/chat_message.js +++ b/src/components/chat_message/chat_message.js @@ -57,6 +57,8 @@ const ChatMessage = { messageForStatusContent () { return { summary: '', + emojis: this.message.emojis, + raw_html: this.message.content_raw, statusnet_html: this.message.content, text: this.message.content, attachments: this.message.attachments diff --git a/src/components/chat_message/chat_message.scss b/src/components/chat_message/chat_message.scss index e4351d3b..220355ea 100644 --- a/src/components/chat_message/chat_message.scss +++ b/src/components/chat_message/chat_message.scss @@ -89,8 +89,9 @@ } .without-attachment { - .status-content { - &::after { + .message-content { + // TODO figure out how to do it properly + .text::after { margin-right: 5.4em; content: " "; display: inline-block; @@ -162,6 +163,7 @@ .visible { opacity: 1; } + } .chat-message-date-separator { diff --git a/src/components/chat_message/chat_message.vue b/src/components/chat_message/chat_message.vue index 0f3fc97d..d62b831d 100644 --- a/src/components/chat_message/chat_message.vue +++ b/src/components/chat_message/chat_message.vue @@ -71,6 +71,7 @@ </Popover> </div> <StatusContent + class="message-content" :status="messageForStatusContent" :full-content="true" > diff --git a/src/components/settings_modal/tabs/theme_tab/theme_tab.js b/src/components/settings_modal/tabs/theme_tab/theme_tab.js index 1388f74b..63416e93 100644 --- a/src/components/settings_modal/tabs/theme_tab/theme_tab.js +++ b/src/components/settings_modal/tabs/theme_tab/theme_tab.js @@ -474,7 +474,7 @@ export default { this.loadThemeFromLocalStorage(false, true) break case 'file': - console.err('Forcing snapshout from file is not supported yet') + console.error('Forcing snapshout from file is not supported yet') break } this.dismissWarning() diff --git a/src/components/status/status.vue b/src/components/status/status.vue index cc5fb79f..a4247cd4 100644 --- a/src/components/status/status.vue +++ b/src/components/status/status.vue @@ -89,7 +89,10 @@ v-if="retweeterHtml" :to="retweeterProfileLink" > - <RichContent :html="retweeterHtml" :emoji="retweeterUser.emoji"/> + <RichContent + :html="retweeterHtml" + :emoji="retweeterUser.emoji" + /> </router-link> <router-link v-else @@ -146,7 +149,10 @@ class="status-username" :title="status.user.name" > - <RichContent :html="status.user.name" :emoji="status.user.emoji" /> + <RichContent + :html="status.user.name" + :emoji="status.user.emoji" + /> </h4> <h4 v-else diff --git a/src/components/status_text/status_text.js b/src/components/status_body/status_body.js index e0b11edc..232afccb 100644 --- a/src/components/status_text/status_text.js +++ b/src/components/status_body/status_body.js @@ -94,7 +94,7 @@ const StatusContent = { return html } } catch (e) { - console.err('Failed to process status html', e) + console.error('Failed to process status html', e) return html } } else { @@ -104,13 +104,13 @@ const StatusContent = { attachmentTypes () { return this.status.attachments.map(file => fileType.fileType(file.mimetype)) }, - ...mapGetters(['mergedConfig']), + ...mapGetters(['mergedConfig']) }, components: { RichContent }, mounted () { - this.status.attentions.forEach(attn => { + this.status.attentions && this.status.attentions.forEach(attn => { const { id } = attn this.$store.dispatch('fetchUserIfMissing', id) }) diff --git a/src/components/status_body/status_body.scss b/src/components/status_body/status_body.scss new file mode 100644 index 00000000..6282919c --- /dev/null +++ b/src/components/status_body/status_body.scss @@ -0,0 +1,112 @@ +@import '../../_variables.scss'; + +.StatusBody { + .emoji { + --_still_image-label-scale: 0.5; + } + + .summary { + display: block; + font-style: italic; + padding-bottom: 0.5em; + } + + .text { + &.-single-line { + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + height: 1.4em; + } + } + + .summary-wrapper { + margin-bottom: 0.5em; + border-style: solid; + border-width: 0 0 1px 0; + border-color: var(--border, $fallback--border); + flex-grow: 0; + + &.-tall { + position: relative; + + .summary { + max-height: 2em; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + } + } + } + + .text-wrapper { + display: flex; + flex-direction: column; + flex-wrap: nowrap; + + &.-tall-status { + position: relative; + height: 220px; + overflow-x: hidden; + overflow-y: hidden; + z-index: 1; + + .text { + min-height: 0; + mask: + linear-gradient(to top, white, transparent) bottom/100% 70px no-repeat, + linear-gradient(to top, white, white); + + /* Autoprefixed seem to ignore this one, and also syntax is different */ + -webkit-mask-composite: xor; + mask-composite: exclude; + } + } + } + + & .tall-status-hider, + & .tall-subject-hider, + & .status-unhider, + & .cw-status-hider { + display: inline-block; + word-break: break-all; + width: 100%; + text-align: center; + } + + .tall-status-hider { + position: absolute; + height: 70px; + margin-top: 150px; + line-height: 110px; + z-index: 2; + } + + .tall-subject-hider { + // position: absolute; + padding-bottom: 0.5em; + } + + & .status-unhider, + & .cw-status-hider { + word-break: break-all; + + svg { + color: inherit; + } + } + + .greentext { + color: $fallback--cGreen; + color: var(--postGreentext, $fallback--cGreen); + } + + /* Not sure if this is necessary */ + video { + max-width: 100%; + max-height: 400px; + vertical-align: middle; + object-fit: contain; + } + +} diff --git a/src/components/status_body/status_body.vue b/src/components/status_body/status_body.vue new file mode 100644 index 00000000..6f982f2e --- /dev/null +++ b/src/components/status_body/status_body.vue @@ -0,0 +1,95 @@ +<template> + <div class="StatusBody"> + <div class="body"> + <div + v-if="status.summary_html" + class="summary-wrapper" + :class="{ '-tall': (longSubject && !showingLongSubject) }" + > + <RichContent + class="media-body summary" + :html="status.summary_raw_html" + :emoji="status.emojis" + @click.prevent="linkClicked" + /> + <button + v-if="longSubject && showingLongSubject" + class="button-unstyled -link tall-subject-hider" + @click.prevent="showingLongSubject=false" + > + {{ $t("status.hide_full_subject") }} + </button> + <button + v-else-if="longSubject" + class="button-unstyled -link tall-subject-hider" + @click.prevent="showingLongSubject=true" + > + {{ $t("status.show_full_subject") }} + </button> + </div> + <div + :class="{'-tall-status': hideTallStatus}" + class="text-wrapper" + > + <button + v-if="hideTallStatus" + class="button-unstyled -link tall-status-hider" + :class="{ '-focused': focused }" + @click.prevent="toggleShowMore" + > + {{ $t("general.show_more") }} + </button> + <RichContent + v-if="!hideSubjectStatus && !(singleLine && status.summary_html)" + :class="{ '-single-line': singleLine }" + class="text media-body" + :html="postBodyHtml" + :emoji="status.emojis" + :handle-links="true" + @click.prevent="linkClicked" + /> + <button + v-if="hideSubjectStatus" + class="button-unstyled -link cw-status-hider" + @click.prevent="toggleShowMore" + > + {{ $t("status.show_content") }} + <FAIcon + v-if="attachmentTypes.includes('image')" + icon="image" + /> + <FAIcon + v-if="attachmentTypes.includes('video')" + icon="video" + /> + <FAIcon + v-if="attachmentTypes.includes('audio')" + icon="music" + /> + <FAIcon + v-if="attachmentTypes.includes('unknown')" + icon="file" + /> + <FAIcon + v-if="status.poll && status.poll.options" + icon="poll-h" + /> + <FAIcon + v-if="status.card" + icon="link" + /> + </button> + <button + v-if="showingMore && !fullContent" + class="button-unstyled -link status-unhider" + @click.prevent="toggleShowMore" + > + {{ tallStatus ? $t("general.show_less") : $t("status.hide_content") }} + </button> + </div> + </div> + <slot v-if="!hideSubjectStatus" /> + </div> +</template> +<script src="./status_body.js" ></script> +<style lang="scss" src="./status_body.scss" /> diff --git a/src/components/status_content/status_content.js b/src/components/status_content/status_content.js index 67323b8a..1b80ee09 100644 --- a/src/components/status_content/status_content.js +++ b/src/components/status_content/status_content.js @@ -1,7 +1,7 @@ import Attachment from '../attachment/attachment.vue' import Poll from '../poll/poll.vue' import Gallery from '../gallery/gallery.vue' -import StatusText from 'src/components/status_text/status_text.vue' +import StatusBody from 'src/components/status_body/status_body.vue' import LinkPreview from '../link-preview/link-preview.vue' import fileType from 'src/services/file_type/file_type.service' import { mapGetters, mapState } from 'vuex' @@ -88,7 +88,7 @@ const StatusContent = { Poll, Gallery, LinkPreview, - StatusText + StatusBody }, methods: { setMedia () { diff --git a/src/components/status_content/status_content.vue b/src/components/status_content/status_content.vue index 7389244a..0551f275 100644 --- a/src/components/status_content/status_content.vue +++ b/src/components/status_content/status_content.vue @@ -1,7 +1,7 @@ <template> <div class="StatusContent"> <slot name="header" /> - <StatusText :status="status"> + <StatusBody :status="status" :single-line="singleLine"> <div v-if="status.poll && status.poll.options"> <poll :base-poll="status.poll" /> </div> @@ -40,7 +40,7 @@ :nsfw="nsfwClickthrough" /> </div> - </StatusText> + </StatusBody> <slot name="footer" /> </div> </template> @@ -54,103 +54,5 @@ $status-margin: 0.75em; .StatusContent { flex: 1; min-width: 0; - - .status-content-wrapper { - display: flex; - flex-direction: column; - flex-wrap: nowrap; - } - - .tall-status { - position: relative; - height: 220px; - overflow-x: hidden; - overflow-y: hidden; - z-index: 1; - .status-content { - min-height: 0; - mask: linear-gradient(to top, white, transparent) bottom/100% 70px no-repeat, - linear-gradient(to top, white, white); - /* Autoprefixed seem to ignore this one, and also syntax is different */ - -webkit-mask-composite: xor; - mask-composite: exclude; - } - } - - .tall-status-hider { - display: inline-block; - word-break: break-all; - position: absolute; - height: 70px; - margin-top: 150px; - width: 100%; - text-align: center; - line-height: 110px; - z-index: 2; - } - - .status-unhider, .cw-status-hider { - width: 100%; - text-align: center; - display: inline-block; - word-break: break-all; - - svg { - color: inherit; - } - } - - video { - max-width: 100%; - max-height: 400px; - vertical-align: middle; - object-fit: contain; - } - - .summary-wrapper { - margin-bottom: 0.5em; - border-style: solid; - border-width: 0 0 1px 0; - border-color: var(--border, $fallback--border); - flex-grow: 0; - } - - .summary { - font-style: italic; - padding-bottom: 0.5em; - } - - .tall-subject { - position: relative; - .summary { - max-height: 2em; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - } - } - - .tall-subject-hider { - display: inline-block; - word-break: break-all; - // position: absolute; - width: 100%; - text-align: center; - padding-bottom: 0.5em; - } - - .status-content { - &.single-line { - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; - height: 1.4em; - } - } -} - -.greentext { - color: $fallback--cGreen; - color: var(--postGreentext, $fallback--cGreen); } </style> diff --git a/src/components/status_text/status_text.vue b/src/components/status_text/status_text.vue deleted file mode 100644 index bf723e15..00000000 --- a/src/components/status_text/status_text.vue +++ /dev/null @@ -1,95 +0,0 @@ -<template> - <div class="StatusText"> - <div - v-if="status.summary_html" - class="summary-wrapper" - :class="{ 'tall-subject': (longSubject && !showingLongSubject) }" - > - <RichContent - class="media-body summary" - :html="status.summary_raw_html" - :emoji="status.emojis" - @click.prevent="linkClicked" - /> - <button - v-if="longSubject && showingLongSubject" - class="button-unstyled -link tall-subject-hider" - @click.prevent="showingLongSubject=false" - > - {{ $t("status.hide_full_subject") }} - </button> - <button - v-else-if="longSubject" - class="button-unstyled -link tall-subject-hider" - :class="{ 'tall-subject-hider_focused': focused }" - @click.prevent="showingLongSubject=true" - > - {{ $t("status.show_full_subject") }} - </button> - </div> - <div - :class="{'tall-status': hideTallStatus}" - class="status-content-wrapper" - > - <button - v-if="hideTallStatus" - class="button-unstyled -link tall-status-hider" - :class="{ 'tall-status-hider_focused': focused }" - @click.prevent="toggleShowMore" - > - {{ $t("general.show_more") }} - </button> - <RichContent - v-if="!hideSubjectStatus" - :class="{ 'single-line': singleLine }" - class="status-content media-body" - :html="postBodyHtml" - :emoji="status.emojis" - :handleLinks="true" - @click.prevent="linkClicked" - /> - <button - v-if="hideSubjectStatus" - class="button-unstyled -link cw-status-hider" - @click.prevent="toggleShowMore" - > - {{ $t("status.show_content") }} - <FAIcon - v-if="attachmentTypes.includes('image')" - icon="image" - /> - <FAIcon - v-if="attachmentTypes.includes('video')" - icon="video" - /> - <FAIcon - v-if="attachmentTypes.includes('audio')" - icon="music" - /> - <FAIcon - v-if="attachmentTypes.includes('unknown')" - icon="file" - /> - <FAIcon - v-if="status.poll && status.poll.options" - icon="poll-h" - /> - <FAIcon - v-if="status.card" - icon="link" - /> - </button> - <button - v-if="showingMore && !fullContent" - class="button-unstyled -link status-unhider" - @click.prevent="toggleShowMore" - > - {{ tallStatus ? $t("general.show_less") : $t("status.hide_content") }} - </button> - </div> - <div v-if="!hideSubjectStatus"> - <slot/> - </div> - </div> -</template> -<script src="./status_text.js" ></script> diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js index 8dc22823..13162dcf 100644 --- a/src/services/entity_normalizer/entity_normalizer.service.js +++ b/src/services/entity_normalizer/entity_normalizer.service.js @@ -448,6 +448,8 @@ export const parseChatMessage = (message) => { output.id = message.id output.created_at = new Date(message.created_at) output.chat_id = message.chat_id + output.emojis = message.emojis + output.content_raw = message.content if (message.content) { output.content = addEmojis(message.content, message.emojis) } else { diff --git a/src/services/mini_html_converter/mini_html_converter.service.js b/src/services/mini_html_converter/mini_html_converter.service.js index 01f8adf8..900752cd 100644 --- a/src/services/mini_html_converter/mini_html_converter.service.js +++ b/src/services/mini_html_converter/mini_html_converter.service.js @@ -1,6 +1,6 @@ /** * This is a not-so-tiny purpose-built HTML parser/processor. It was made for use - * with StatusText component for purpose of replacing tags with vue components + * with StatusBody component for purpose of replacing tags with vue components * * known issue: doesn't handle CDATA so nested CDATA might not work well * |
