Merge pull request #3349 from ollipa/ollipa/edit-topic
Add functionality to edit channel topic from the user interface
This commit is contained in:
commit
217cfb4701
@ -20,7 +20,19 @@
|
|||||||
<div class="header">
|
<div class="header">
|
||||||
<button class="lt" aria-label="Toggle channel list" />
|
<button class="lt" aria-label="Toggle channel list" />
|
||||||
<span class="title">{{ channel.name }}</span>
|
<span class="title">{{ channel.name }}</span>
|
||||||
<span :title="channel.topic" class="topic"
|
<div v-if="channel.editTopic === true" class="topic-container">
|
||||||
|
<input
|
||||||
|
:value="channel.topic"
|
||||||
|
class="topic-input"
|
||||||
|
placeholder="Set channel topic"
|
||||||
|
@keyup.enter="saveTopic"
|
||||||
|
@keyup.esc="channel.editTopic = false"
|
||||||
|
/>
|
||||||
|
<span aria-label="Save topic" class="save-topic" @click="saveTopic">
|
||||||
|
<span type="button" aria-label="Save topic"></span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<span v-else :title="channel.topic" class="topic" @dblclick="editTopic"
|
||||||
><ParsedMessage
|
><ParsedMessage
|
||||||
v-if="channel.topic"
|
v-if="channel.topic"
|
||||||
:network="network"
|
:network="network"
|
||||||
@ -77,6 +89,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
const socket = require("../js/socket");
|
||||||
import ParsedMessage from "./ParsedMessage.vue";
|
import ParsedMessage from "./ParsedMessage.vue";
|
||||||
import MessageList from "./MessageList.vue";
|
import MessageList from "./MessageList.vue";
|
||||||
import ChatInput from "./ChatInput.vue";
|
import ChatInput from "./ChatInput.vue";
|
||||||
@ -118,6 +131,25 @@ export default {
|
|||||||
hideUserVisibleError() {
|
hideUserVisibleError() {
|
||||||
this.$root.currentUserVisibleError = null;
|
this.$root.currentUserVisibleError = null;
|
||||||
},
|
},
|
||||||
|
editTopic() {
|
||||||
|
if (this.channel.type === "channel") {
|
||||||
|
this.channel.editTopic = true;
|
||||||
|
|
||||||
|
this.$nextTick(() => {
|
||||||
|
document.querySelector(`#chan-${this.channel.id} .topic-input`).focus();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
saveTopic() {
|
||||||
|
this.channel.editTopic = false;
|
||||||
|
const newTopic = document.querySelector(`#chan-${this.channel.id} .topic-input`).value;
|
||||||
|
|
||||||
|
if (this.channel.topic !== newTopic) {
|
||||||
|
const target = this.channel.id;
|
||||||
|
const text = `/raw TOPIC ${this.channel.name} :${newTopic}`;
|
||||||
|
socket.emit("input", {target, text});
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -277,6 +277,7 @@ kbd {
|
|||||||
#chat .toggle-button::after,
|
#chat .toggle-button::after,
|
||||||
#chat .toggle-content .more-caret::before,
|
#chat .toggle-content .more-caret::before,
|
||||||
#chat .scroll-down-arrow::after,
|
#chat .scroll-down-arrow::after,
|
||||||
|
#chat .topic-container .save-topic span::before,
|
||||||
#version-checker::before,
|
#version-checker::before,
|
||||||
.context-menu-item::before,
|
.context-menu-item::before,
|
||||||
#help .website-link::before,
|
#help .website-link::before,
|
||||||
@ -969,6 +970,12 @@ background on hover (unless active) */
|
|||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.topic-container {
|
||||||
|
position: relative;
|
||||||
|
flex-grow: 1;
|
||||||
|
padding-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
#windows .header .topic {
|
#windows .header .topic {
|
||||||
color: var(--body-color-muted);
|
color: var(--body-color-muted);
|
||||||
margin-left: 8px;
|
margin-left: 8px;
|
||||||
@ -978,6 +985,41 @@ background on hover (unless active) */
|
|||||||
font-size: 14px;
|
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 {
|
#chat {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
flex: 1 0 auto;
|
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 */
|
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 {
|
.password-container .reveal-password.visible span::before {
|
||||||
content: "\f070"; /* https://fontawesome.com/icons/eye-slash?style=solid */
|
content: "\f070"; /* https://fontawesome.com/icons/eye-slash?style=solid */
|
||||||
color: #ff4136;
|
color: #ff4136;
|
||||||
|
@ -6,7 +6,7 @@ const utils = require("./utils");
|
|||||||
const ContextMenu = require("./contextMenu");
|
const ContextMenu = require("./contextMenu");
|
||||||
const contextMenuActions = [];
|
const contextMenuActions = [];
|
||||||
const contextMenuItems = [];
|
const contextMenuItems = [];
|
||||||
const {findChannel} = require("./vue");
|
const {vueApp, findChannel} = require("./vue");
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
addContextMenuItem,
|
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 addBanListItem() {
|
||||||
function banlist(itemData) {
|
function banlist(itemData) {
|
||||||
socket.emit("input", {
|
socket.emit("input", {
|
||||||
@ -376,6 +395,7 @@ function addDefaultItems() {
|
|||||||
addEditNetworkItem();
|
addEditNetworkItem();
|
||||||
addJoinItem();
|
addJoinItem();
|
||||||
addChannelListItem();
|
addChannelListItem();
|
||||||
|
addEditTopicItem();
|
||||||
addBanListItem();
|
addBanListItem();
|
||||||
addIgnoreListItem();
|
addIgnoreListItem();
|
||||||
addConnectItem();
|
addConnectItem();
|
||||||
|
@ -76,6 +76,7 @@ function initChannel(channel) {
|
|||||||
channel.inputHistory = [""];
|
channel.inputHistory = [""];
|
||||||
channel.historyLoading = false;
|
channel.historyLoading = false;
|
||||||
channel.scrolledToBottom = true;
|
channel.scrolledToBottom = true;
|
||||||
|
channel.editTopic = false;
|
||||||
|
|
||||||
if (channel.type === "channel") {
|
if (channel.type === "channel") {
|
||||||
channel.usersOutdated = true;
|
channel.usersOutdated = true;
|
||||||
|
Loading…
Reference in New Issue
Block a user