mirror of
https://github.com/thelounge/thelounge
synced 2024-12-04 01:39:14 +00:00
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
9 changed files with 126 additions and 27 deletions
|
@ -36,10 +36,6 @@ function buildChatMessage(data) {
|
||||||
target = "#chan-" + chat.find(".active").data("id");
|
target = "#chan-" + chat.find(".active").data("id");
|
||||||
}
|
}
|
||||||
|
|
||||||
data.msg.previews.forEach((preview) => {
|
|
||||||
preview.shown = options.shouldOpenMessagePreview(preview.type);
|
|
||||||
});
|
|
||||||
|
|
||||||
const chan = chat.find(target);
|
const chan = chat.find(target);
|
||||||
let template = "msg";
|
let template = "msg";
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
const $ = require("jquery");
|
const $ = require("jquery");
|
||||||
const options = require("./options");
|
const options = require("./options");
|
||||||
|
const socket = require("./socket");
|
||||||
const templates = require("../views");
|
const templates = require("../views");
|
||||||
const input = $("#input");
|
const input = $("#input");
|
||||||
|
|
||||||
|
@ -24,7 +25,7 @@ function renderPreview(preview, msg) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
preview.shown = options.shouldOpenMessagePreview(preview.type);
|
preview.shown = preview.shown && options.shouldOpenMessagePreview(preview.type);
|
||||||
|
|
||||||
const container = msg.closest(".chat");
|
const container = msg.closest(".chat");
|
||||||
let bottom = false;
|
let bottom = false;
|
||||||
|
@ -60,6 +61,16 @@ $("#chat").on("click", ".toggle-button", function() {
|
||||||
self.toggleClass("opened");
|
self.toggleClass("opened");
|
||||||
content.toggleClass("show");
|
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 scrollbar was at the bottom before toggling the preview, keep it at the bottom
|
||||||
if (bottom) {
|
if (bottom) {
|
||||||
container.scrollBottom();
|
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) {
|
Chan.prototype.findUser = function(nick) {
|
||||||
return _.find(this.users, {nick: nick});
|
return _.find(this.users, {nick: nick});
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,6 +2,31 @@
|
||||||
|
|
||||||
var _ = require("lodash");
|
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 = {
|
Msg.Type = {
|
||||||
UNHANDLED: "unhandled",
|
UNHANDLED: "unhandled",
|
||||||
ACTION: "action",
|
ACTION: "action",
|
||||||
|
@ -24,22 +49,3 @@ Msg.Type = {
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = Msg;
|
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: "",
|
body: "",
|
||||||
thumb: "",
|
thumb: "",
|
||||||
link: link,
|
link: link,
|
||||||
|
shown: true,
|
||||||
})).slice(0, 5); // Only preview the first 5 URLs in message to avoid abuse
|
})).slice(0, 5); // Only preview the first 5 URLs in message to avoid abuse
|
||||||
|
|
||||||
msg.previews.forEach((preview) => {
|
msg.previews.forEach((preview) => {
|
||||||
|
|
|
@ -280,6 +280,26 @@ function init(socket, client) {
|
||||||
client.names(data);
|
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.join(client.id);
|
||||||
socket.emit("init", {
|
socket.emit("init", {
|
||||||
active: client.lastActiveChannel,
|
active: client.lastActiveChannel,
|
||||||
|
|
|
@ -3,9 +3,30 @@
|
||||||
var expect = require("chai").expect;
|
var expect = require("chai").expect;
|
||||||
|
|
||||||
var Chan = require("../../src/models/chan");
|
var Chan = require("../../src/models/chan");
|
||||||
|
var Msg = require("../../src/models/msg");
|
||||||
var User = require("../../src/models/user");
|
var User = require("../../src/models/user");
|
||||||
|
|
||||||
describe("Chan", function() {
|
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() {
|
describe("#sortUsers(irc)", function() {
|
||||||
var network = {
|
var network = {
|
||||||
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: "",
|
head: "",
|
||||||
link: url,
|
link: url,
|
||||||
thumb: "",
|
thumb: "",
|
||||||
type: "loading"
|
type: "loading",
|
||||||
|
shown: true,
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
this.app.get("/basic", function(req, res) {
|
this.app.get("/basic", function(req, res) {
|
||||||
|
@ -193,13 +194,15 @@ describe("Link plugin", function() {
|
||||||
head: "",
|
head: "",
|
||||||
link: "http://localhost:9002/one",
|
link: "http://localhost:9002/one",
|
||||||
thumb: "",
|
thumb: "",
|
||||||
type: "loading"
|
type: "loading",
|
||||||
|
shown: true,
|
||||||
}, {
|
}, {
|
||||||
body: "",
|
body: "",
|
||||||
head: "",
|
head: "",
|
||||||
link: "http://localhost:9002/two",
|
link: "http://localhost:9002/two",
|
||||||
thumb: "",
|
thumb: "",
|
||||||
type: "loading"
|
type: "loading",
|
||||||
|
shown: true,
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
this.app.get("/one", function(req, res) {
|
this.app.get("/one", function(req, res) {
|
||||||
|
|
Loading…
Reference in a new issue