Create a generic confirmation dialog
This commit is contained in:
parent
7216b8124b
commit
44a8925b8c
@ -5,6 +5,7 @@
|
|||||||
<router-view ref="window"></router-view>
|
<router-view ref="window"></router-view>
|
||||||
<ImageViewer ref="imageViewer" />
|
<ImageViewer ref="imageViewer" />
|
||||||
<ContextMenu ref="contextMenu" />
|
<ContextMenu ref="contextMenu" />
|
||||||
|
<ConfirmDialog ref="confirmDialog" />
|
||||||
<div id="upload-overlay"></div>
|
<div id="upload-overlay"></div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -18,6 +19,7 @@ import storage from "../js/localStorage";
|
|||||||
import Sidebar from "./Sidebar.vue";
|
import Sidebar from "./Sidebar.vue";
|
||||||
import ImageViewer from "./ImageViewer.vue";
|
import ImageViewer from "./ImageViewer.vue";
|
||||||
import ContextMenu from "./ContextMenu.vue";
|
import ContextMenu from "./ContextMenu.vue";
|
||||||
|
import ConfirmDialog from "./ConfirmDialog.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "App",
|
name: "App",
|
||||||
@ -25,6 +27,7 @@ export default {
|
|||||||
Sidebar,
|
Sidebar,
|
||||||
ImageViewer,
|
ImageViewer,
|
||||||
ContextMenu,
|
ContextMenu,
|
||||||
|
ConfirmDialog,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
viewportClasses() {
|
viewportClasses() {
|
||||||
|
84
client/components/ConfirmDialog.vue
Normal file
84
client/components/ConfirmDialog.vue
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
<template>
|
||||||
|
<div id="confirm-dialog-overlay" :class="{opened: data !== null}">
|
||||||
|
<div v-if="data !== null" id="confirm-dialog">
|
||||||
|
<div class="confirm-text">
|
||||||
|
<div class="confirm-text-title">{{ data.title }}</div>
|
||||||
|
<p>{{ data.text }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="confirm-buttons">
|
||||||
|
<button class="btn btn-cancel" @click="close(false)">Cancel</button>
|
||||||
|
<button class="btn btn-danger" @click="close(true)">{{ data.button }}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#confirm-dialog {
|
||||||
|
background: var(--body-bg-color);
|
||||||
|
color: #fff;
|
||||||
|
margin: 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
max-width: 500px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#confirm-dialog .confirm-text {
|
||||||
|
padding: 15px;
|
||||||
|
user-select: text;
|
||||||
|
}
|
||||||
|
|
||||||
|
#confirm-dialog .confirm-text-title {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#confirm-dialog .confirm-buttons {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
padding: 15px;
|
||||||
|
background: rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
#confirm-dialog .confirm-buttons .btn {
|
||||||
|
margin-bottom: 0;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#confirm-dialog .confirm-buttons .btn-cancel {
|
||||||
|
border-color: transparent;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "ConfirmDialog",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
data: null,
|
||||||
|
callback: null,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.$root.$on("escapekey", this.close);
|
||||||
|
this.$root.$on("confirm-dialog", this.open);
|
||||||
|
},
|
||||||
|
destroyed() {
|
||||||
|
this.$root.$off("escapekey", this.close);
|
||||||
|
this.$root.$off("confirm-dialog", this.open);
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
open(data, callback) {
|
||||||
|
this.data = data;
|
||||||
|
this.callback = callback;
|
||||||
|
},
|
||||||
|
close(result) {
|
||||||
|
this.data = null;
|
||||||
|
|
||||||
|
if (this.callback) {
|
||||||
|
this.callback(!!result);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
@ -38,11 +38,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {
|
import {generateUserContextMenu, generateChannelContextMenu} from "../js/helpers/contextMenu.js";
|
||||||
generateUserContextMenu,
|
|
||||||
generateChannelContextMenu,
|
|
||||||
generateRemoveNetwork,
|
|
||||||
} from "../js/helpers/contextMenu.js";
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "ContextMenu",
|
name: "ContextMenu",
|
||||||
@ -65,21 +61,15 @@ export default {
|
|||||||
this.$root.$on("escapekey", this.close);
|
this.$root.$on("escapekey", this.close);
|
||||||
this.$root.$on("contextmenu:user", this.openUserContextMenu);
|
this.$root.$on("contextmenu:user", this.openUserContextMenu);
|
||||||
this.$root.$on("contextmenu:channel", this.openChannelContextMenu);
|
this.$root.$on("contextmenu:channel", this.openChannelContextMenu);
|
||||||
this.$root.$on("contextmenu:removenetwork", this.openRemoveNetworkContextMenu);
|
|
||||||
},
|
},
|
||||||
destroyed() {
|
destroyed() {
|
||||||
this.$root.$off("escapekey", this.close);
|
this.$root.$off("escapekey", this.close);
|
||||||
this.$root.$off("contextmenu:user", this.openUserContextMenu);
|
this.$root.$off("contextmenu:user", this.openUserContextMenu);
|
||||||
this.$root.$off("contextmenu:channel", this.openChannelContextMenu);
|
this.$root.$off("contextmenu:channel", this.openChannelContextMenu);
|
||||||
this.$root.$off("contextmenu:removenetwork", this.openRemoveNetworkContextMenu);
|
|
||||||
|
|
||||||
this.close();
|
this.close();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
openRemoveNetworkContextMenu(data) {
|
|
||||||
const items = generateRemoveNetwork(this.$root, data.lobby);
|
|
||||||
this.open(data.event, items);
|
|
||||||
},
|
|
||||||
openChannelContextMenu(data) {
|
openChannelContextMenu(data) {
|
||||||
const items = generateChannelContextMenu(this.$root, data.channel, data.network);
|
const items = generateChannelContextMenu(this.$root, data.channel, data.network);
|
||||||
this.open(data.event, items);
|
this.open(data.event, items);
|
||||||
|
@ -2709,6 +2709,7 @@ part/quit messages where we don't load previews (adds a blank line otherwise) */
|
|||||||
|
|
||||||
/* Image viewer and drag-and-drop overlay */
|
/* Image viewer and drag-and-drop overlay */
|
||||||
|
|
||||||
|
#confirm-dialog-overlay,
|
||||||
#upload-overlay,
|
#upload-overlay,
|
||||||
#image-viewer,
|
#image-viewer,
|
||||||
#image-viewer .open-btn,
|
#image-viewer .open-btn,
|
||||||
@ -2720,6 +2721,7 @@ part/quit messages where we don't load previews (adds a blank line otherwise) */
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#confirm-dialog-overlay,
|
||||||
#upload-overlay,
|
#upload-overlay,
|
||||||
#image-viewer {
|
#image-viewer {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
@ -2735,12 +2737,14 @@ part/quit messages where we don't load previews (adds a blank line otherwise) */
|
|||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#confirm-dialog-overlay.opened,
|
||||||
#upload-overlay.is-dragover,
|
#upload-overlay.is-dragover,
|
||||||
#image-viewer.opened {
|
#image-viewer.opened {
|
||||||
visibility: visible;
|
visibility: visible;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#confirm-dialog-overlay,
|
||||||
#image-viewer {
|
#image-viewer {
|
||||||
background: rgba(0, 0, 0, 0.9);
|
background: rgba(0, 0, 0, 0.9);
|
||||||
}
|
}
|
||||||
|
@ -135,17 +135,29 @@ export function generateChannelContextMenu($root, channel, network) {
|
|||||||
type: "item",
|
type: "item",
|
||||||
class: "clear-history",
|
class: "clear-history",
|
||||||
action() {
|
action() {
|
||||||
// TODO: Confirmation window
|
$root.$emit(
|
||||||
|
"confirm-dialog",
|
||||||
|
{
|
||||||
|
title: "Clear history",
|
||||||
|
text: `Are you sure you want to clear history for ${channel.name}? This cannot be undone.`,
|
||||||
|
button: "Clear history",
|
||||||
|
},
|
||||||
|
(result) => {
|
||||||
|
if (!result) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
channel.messages = [];
|
channel.messages = [];
|
||||||
channel.unread = 0;
|
channel.unread = 0;
|
||||||
channel.highlight = 0;
|
channel.highlight = 0;
|
||||||
channel.firstUnread = 0;
|
channel.firstUnread = 0;
|
||||||
channel.moreHistoryAvailable = false;
|
channel.moreHistoryAvailable = false;
|
||||||
|
|
||||||
socket.emit("history:clear", {
|
socket.emit("history:clear", {
|
||||||
target: channel.id,
|
target: channel.id,
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -282,31 +294,3 @@ export function generateUserContextMenu($root, channel, network, user) {
|
|||||||
|
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function generateRemoveNetwork($root, lobby) {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
label: lobby.name,
|
|
||||||
type: "item",
|
|
||||||
class: "network",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: "divider",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Yes, remove this",
|
|
||||||
type: "item",
|
|
||||||
action() {
|
|
||||||
lobby.closed = true;
|
|
||||||
socket.emit("input", {
|
|
||||||
target: Number(lobby.id),
|
|
||||||
text: "/quit",
|
|
||||||
});
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Cancel",
|
|
||||||
type: "item",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
@ -30,20 +30,25 @@ const vueApp = new Vue({
|
|||||||
},
|
},
|
||||||
closeChannel(channel) {
|
closeChannel(channel) {
|
||||||
if (channel.type === "lobby") {
|
if (channel.type === "lobby") {
|
||||||
const el = document.querySelector(
|
this.$root.$emit(
|
||||||
`#sidebar .channel-list-item[aria-controls="#chan-${channel.id}"]`
|
"confirm-dialog",
|
||||||
);
|
{
|
||||||
const rect = el.getBoundingClientRect();
|
title: "Remove network",
|
||||||
const event = new MouseEvent("click", {
|
text: `Are you sure you want to quit and remove ${channel.name}? This cannot be undone.`,
|
||||||
view: window,
|
button: "Remove network",
|
||||||
clientX: rect.left + 10,
|
},
|
||||||
clientY: rect.top,
|
(result) => {
|
||||||
});
|
if (!result) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.$root.$emit("contextmenu:removenetwork", {
|
channel.closed = true;
|
||||||
event: event,
|
socket.emit("input", {
|
||||||
lobby: channel,
|
target: Number(channel.id),
|
||||||
});
|
text: "/quit",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user