diff --git a/client/components/Chat.vue b/client/components/Chat.vue
index f80ae191..e6d9c9d9 100644
--- a/client/components/Chat.vue
+++ b/client/components/Chat.vue
@@ -20,7 +20,19 @@
+
diff --git a/client/css/style.css b/client/css/style.css
index 4e7803d2..5f6c4754 100644
--- a/client/css/style.css
+++ b/client/css/style.css
@@ -277,6 +277,7 @@ kbd {
#chat .toggle-button::after,
#chat .toggle-content .more-caret::before,
#chat .scroll-down-arrow::after,
+#chat .topic-container .save-topic span::before,
#version-checker::before,
.context-menu-item::before,
#help .website-link::before,
@@ -969,6 +970,12 @@ background on hover (unless active) */
flex-shrink: 0;
}
+.topic-container {
+ position: relative;
+ flex-grow: 1;
+ padding-left: 10px;
+}
+
#windows .header .topic {
color: var(--body-color-muted);
margin-left: 8px;
@@ -978,6 +985,41 @@ background on hover (unless active) */
font-size: 14px;
}
+#windows .header .topic-input {
+ color: inherit;
+ background: transparent;
+ border: 1px solid #cdd3da;
+ border-radius: 2px;
+ padding-right: 37px;
+ padding-left: 10px;
+ width: 100%;
+ height: 35px;
+ overflow: hidden;
+ font-size: 14px;
+ outline: none;
+}
+
+.topic-container .save-topic {
+ position: absolute;
+ top: 6px;
+ right: 0;
+}
+
+.topic-container .save-topic span {
+ font-size: 16px;
+ color: #607992;
+ width: 35px;
+ height: 35px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ cursor: pointer;
+}
+
+.topic-container .save-topic span:hover {
+ opacity: 0.6;
+}
+
#chat {
overflow: hidden;
flex: 1 0 auto;
@@ -1829,6 +1871,10 @@ part/quit messages where we don't load previews (adds a blank line otherwise) */
content: "\f06e"; /* https://fontawesome.com/icons/eye?style=solid */
}
+.topic-container .save-topic span::before {
+ content: "\f00c"; /* https://fontawesome.com/icons/check?style=solid */
+}
+
.password-container .reveal-password.visible span::before {
content: "\f070"; /* https://fontawesome.com/icons/eye-slash?style=solid */
color: #ff4136;
diff --git a/client/js/contextMenuFactory.js b/client/js/contextMenuFactory.js
index 62dc47af..0b6d43be 100644
--- a/client/js/contextMenuFactory.js
+++ b/client/js/contextMenuFactory.js
@@ -6,7 +6,7 @@ const utils = require("./utils");
const ContextMenu = require("./contextMenu");
const contextMenuActions = [];
const contextMenuItems = [];
-const {findChannel} = require("./vue");
+const {vueApp, findChannel} = require("./vue");
module.exports = {
addContextMenuItem,
@@ -316,6 +316,25 @@ function addChannelListItem() {
});
}
+function addEditTopicItem() {
+ function setEditTopic(itemData) {
+ findChannel(Number(itemData)).channel.editTopic = true;
+ document.querySelector(`#sidebar .chan[data-id="${Number(itemData)}"]`).click();
+
+ vueApp.$nextTick(() => {
+ document.querySelector(`#chan-${Number(itemData)} .topic-input`).focus();
+ });
+ }
+
+ addContextMenuItem({
+ check: (target) => target.hasClass("channel"),
+ className: "edit",
+ displayName: "Edit topic",
+ data: (target) => target.attr("data-id"),
+ callback: setEditTopic,
+ });
+}
+
function addBanListItem() {
function banlist(itemData) {
socket.emit("input", {
@@ -376,6 +395,7 @@ function addDefaultItems() {
addEditNetworkItem();
addJoinItem();
addChannelListItem();
+ addEditTopicItem();
addBanListItem();
addIgnoreListItem();
addConnectItem();
diff --git a/client/js/vue.js b/client/js/vue.js
index 10c082ee..fea5d622 100644
--- a/client/js/vue.js
+++ b/client/js/vue.js
@@ -76,6 +76,7 @@ function initChannel(channel) {
channel.inputHistory = [""];
channel.historyLoading = false;
channel.scrolledToBottom = true;
+ channel.editTopic = false;
if (channel.type === "channel") {
channel.usersOutdated = true;