Render preview toggle in Vue
This commit is contained in:
parent
ebfc6fa724
commit
2bb8287519
@ -126,14 +126,6 @@ export default {
|
|||||||
mounted() {
|
mounted() {
|
||||||
const options = require("../js/options");
|
const options = require("../js/options");
|
||||||
this.$set(this.link, "canDisplay", this.link.type !== "loading" && options.shouldOpenMessagePreview(this.link.type));
|
this.$set(this.link, "canDisplay", this.link.type !== "loading" && options.shouldOpenMessagePreview(this.link.type));
|
||||||
|
|
||||||
this.$nextTick(() => {
|
|
||||||
const escapedLink = this.link.link.replace(/["\\]/g, "\\$&");
|
|
||||||
|
|
||||||
this.$parent.$refs.text
|
|
||||||
.querySelector(`.toggle-preview[data-url="${escapedLink}"]`)
|
|
||||||
.removeAttribute("hidden");
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
onPreviewReady() {
|
onPreviewReady() {
|
||||||
|
22
client/components/LinkPreviewToggle.vue
Normal file
22
client/components/LinkPreviewToggle.vue
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<template>
|
||||||
|
<button
|
||||||
|
v-if="link.canDisplay"
|
||||||
|
@click="onClick"
|
||||||
|
:class="['toggle-button', 'toggle-preview', { opened: link.shown }]"/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "LinkPreviewToggle",
|
||||||
|
props: {
|
||||||
|
link: Object,
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onClick: function() {
|
||||||
|
this.link.shown = !this.link.shown;
|
||||||
|
|
||||||
|
this.$parent.$emit("linkPreviewToggle");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
@ -2,8 +2,8 @@
|
|||||||
<span class="content">
|
<span class="content">
|
||||||
<Username :user="message.from"/>
|
<Username :user="message.from"/>
|
||||||
<span
|
<span
|
||||||
class="text"
|
ref="text"
|
||||||
v-html="$options.filters.parse(message.text, message.users)"/>
|
class="text"><ParsedMessage :message="message"/></span>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ export default {
|
|||||||
message: Object,
|
message: Object,
|
||||||
},
|
},
|
||||||
render(createElement, context) {
|
render(createElement, context) {
|
||||||
return parse(context.props.message.text, context.props.message.users, createElement);
|
return parse(context.props.message.text, context.props.message, createElement);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -9,6 +9,7 @@ const findNames = require("./ircmessageparser/findNames");
|
|||||||
const merge = require("./ircmessageparser/merge");
|
const merge = require("./ircmessageparser/merge");
|
||||||
const colorClass = require("./colorClass");
|
const colorClass = require("./colorClass");
|
||||||
const emojiMap = require("../fullnamemap.json");
|
const emojiMap = require("../fullnamemap.json");
|
||||||
|
const LinkPreviewToggle = require("../../../components/LinkPreviewToggle.vue").default;
|
||||||
|
|
||||||
// Create an HTML `span` with styling information for a given fragment
|
// Create an HTML `span` with styling information for a given fragment
|
||||||
function createFragment(fragment) {
|
function createFragment(fragment) {
|
||||||
@ -108,7 +109,7 @@ function createVueFragment(fragment, createElement) {
|
|||||||
|
|
||||||
// Transform an IRC message potentially filled with styling control codes, URLs,
|
// Transform an IRC message potentially filled with styling control codes, URLs,
|
||||||
// nicknames, and channels into a string of HTML elements to display on the client.
|
// nicknames, and channels into a string of HTML elements to display on the client.
|
||||||
module.exports = function parse(text, users = [], createElement = null) {
|
module.exports = function parse(text, message = null, createElement = null) {
|
||||||
// Extract the styling information and get the plain text version from it
|
// Extract the styling information and get the plain text version from it
|
||||||
const styleFragments = parseStyle(text);
|
const styleFragments = parseStyle(text);
|
||||||
const cleanText = styleFragments.map((fragment) => fragment.text).join("");
|
const cleanText = styleFragments.map((fragment) => fragment.text).join("");
|
||||||
@ -121,7 +122,7 @@ module.exports = function parse(text, users = [], createElement = null) {
|
|||||||
const channelParts = findChannels(cleanText, channelPrefixes, userModes);
|
const channelParts = findChannels(cleanText, channelPrefixes, userModes);
|
||||||
const linkParts = findLinks(cleanText);
|
const linkParts = findLinks(cleanText);
|
||||||
const emojiParts = findEmoji(cleanText);
|
const emojiParts = findEmoji(cleanText);
|
||||||
const nameParts = findNames(cleanText, (users || []));
|
const nameParts = findNames(cleanText, message ? (message.users || []) : []);
|
||||||
|
|
||||||
const parts = channelParts
|
const parts = channelParts
|
||||||
.concat(linkParts)
|
.concat(linkParts)
|
||||||
@ -134,7 +135,8 @@ module.exports = function parse(text, users = [], createElement = null) {
|
|||||||
|
|
||||||
// Wrap these potentially styled fragments with links and channel buttons
|
// Wrap these potentially styled fragments with links and channel buttons
|
||||||
if (textPart.link) {
|
if (textPart.link) {
|
||||||
return createElement("a", {
|
const preview = message && message.previews.find((p) => p.link === textPart.link);
|
||||||
|
const link = createElement("a", {
|
||||||
class: [
|
class: [
|
||||||
"inline-channel",
|
"inline-channel",
|
||||||
],
|
],
|
||||||
@ -144,6 +146,24 @@ module.exports = function parse(text, users = [], createElement = null) {
|
|||||||
rel: "noopener",
|
rel: "noopener",
|
||||||
},
|
},
|
||||||
}, fragments);
|
}, fragments);
|
||||||
|
|
||||||
|
if (!preview) {
|
||||||
|
return link;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [link, createElement(LinkPreviewToggle, {
|
||||||
|
class: ["toggle-button", "toggle-preview"],
|
||||||
|
props: {
|
||||||
|
link: preview,
|
||||||
|
},
|
||||||
|
on: {
|
||||||
|
linkPreviewToggle() {
|
||||||
|
console.log('it got toggled!!!')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, fragments)];
|
||||||
|
|
||||||
|
//`<button class="toggle-button toggle-preview" data-url="${escapedLink}" hidden></button>`;
|
||||||
} else if (textPart.channel) {
|
} else if (textPart.channel) {
|
||||||
return createElement("span", {
|
return createElement("span", {
|
||||||
class: [
|
class: [
|
||||||
|
@ -109,31 +109,6 @@ function appendPreview(preview, msg, template) {
|
|||||||
// their "More" button. Debounced handler to avoid performance cost.
|
// their "More" button. Debounced handler to avoid performance cost.
|
||||||
$(window).on("resize", debounce(togglePreviewMoreButtonsIfNeeded, 150));
|
$(window).on("resize", debounce(togglePreviewMoreButtonsIfNeeded, 150));
|
||||||
|
|
||||||
$("#chat").on("click", ".text .toggle-button", function() {
|
|
||||||
const self = $(this);
|
|
||||||
const content = self.closest(".content")
|
|
||||||
.find(`.preview[data-url="${self.data("url")}"] .toggle-content`);
|
|
||||||
|
|
||||||
self.toggleClass("opened");
|
|
||||||
content.toggleClass("show");
|
|
||||||
|
|
||||||
const isExpanded = content.hasClass("show");
|
|
||||||
|
|
||||||
if (isExpanded) {
|
|
||||||
content.trigger("showMoreIfNeeded");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tell the server we're toggling so it remembers at page reload
|
|
||||||
// TODO Avoid sending many single events when using `/collapse` or `/expand`
|
|
||||||
// See https://github.com/thelounge/thelounge/issues/1377
|
|
||||||
socket.emit("msg:preview:toggle", {
|
|
||||||
target: parseInt(self.closest(".chan").data("id"), 10),
|
|
||||||
msgId: parseInt(self.closest(".msg").prop("id").replace("msg-", ""), 10),
|
|
||||||
link: self.data("url"),
|
|
||||||
shown: isExpanded,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#chat").on("click", ".toggle-content .more", function() {
|
$("#chat").on("click", ".toggle-content .more", function() {
|
||||||
togglePreviewMore($(this));
|
togglePreviewMore($(this));
|
||||||
return false;
|
return false;
|
||||||
|
Loading…
Reference in New Issue
Block a user