Merge pull request #1366 from thelounge/astorije/persist-preview-toggle
Keep track of preview visibility on the server so it persists at page reload
This commit is contained in:
commit
8aa89d7da2
@ -36,10 +36,6 @@ function buildChatMessage(data) {
|
||||
target = "#chan-" + chat.find(".active").data("id");
|
||||
}
|
||||
|
||||
data.msg.previews.forEach((preview) => {
|
||||
preview.shown = options.shouldOpenMessagePreview(preview.type);
|
||||
});
|
||||
|
||||
const chan = chat.find(target);
|
||||
let template = "msg";
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
const $ = require("jquery");
|
||||
const options = require("./options");
|
||||
const socket = require("./socket");
|
||||
const templates = require("../views");
|
||||
const input = $("#input");
|
||||
|
||||
@ -24,7 +25,7 @@ function renderPreview(preview, msg) {
|
||||
return;
|
||||
}
|
||||
|
||||
preview.shown = options.shouldOpenMessagePreview(preview.type);
|
||||
preview.shown = preview.shown && options.shouldOpenMessagePreview(preview.type);
|
||||
|
||||
const container = msg.closest(".chat");
|
||||
let bottom = false;
|
||||
@ -60,6 +61,16 @@ $("#chat").on("click", ".toggle-button", function() {
|
||||
self.toggleClass("opened");
|
||||
content.toggleClass("show");
|
||||
|
||||
// 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/lounge/issues/1377
|
||||
socket.emit("msg:preview:toggle", {
|
||||
target: parseInt(self.closest(".chan").data("id"), 10),
|
||||
msgId: parseInt(self.closest(".msg").attr("id").replace("msg-", ""), 10),
|
||||
link: self.data("url"),
|
||||
shown: content.hasClass("show"),
|
||||
});
|
||||
|
||||
// If scrollbar was at the bottom before toggling the preview, keep it at the bottom
|
||||
if (bottom) {
|
||||
container.scrollBottom();
|
||||
|
@ -93,6 +93,10 @@ Chan.prototype.sortUsers = function(irc) {
|
||||
});
|
||||
};
|
||||
|
||||
Chan.prototype.findMessage = function(msgId) {
|
||||
return this.messages.find((message) => message.id === msgId);
|
||||
};
|
||||
|
||||
Chan.prototype.findUser = function(nick) {
|
||||
return _.find(this.users, {nick: nick});
|
||||
};
|
||||
|
@ -2,6 +2,31 @@
|
||||
|
||||
var _ = require("lodash");
|
||||
|
||||
var id = 0;
|
||||
|
||||
class Msg {
|
||||
constructor(attr) {
|
||||
_.defaults(this, attr, {
|
||||
from: "",
|
||||
id: id++,
|
||||
previews: [],
|
||||
text: "",
|
||||
type: Msg.Type.MESSAGE,
|
||||
self: false
|
||||
});
|
||||
|
||||
if (this.time > 0) {
|
||||
this.time = new Date(this.time);
|
||||
} else {
|
||||
this.time = new Date();
|
||||
}
|
||||
}
|
||||
|
||||
findPreview(link) {
|
||||
return this.previews.find((preview) => preview.link === link);
|
||||
}
|
||||
}
|
||||
|
||||
Msg.Type = {
|
||||
UNHANDLED: "unhandled",
|
||||
ACTION: "action",
|
||||
@ -24,22 +49,3 @@ Msg.Type = {
|
||||
};
|
||||
|
||||
module.exports = Msg;
|
||||
|
||||
var id = 0;
|
||||
|
||||
function Msg(attr) {
|
||||
_.defaults(this, attr, {
|
||||
from: "",
|
||||
id: id++,
|
||||
previews: [],
|
||||
text: "",
|
||||
type: Msg.Type.MESSAGE,
|
||||
self: false
|
||||
});
|
||||
|
||||
if (this.time > 0) {
|
||||
this.time = new Date(this.time);
|
||||
} else {
|
||||
this.time = new Date();
|
||||
}
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ module.exports = function(client, chan, msg) {
|
||||
body: "",
|
||||
thumb: "",
|
||||
link: link,
|
||||
shown: true,
|
||||
})).slice(0, 5); // Only preview the first 5 URLs in message to avoid abuse
|
||||
|
||||
msg.previews.forEach((preview) => {
|
||||
|
@ -280,6 +280,26 @@ function init(socket, client) {
|
||||
client.names(data);
|
||||
}
|
||||
);
|
||||
|
||||
socket.on("msg:preview:toggle", function(data) {
|
||||
const networkAndChan = client.find(data.target);
|
||||
if (!networkAndChan) {
|
||||
return;
|
||||
}
|
||||
|
||||
const message = networkAndChan.chan.findMessage(data.msgId);
|
||||
|
||||
if (!message) {
|
||||
return;
|
||||
}
|
||||
|
||||
const preview = message.findPreview(data.link);
|
||||
|
||||
if (preview) {
|
||||
preview.shown = data.shown;
|
||||
}
|
||||
});
|
||||
|
||||
socket.join(client.id);
|
||||
socket.emit("init", {
|
||||
active: client.lastActiveChannel,
|
||||
|
@ -3,9 +3,30 @@
|
||||
var expect = require("chai").expect;
|
||||
|
||||
var Chan = require("../../src/models/chan");
|
||||
var Msg = require("../../src/models/msg");
|
||||
var User = require("../../src/models/user");
|
||||
|
||||
describe("Chan", function() {
|
||||
describe("#findMessage(id)", function() {
|
||||
const chan = new Chan({
|
||||
messages: [
|
||||
new Msg(),
|
||||
new Msg({
|
||||
text: "Message to be found"
|
||||
}),
|
||||
new Msg()
|
||||
]
|
||||
});
|
||||
|
||||
it("should find a message in the list of messages", function() {
|
||||
expect(chan.findMessage(1).text).to.equal("Message to be found");
|
||||
});
|
||||
|
||||
it("should not find a message that does not exist", function() {
|
||||
expect(chan.findMessage(42)).to.be.undefined;
|
||||
});
|
||||
});
|
||||
|
||||
describe("#sortUsers(irc)", function() {
|
||||
var network = {
|
||||
network: {
|
||||
|
37
test/models/msg.js
Normal file
37
test/models/msg.js
Normal file
@ -0,0 +1,37 @@
|
||||
"use strict";
|
||||
|
||||
const expect = require("chai").expect;
|
||||
|
||||
const Msg = require("../../src/models/msg");
|
||||
|
||||
describe("Msg", function() {
|
||||
describe("#findPreview(link)", function() {
|
||||
const msg = new Msg({
|
||||
previews: [{
|
||||
body: "",
|
||||
head: "Example Domain",
|
||||
link: "https://example.org/",
|
||||
thumb: "",
|
||||
type: "link",
|
||||
shown: true,
|
||||
}, {
|
||||
body: "",
|
||||
head: "The Lounge",
|
||||
link: "https://thelounge.github.io/",
|
||||
thumb: "",
|
||||
type: "link",
|
||||
shown: true,
|
||||
}]
|
||||
});
|
||||
|
||||
it("should find a preview given an existing link", function() {
|
||||
expect(msg.findPreview("https://thelounge.github.io/").head)
|
||||
.to.equal("The Lounge");
|
||||
});
|
||||
|
||||
it("should not find a preview that does not exist", function() {
|
||||
expect(msg.findPreview("https://github.com/thelounge/lounge"))
|
||||
.to.be.undefined;
|
||||
});
|
||||
});
|
||||
});
|
@ -39,7 +39,8 @@ describe("Link plugin", function() {
|
||||
head: "",
|
||||
link: url,
|
||||
thumb: "",
|
||||
type: "loading"
|
||||
type: "loading",
|
||||
shown: true,
|
||||
}]);
|
||||
|
||||
this.app.get("/basic", function(req, res) {
|
||||
@ -193,13 +194,15 @@ describe("Link plugin", function() {
|
||||
head: "",
|
||||
link: "http://localhost:9002/one",
|
||||
thumb: "",
|
||||
type: "loading"
|
||||
type: "loading",
|
||||
shown: true,
|
||||
}, {
|
||||
body: "",
|
||||
head: "",
|
||||
link: "http://localhost:9002/two",
|
||||
thumb: "",
|
||||
type: "loading"
|
||||
type: "loading",
|
||||
shown: true,
|
||||
}]);
|
||||
|
||||
this.app.get("/one", function(req, res) {
|
||||
|
Loading…
Reference in New Issue
Block a user