Create an event bus
This commit is contained in:
parent
96a983b310
commit
f0253075d8
@ -13,6 +13,7 @@
|
||||
|
||||
<script>
|
||||
const constants = require("../js/constants");
|
||||
import eventbus from "../js/eventbus";
|
||||
import Mousetrap from "mousetrap";
|
||||
import throttle from "lodash/throttle";
|
||||
import storage from "../js/localStorage";
|
||||
@ -53,14 +54,14 @@ export default {
|
||||
|
||||
// Make a single throttled resize listener available to all components
|
||||
this.debouncedResize = throttle(() => {
|
||||
this.$root.$emit("resize");
|
||||
eventbus.emit("resize");
|
||||
}, 100);
|
||||
|
||||
window.addEventListener("resize", this.debouncedResize, {passive: true});
|
||||
|
||||
// Emit a daychange event every time the day changes so date markers know when to update themselves
|
||||
const emitDayChange = () => {
|
||||
this.$root.$emit("daychange");
|
||||
eventbus.emit("daychange");
|
||||
// This should always be 24h later but re-computing exact value just in case
|
||||
this.dayChangeTimeout = setTimeout(emitDayChange, this.msUntilNextDay());
|
||||
};
|
||||
@ -77,7 +78,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
escapeKey() {
|
||||
this.$root.$emit("escapekey");
|
||||
eventbus.emit("escapekey");
|
||||
},
|
||||
toggleSidebar(e) {
|
||||
if (isIgnoredKeybind(e)) {
|
||||
|
@ -30,6 +30,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import eventbus from "../js/eventbus";
|
||||
import isChannelCollapsed from "../js/helpers/isChannelCollapsed";
|
||||
|
||||
export default {
|
||||
@ -74,7 +75,7 @@ export default {
|
||||
this.$root.switchToChannel(this.channel);
|
||||
},
|
||||
openContextMenu(event) {
|
||||
this.$root.$emit("contextmenu:channel", {
|
||||
eventbus.emit("contextmenu:channel", {
|
||||
event: event,
|
||||
channel: this.channel,
|
||||
network: this.network,
|
||||
|
@ -102,6 +102,7 @@
|
||||
|
||||
<script>
|
||||
import socket from "../js/socket";
|
||||
import eventbus from "../js/eventbus";
|
||||
import ParsedMessage from "./ParsedMessage.vue";
|
||||
import MessageList from "./MessageList.vue";
|
||||
import ChatInput from "./ChatInput.vue";
|
||||
@ -197,14 +198,14 @@ export default {
|
||||
}
|
||||
},
|
||||
openContextMenu(event) {
|
||||
this.$root.$emit("contextmenu:channel", {
|
||||
eventbus.emit("contextmenu:channel", {
|
||||
event: event,
|
||||
channel: this.channel,
|
||||
network: this.network,
|
||||
});
|
||||
},
|
||||
openMentions() {
|
||||
this.$root.$emit("mentions:toggle", {
|
||||
eventbus.emit("mentions:toggle", {
|
||||
event: event,
|
||||
});
|
||||
},
|
||||
|
@ -56,6 +56,7 @@ import autocompletion from "../js/autocompletion";
|
||||
import commands from "../js/commands/index";
|
||||
import socket from "../js/socket";
|
||||
import upload from "../js/upload";
|
||||
import eventbus from "../js/eventbus";
|
||||
|
||||
const formattingHotkeys = {
|
||||
"mod+k": "\x03",
|
||||
@ -101,7 +102,7 @@ export default {
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.$root.$on("escapekey", this.blurInput);
|
||||
eventbus.on("escapekey", this.blurInput);
|
||||
|
||||
if (this.$store.state.settings.autocomplete) {
|
||||
autocompletionRef = autocompletion(this.$refs.input);
|
||||
@ -163,7 +164,7 @@ export default {
|
||||
}
|
||||
},
|
||||
destroyed() {
|
||||
this.$root.$off("escapekey", this.blurInput);
|
||||
eventbus.off("escapekey", this.blurInput);
|
||||
|
||||
if (autocompletionRef) {
|
||||
autocompletionRef.destroy();
|
||||
|
@ -51,6 +51,8 @@
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import eventbus from "../js/eventbus";
|
||||
|
||||
export default {
|
||||
name: "ConfirmDialog",
|
||||
data() {
|
||||
@ -60,12 +62,12 @@ export default {
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.$root.$on("escapekey", this.close);
|
||||
this.$root.$on("confirm-dialog", this.open);
|
||||
eventbus.on("escapekey", this.close);
|
||||
eventbus.on("confirm-dialog", this.open);
|
||||
},
|
||||
destroyed() {
|
||||
this.$root.$off("escapekey", this.close);
|
||||
this.$root.$off("confirm-dialog", this.open);
|
||||
eventbus.off("escapekey", this.close);
|
||||
eventbus.off("confirm-dialog", this.open);
|
||||
},
|
||||
methods: {
|
||||
open(data, callback) {
|
||||
|
@ -39,6 +39,7 @@
|
||||
|
||||
<script>
|
||||
import {generateUserContextMenu, generateChannelContextMenu} from "../js/helpers/contextMenu.js";
|
||||
import eventbus from "../js/eventbus";
|
||||
|
||||
export default {
|
||||
name: "ContextMenu",
|
||||
@ -58,14 +59,14 @@ export default {
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.$root.$on("escapekey", this.close);
|
||||
this.$root.$on("contextmenu:user", this.openUserContextMenu);
|
||||
this.$root.$on("contextmenu:channel", this.openChannelContextMenu);
|
||||
eventbus.on("escapekey", this.close);
|
||||
eventbus.on("contextmenu:user", this.openUserContextMenu);
|
||||
eventbus.on("contextmenu:channel", this.openChannelContextMenu);
|
||||
},
|
||||
destroyed() {
|
||||
this.$root.$off("escapekey", this.close);
|
||||
this.$root.$off("contextmenu:user", this.openUserContextMenu);
|
||||
this.$root.$off("contextmenu:channel", this.openChannelContextMenu);
|
||||
eventbus.off("escapekey", this.close);
|
||||
eventbus.off("contextmenu:user", this.openUserContextMenu);
|
||||
eventbus.off("contextmenu:channel", this.openChannelContextMenu);
|
||||
|
||||
this.close();
|
||||
},
|
||||
|
@ -9,6 +9,7 @@
|
||||
<script>
|
||||
import dayjs from "dayjs";
|
||||
import calendar from "dayjs/plugin/calendar";
|
||||
import eventbus from "../js/eventbus";
|
||||
|
||||
dayjs.extend(calendar);
|
||||
|
||||
@ -24,11 +25,11 @@ export default {
|
||||
},
|
||||
mounted() {
|
||||
if (this.hoursPassed() < 48) {
|
||||
this.$root.$on("daychange", this.dayChange);
|
||||
eventbus.on("daychange", this.dayChange);
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.$root.$off("daychange", this.dayChange);
|
||||
eventbus.off("daychange", this.dayChange);
|
||||
},
|
||||
methods: {
|
||||
hoursPassed() {
|
||||
@ -38,7 +39,7 @@ export default {
|
||||
this.$forceUpdate();
|
||||
|
||||
if (this.hoursPassed() >= 48) {
|
||||
this.$root.$off("daychange", this.dayChange);
|
||||
eventbus.off("daychange", this.dayChange);
|
||||
}
|
||||
},
|
||||
friendlyDate() {
|
||||
|
@ -40,6 +40,7 @@
|
||||
|
||||
<script>
|
||||
import Mousetrap from "mousetrap";
|
||||
import eventbus from "../js/eventbus";
|
||||
|
||||
export default {
|
||||
name: "ImageViewer",
|
||||
@ -79,8 +80,8 @@ export default {
|
||||
link(newLink, oldLink) {
|
||||
// TODO: history.pushState
|
||||
if (newLink === null) {
|
||||
this.$root.$off("escapekey", this.closeViewer);
|
||||
this.$root.$off("resize", this.correctPosition);
|
||||
eventbus.off("escapekey", this.closeViewer);
|
||||
eventbus.off("resize", this.correctPosition);
|
||||
Mousetrap.unbind("left", this.previous);
|
||||
Mousetrap.unbind("right", this.next);
|
||||
return;
|
||||
@ -89,8 +90,8 @@ export default {
|
||||
this.setPrevNextImages();
|
||||
|
||||
if (!oldLink) {
|
||||
this.$root.$on("escapekey", this.closeViewer);
|
||||
this.$root.$on("resize", this.correctPosition);
|
||||
eventbus.on("escapekey", this.closeViewer);
|
||||
eventbus.on("resize", this.correctPosition);
|
||||
Mousetrap.bind("left", this.previous);
|
||||
Mousetrap.bind("right", this.next);
|
||||
}
|
||||
|
@ -130,6 +130,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import eventbus from "../js/eventbus";
|
||||
import friendlysize from "../js/helpers/friendlysize";
|
||||
|
||||
export default {
|
||||
@ -167,12 +168,12 @@ export default {
|
||||
this.updateShownState();
|
||||
},
|
||||
mounted() {
|
||||
this.$root.$on("resize", this.handleResize);
|
||||
eventbus.on("resize", this.handleResize);
|
||||
|
||||
this.onPreviewUpdate();
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.$root.$off("resize", this.handleResize);
|
||||
eventbus.off("resize", this.handleResize);
|
||||
},
|
||||
destroyed() {
|
||||
// Let this preview go through load/canplay events again,
|
||||
|
@ -125,6 +125,7 @@
|
||||
import Username from "./Username.vue";
|
||||
import ParsedMessage from "./ParsedMessage.vue";
|
||||
import socket from "../js/socket";
|
||||
import eventbus from "../js/eventbus";
|
||||
import localetime from "../js/helpers/localetime";
|
||||
import dayjs from "dayjs";
|
||||
import relativeTime from "dayjs/plugin/relativeTime";
|
||||
@ -161,10 +162,10 @@ export default {
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.$root.$on("mentions:toggle", this.openPopup);
|
||||
eventbus.on("mentions:toggle", this.openPopup);
|
||||
},
|
||||
destroyed() {
|
||||
this.$root.$off("mentions:toggle", this.openPopup);
|
||||
eventbus.off("mentions:toggle", this.openPopup);
|
||||
},
|
||||
methods: {
|
||||
messageTime(time) {
|
||||
|
@ -56,6 +56,7 @@
|
||||
|
||||
<script>
|
||||
const constants = require("../js/constants");
|
||||
import eventbus from "../js/eventbus";
|
||||
import clipboard from "../js/clipboard";
|
||||
import socket from "../js/socket";
|
||||
import Message from "./Message.vue";
|
||||
@ -173,7 +174,7 @@ export default {
|
||||
mounted() {
|
||||
this.$refs.chat.addEventListener("scroll", this.handleScroll, {passive: true});
|
||||
|
||||
this.$root.$on("resize", this.handleResize);
|
||||
eventbus.on("resize", this.handleResize);
|
||||
|
||||
this.$nextTick(() => {
|
||||
if (this.historyObserver) {
|
||||
@ -185,7 +186,7 @@ export default {
|
||||
this.unreadMarkerShown = false;
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.$root.$off("resize", this.handleResize);
|
||||
eventbus.off("resize", this.handleResize);
|
||||
this.$refs.chat.removeEventListener("scroll", this.handleScroll);
|
||||
},
|
||||
destroyed() {
|
||||
|
@ -11,6 +11,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import eventbus from "../js/eventbus";
|
||||
import colorClass from "../js/helpers/colorClass";
|
||||
|
||||
export default {
|
||||
@ -30,7 +31,7 @@ export default {
|
||||
return this.onHover(this.user);
|
||||
},
|
||||
openContextMenu(event) {
|
||||
this.$root.$emit("contextmenu:user", {
|
||||
eventbus.emit("contextmenu:user", {
|
||||
event: event,
|
||||
user: this.user,
|
||||
});
|
||||
|
43
client/js/eventbus.js
Normal file
43
client/js/eventbus.js
Normal file
@ -0,0 +1,43 @@
|
||||
const events = new Map();
|
||||
|
||||
class EventBus {
|
||||
/**
|
||||
* Register an event handler for the given type.
|
||||
*
|
||||
* @param {String} type Type of event to listen for.
|
||||
* @param {Function} handler Function to call in response to given event.
|
||||
*/
|
||||
on(type, handler) {
|
||||
if (events.has(type)) {
|
||||
events[type].push(handler);
|
||||
} else {
|
||||
events[type] = [handler];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an event handler for the given type.
|
||||
*
|
||||
* @param {String} type Type of event to unregister `handler` from.
|
||||
* @param {Function} handler Handler function to remove.
|
||||
*/
|
||||
off(type, handler) {
|
||||
if (events.has(type)) {
|
||||
events[type] = events[type].filter((item) => item !== handler);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke all handlers for the given type.
|
||||
*
|
||||
* @param {String} type The event type to invoke.
|
||||
* @param {Any} [evt] Any value (object is recommended and powerful), passed to each handler.
|
||||
*/
|
||||
emit(type, evt) {
|
||||
if (events.has(type)) {
|
||||
events[type].slice().map((handler) => handler(evt));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default new EventBus();
|
@ -1,6 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
import socket from "../socket";
|
||||
import eventbus from "../eventbus";
|
||||
|
||||
export function generateChannelContextMenu($root, channel, network) {
|
||||
const typeMap = {
|
||||
@ -135,7 +136,7 @@ export function generateChannelContextMenu($root, channel, network) {
|
||||
type: "item",
|
||||
class: "clear-history",
|
||||
action() {
|
||||
$root.$emit(
|
||||
eventbus.emit(
|
||||
"confirm-dialog",
|
||||
{
|
||||
title: "Clear history",
|
||||
|
@ -9,6 +9,7 @@ import App from "../components/App.vue";
|
||||
import storage from "./localStorage";
|
||||
import {router, navigate} from "./router";
|
||||
import socket from "./socket";
|
||||
import eventbus from "./eventbus";
|
||||
|
||||
import "./socket-events";
|
||||
import "./webpush";
|
||||
@ -18,7 +19,7 @@ const favicon = document.getElementById("favicon");
|
||||
const faviconNormal = favicon.getAttribute("href");
|
||||
const faviconAlerted = favicon.dataset.other;
|
||||
|
||||
const vueApp = new Vue({
|
||||
new Vue({
|
||||
el: "#viewport",
|
||||
router,
|
||||
mounted() {
|
||||
@ -30,7 +31,7 @@ const vueApp = new Vue({
|
||||
},
|
||||
closeChannel(channel) {
|
||||
if (channel.type === "lobby") {
|
||||
this.$root.$emit(
|
||||
eventbus.emit(
|
||||
"confirm-dialog",
|
||||
{
|
||||
title: "Remove network",
|
||||
@ -75,7 +76,7 @@ store.watch(
|
||||
(sidebarOpen) => {
|
||||
if (window.innerWidth > constants.mobileViewportPixels) {
|
||||
storage.set("thelounge.state.sidebar", sidebarOpen);
|
||||
vueApp.$emit("resize");
|
||||
eventbus.emit("resize");
|
||||
}
|
||||
}
|
||||
);
|
||||
@ -84,7 +85,7 @@ store.watch(
|
||||
(state) => state.userlistOpen,
|
||||
(userlistOpen) => {
|
||||
storage.set("thelounge.state.userlist", userlistOpen);
|
||||
vueApp.$emit("resize");
|
||||
eventbus.emit("resize");
|
||||
}
|
||||
);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user