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