Move most side bar and user list interactions to vue.
This commit is contained in:
parent
e73bf1e9a7
commit
467ebab31f
@ -2,7 +2,7 @@
|
|||||||
<!-- TODO: move all class toggling to vue, since vue clears existing classes when changing the notified class -->
|
<!-- TODO: move all class toggling to vue, since vue clears existing classes when changing the notified class -->
|
||||||
<div
|
<div
|
||||||
id="viewport"
|
id="viewport"
|
||||||
:class="{notified: $store.state.isNotified}"
|
:class="viewportClasses"
|
||||||
role="tablist"
|
role="tablist"
|
||||||
>
|
>
|
||||||
<Sidebar
|
<Sidebar
|
||||||
@ -54,6 +54,15 @@ export default {
|
|||||||
activeChannel: Object,
|
activeChannel: Object,
|
||||||
networks: Array,
|
networks: Array,
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
viewportClasses() {
|
||||||
|
return {
|
||||||
|
"notified": this.$store.state.isNotified,
|
||||||
|
"menu-open": this.$store.state.sidebarOpen,
|
||||||
|
"userlist-open": this.$store.state.userlistOpen,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
// 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(() => {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
|
<!-- TODO: move closed style to it's own class -->
|
||||||
<div
|
<div
|
||||||
v-if="
|
v-if="
|
||||||
!network.isCollapsed ||
|
!network.isCollapsed ||
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
role="tabpanel"
|
role="tabpanel"
|
||||||
>
|
>
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<button class="lt" aria-label="Toggle channel list" />
|
<SidebarToggle />
|
||||||
<span class="title">{{ channel.name }}</span>
|
<span class="title">{{ channel.name }}</span>
|
||||||
<div v-if="channel.editTopic === true" class="topic-container">
|
<div v-if="channel.editTopic === true" class="topic-container">
|
||||||
<input
|
<input
|
||||||
@ -44,7 +44,11 @@
|
|||||||
class="rt-tooltip tooltipped tooltipped-w"
|
class="rt-tooltip tooltipped tooltipped-w"
|
||||||
aria-label="Toggle user list"
|
aria-label="Toggle user list"
|
||||||
>
|
>
|
||||||
<button class="rt" aria-label="Toggle user list" />
|
<button
|
||||||
|
class="rt"
|
||||||
|
aria-label="Toggle user list"
|
||||||
|
@click="$root.toggleUserlist"
|
||||||
|
/>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="channel.type === 'special'" class="chat-content">
|
<div v-if="channel.type === 'special'" class="chat-content">
|
||||||
@ -94,6 +98,7 @@ 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";
|
||||||
import ChatUserList from "./ChatUserList.vue";
|
import ChatUserList from "./ChatUserList.vue";
|
||||||
|
import SidebarToggle from "./SidebarToggle.vue";
|
||||||
import ListBans from "./Special/ListBans.vue";
|
import ListBans from "./Special/ListBans.vue";
|
||||||
import ListInvites from "./Special/ListInvites.vue";
|
import ListInvites from "./Special/ListInvites.vue";
|
||||||
import ListChannels from "./Special/ListChannels.vue";
|
import ListChannels from "./Special/ListChannels.vue";
|
||||||
@ -106,6 +111,7 @@ export default {
|
|||||||
MessageList,
|
MessageList,
|
||||||
ChatInput,
|
ChatInput,
|
||||||
ChatUserList,
|
ChatUserList,
|
||||||
|
SidebarToggle,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
network: Object,
|
network: Object,
|
||||||
|
@ -6,10 +6,7 @@
|
|||||||
aria-label="Connect"
|
aria-label="Connect"
|
||||||
>
|
>
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<button
|
<SidebarToggle />
|
||||||
class="lt"
|
|
||||||
aria-label="Toggle channel list"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<form
|
<form
|
||||||
class="container"
|
class="container"
|
||||||
@ -217,11 +214,13 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import RevealPassword from "./RevealPassword.vue";
|
import RevealPassword from "./RevealPassword.vue";
|
||||||
|
import SidebarToggle from "./SidebarToggle.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "NetworkForm",
|
name: "NetworkForm",
|
||||||
components: {
|
components: {
|
||||||
RevealPassword,
|
RevealPassword,
|
||||||
|
SidebarToggle,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
handleSubmit: Function,
|
handleSubmit: Function,
|
||||||
|
@ -66,7 +66,10 @@
|
|||||||
/></span>
|
/></span>
|
||||||
</footer>
|
</footer>
|
||||||
</aside>
|
</aside>
|
||||||
<div id="sidebar-overlay" />
|
<div
|
||||||
|
id="sidebar-overlay"
|
||||||
|
@click="$root.setSidebar(false)"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
13
client/components/SidebarToggle.vue
Normal file
13
client/components/SidebarToggle.vue
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<button
|
||||||
|
class="lt"
|
||||||
|
aria-label="Toggle channel list"
|
||||||
|
@click="$root.toggleSidebar"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "SidebarToggle",
|
||||||
|
};
|
||||||
|
</script>
|
@ -5,10 +5,7 @@
|
|||||||
aria-label="Changelog"
|
aria-label="Changelog"
|
||||||
>
|
>
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<button
|
<SidebarToggle />
|
||||||
class="lt"
|
|
||||||
aria-label="Toggle channel list"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<a
|
<a
|
||||||
@ -42,8 +39,13 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import SidebarToggle from "../SidebarToggle.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Changelog",
|
name: "Changelog",
|
||||||
|
components: {
|
||||||
|
SidebarToggle,
|
||||||
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|
||||||
},
|
},
|
||||||
|
@ -6,10 +6,7 @@
|
|||||||
aria-label="Help"
|
aria-label="Help"
|
||||||
>
|
>
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<button
|
<SidebarToggle />
|
||||||
class="lt"
|
|
||||||
aria-label="Toggle channel list"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h1 class="title">Help</h1>
|
<h1 class="title">Help</h1>
|
||||||
@ -659,7 +656,12 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import SidebarToggle from "../SidebarToggle.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Help",
|
name: "Help",
|
||||||
|
components: {
|
||||||
|
SidebarToggle,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -6,10 +6,7 @@
|
|||||||
aria-label="Settings"
|
aria-label="Settings"
|
||||||
>
|
>
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<button
|
<SidebarToggle />
|
||||||
class="lt"
|
|
||||||
aria-label="Toggle channel list"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<form
|
<form
|
||||||
ref="settingsForm"
|
ref="settingsForm"
|
||||||
@ -505,12 +502,14 @@
|
|||||||
import socket from "../../js/socket";
|
import socket from "../../js/socket";
|
||||||
import RevealPassword from "../RevealPassword.vue";
|
import RevealPassword from "../RevealPassword.vue";
|
||||||
import Session from "../Session.vue";
|
import Session from "../Session.vue";
|
||||||
|
import SidebarToggle from "../SidebarToggle.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Settings",
|
name: "Settings",
|
||||||
components: {
|
components: {
|
||||||
RevealPassword,
|
RevealPassword,
|
||||||
Session,
|
Session,
|
||||||
|
SidebarToggle,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -10,9 +10,7 @@ const {vueApp, findChannel} = require("./vue");
|
|||||||
|
|
||||||
window.vueMounted = () => {
|
window.vueMounted = () => {
|
||||||
require("./socket-events");
|
require("./socket-events");
|
||||||
const slideoutMenu = require("./slideout");
|
|
||||||
const contextMenuFactory = require("./contextMenuFactory");
|
const contextMenuFactory = require("./contextMenuFactory");
|
||||||
const storage = require("./localStorage");
|
|
||||||
const utils = require("./utils");
|
const utils = require("./utils");
|
||||||
require("./webpush");
|
require("./webpush");
|
||||||
require("./keybinds");
|
require("./keybinds");
|
||||||
@ -20,40 +18,6 @@ window.vueMounted = () => {
|
|||||||
const sidebar = $("#sidebar, #footer");
|
const sidebar = $("#sidebar, #footer");
|
||||||
const viewport = $("#viewport");
|
const viewport = $("#viewport");
|
||||||
|
|
||||||
function storeSidebarVisibility(name, state) {
|
|
||||||
storage.set(name, state);
|
|
||||||
|
|
||||||
vueApp.$emit("resize");
|
|
||||||
}
|
|
||||||
|
|
||||||
// If sidebar overlay is visible and it is clicked, close the sidebar
|
|
||||||
$("#sidebar-overlay").on("click", () => {
|
|
||||||
slideoutMenu.toggle(false);
|
|
||||||
|
|
||||||
if ($(window).outerWidth() > utils.mobileViewportPixels) {
|
|
||||||
storeSidebarVisibility("thelounge.state.sidebar", false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#windows").on("click", "button.lt", () => {
|
|
||||||
const isOpen = !slideoutMenu.isOpen();
|
|
||||||
|
|
||||||
slideoutMenu.toggle(isOpen);
|
|
||||||
|
|
||||||
if ($(window).outerWidth() > utils.mobileViewportPixels) {
|
|
||||||
storeSidebarVisibility("thelounge.state.sidebar", isOpen);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
viewport.on("click", ".rt", function() {
|
|
||||||
const isOpen = !viewport.hasClass("userlist-open");
|
|
||||||
|
|
||||||
viewport.toggleClass("userlist-open", isOpen);
|
|
||||||
storeSidebarVisibility("thelounge.state.userlist", isOpen);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
viewport.on("contextmenu", ".network .chan", function(e) {
|
viewport.on("contextmenu", ".network .chan", function(e) {
|
||||||
return contextMenuFactory.createContextMenu($(this), e).show();
|
return contextMenuFactory.createContextMenu($(this), e).show();
|
||||||
});
|
});
|
||||||
@ -138,8 +102,8 @@ window.vueMounted = () => {
|
|||||||
|
|
||||||
socket.emit("open", channel ? channel.channel.id : null);
|
socket.emit("open", channel ? channel.channel.id : null);
|
||||||
|
|
||||||
if ($(window).outerWidth() <= utils.mobileViewportPixels) {
|
if (!keepSidebarOpen && $(window).outerWidth() <= utils.mobileViewportPixels) {
|
||||||
slideoutMenu.toggle(false);
|
vueApp.setSidebar(false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
vueApp.activeChannel = null;
|
vueApp.activeChannel = null;
|
||||||
|
@ -1,112 +1,112 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const viewport = document.getElementById("viewport");
|
|
||||||
const menu = document.getElementById("sidebar");
|
|
||||||
const sidebarOverlay = document.getElementById("sidebar-overlay");
|
|
||||||
|
|
||||||
let touchStartPos = null;
|
|
||||||
let touchCurPos = null;
|
|
||||||
let touchStartTime = 0;
|
|
||||||
let menuWidth = 0;
|
|
||||||
let menuIsOpen = false;
|
|
||||||
let menuIsMoving = false;
|
|
||||||
let menuIsAbsolute = false;
|
|
||||||
|
|
||||||
class SlideoutMenu {
|
class SlideoutMenu {
|
||||||
static enable() {
|
enable() {
|
||||||
document.body.addEventListener("touchstart", onTouchStart, {passive: true});
|
this.viewport = document.getElementById("viewport");
|
||||||
}
|
this.menu = document.getElementById("sidebar");
|
||||||
|
this.sidebarOverlay = document.getElementById("sidebar-overlay");
|
||||||
|
|
||||||
static toggle(state) {
|
this.touchStartPos = null;
|
||||||
menuIsOpen = state;
|
this.touchCurPos = null;
|
||||||
viewport.classList.toggle("menu-open", state);
|
this.touchStartTime = 0;
|
||||||
}
|
this.menuWidth = 0;
|
||||||
|
this.menuIsOpen = false;
|
||||||
|
this.menuIsMoving = false;
|
||||||
|
this.menuIsAbsolute = false;
|
||||||
|
|
||||||
static isOpen() {
|
this.onTouchStart = (e) => {
|
||||||
return menuIsOpen;
|
this.touchStartPos = this.touchCurPos = e.touches.item(0);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onTouchStart(e) {
|
|
||||||
touchStartPos = touchCurPos = e.touches.item(0);
|
|
||||||
|
|
||||||
if (e.touches.length !== 1) {
|
if (e.touches.length !== 1) {
|
||||||
onTouchEnd();
|
this.onTouchEnd();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = window.getComputedStyle(menu);
|
const styles = window.getComputedStyle(this.menu);
|
||||||
|
|
||||||
menuWidth = parseFloat(styles.width);
|
this.menuWidth = parseFloat(styles.width);
|
||||||
menuIsAbsolute = styles.position === "absolute";
|
this.menuIsAbsolute = styles.position === "absolute";
|
||||||
|
|
||||||
if (!menuIsOpen || touchStartPos.screenX > menuWidth) {
|
if (!this.menuIsOpen || this.touchStartPos.screenX > this.menuWidth) {
|
||||||
touchStartTime = Date.now();
|
this.touchStartTime = Date.now();
|
||||||
|
|
||||||
document.body.addEventListener("touchmove", onTouchMove, {passive: true});
|
document.body.addEventListener("touchmove", this.onTouchMove, {passive: true});
|
||||||
document.body.addEventListener("touchend", onTouchEnd, {passive: true});
|
document.body.addEventListener("touchend", this.onTouchEnd, {passive: true});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
function onTouchMove(e) {
|
this.onTouchMove = (e) => {
|
||||||
const touch = (touchCurPos = e.touches.item(0));
|
const touch = this.touchCurPos = e.touches.item(0);
|
||||||
let distX = touch.screenX - touchStartPos.screenX;
|
let distX = touch.screenX - this.touchStartPos.screenX;
|
||||||
const distY = touch.screenY - touchStartPos.screenY;
|
const distY = touch.screenY - this.touchStartPos.screenY;
|
||||||
|
|
||||||
if (!menuIsMoving) {
|
if (!this.menuIsMoving) {
|
||||||
// tan(45°) is 1. Gestures in 0°-45° (< 1) are considered horizontal, so
|
// tan(45°) is 1. Gestures in 0°-45° (< 1) are considered horizontal, so
|
||||||
// menu must be open; gestures in 45°-90° (>1) are considered vertical, so
|
// menu must be open; gestures in 45°-90° (>1) are considered vertical, so
|
||||||
// chat windows must be scrolled.
|
// chat windows must be scrolled.
|
||||||
if (Math.abs(distY / distX) >= 1) {
|
if (Math.abs(distY / distX) >= 1) {
|
||||||
onTouchEnd();
|
this.onTouchEnd();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const devicePixelRatio = window.devicePixelRatio || 2;
|
const devicePixelRatio = window.devicePixelRatio || 2;
|
||||||
|
|
||||||
if (Math.abs(distX) > devicePixelRatio) {
|
if (Math.abs(distX) > devicePixelRatio) {
|
||||||
viewport.classList.toggle("menu-dragging", true);
|
this.viewport.classList.toggle("menu-dragging", true);
|
||||||
menuIsMoving = true;
|
this.menuIsMoving = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do not animate the menu on desktop view
|
// Do not animate the menu on desktop view
|
||||||
if (!menuIsAbsolute) {
|
if (!this.menuIsAbsolute) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (menuIsOpen) {
|
if (this.menuIsOpen) {
|
||||||
distX += menuWidth;
|
distX += this.menuWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (distX > menuWidth) {
|
if (distX > this.menuWidth) {
|
||||||
distX = menuWidth;
|
distX = this.menuWidth;
|
||||||
} else if (distX < 0) {
|
} else if (distX < 0) {
|
||||||
distX = 0;
|
distX = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
menu.style.transform = "translate3d(" + distX + "px, 0, 0)";
|
this.menu.style.transform = "translate3d(" + distX + "px, 0, 0)";
|
||||||
sidebarOverlay.style.opacity = distX / menuWidth;
|
this.sidebarOverlay.style.opacity = distX / this.menuWidth;
|
||||||
}
|
};
|
||||||
|
|
||||||
function onTouchEnd() {
|
this.onTouchEnd = () => {
|
||||||
const diff = touchCurPos.screenX - touchStartPos.screenX;
|
const diff = this.touchCurPos.screenX - this.touchStartPos.screenX;
|
||||||
const absDiff = Math.abs(diff);
|
const absDiff = Math.abs(diff);
|
||||||
|
|
||||||
if (absDiff > menuWidth / 2 || (Date.now() - touchStartTime < 180 && absDiff > 50)) {
|
if (absDiff > this.menuWidth / 2 || Date.now() - this.touchStartTime < 180 && absDiff > 50) {
|
||||||
SlideoutMenu.toggle(diff > 0);
|
this.toggle(diff > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
document.body.removeEventListener("touchmove", onTouchMove);
|
document.body.removeEventListener("touchmove", this.onTouchMove);
|
||||||
document.body.removeEventListener("touchend", onTouchEnd);
|
document.body.removeEventListener("touchend", this.onTouchEnd);
|
||||||
viewport.classList.toggle("menu-dragging", false);
|
this.viewport.classList.toggle("menu-dragging", false);
|
||||||
menu.style.transform = null;
|
this.menu.style.transform = null;
|
||||||
sidebarOverlay.style.opacity = null;
|
this.sidebarOverlay.style.opacity = null;
|
||||||
|
|
||||||
touchStartPos = null;
|
this.touchStartPos = null;
|
||||||
touchCurPos = null;
|
this.touchCurPos = null;
|
||||||
touchStartTime = 0;
|
this.touchStartTime = 0;
|
||||||
menuIsMoving = false;
|
this.menuIsMoving = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
document.body.addEventListener("touchstart", this.onTouchStart, {passive: true});
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = SlideoutMenu;
|
toggle(state) {
|
||||||
|
this.menuIsOpen = state;
|
||||||
|
this.viewport.classList.toggle("menu-open", state);
|
||||||
|
}
|
||||||
|
|
||||||
|
isOpen() {
|
||||||
|
return this.menuIsOpen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = (new SlideoutMenu);
|
||||||
|
@ -4,7 +4,6 @@ const $ = require("jquery");
|
|||||||
const escape = require("css.escape");
|
const escape = require("css.escape");
|
||||||
const socket = require("../socket");
|
const socket = require("../socket");
|
||||||
const webpush = require("../webpush");
|
const webpush = require("../webpush");
|
||||||
const slideoutMenu = require("../slideout");
|
|
||||||
const sidebar = $("#sidebar");
|
const sidebar = $("#sidebar");
|
||||||
const storage = require("../localStorage");
|
const storage = require("../localStorage");
|
||||||
const utils = require("../utils");
|
const utils = require("../utils");
|
||||||
@ -21,7 +20,7 @@ socket.on("init", function(data) {
|
|||||||
vueApp.currentUserVisibleError = null;
|
vueApp.currentUserVisibleError = null;
|
||||||
|
|
||||||
if (!vueApp.initialized) {
|
if (!vueApp.initialized) {
|
||||||
vueApp.initialized = true;
|
vueApp.onSocketInit();
|
||||||
|
|
||||||
if (data.token) {
|
if (data.token) {
|
||||||
storage.set("token", data.token);
|
storage.set("token", data.token);
|
||||||
@ -29,14 +28,11 @@ socket.on("init", function(data) {
|
|||||||
|
|
||||||
webpush.configurePushNotifications(data.pushSubscription, data.applicationServerKey);
|
webpush.configurePushNotifications(data.pushSubscription, data.applicationServerKey);
|
||||||
|
|
||||||
slideoutMenu.enable();
|
const viewportWidth = window.outerWidth;
|
||||||
|
|
||||||
const viewport = $("#viewport");
|
|
||||||
const viewportWidth = $(window).outerWidth();
|
|
||||||
let isUserlistOpen = storage.get("thelounge.state.userlist");
|
let isUserlistOpen = storage.get("thelounge.state.userlist");
|
||||||
|
|
||||||
if (viewportWidth > utils.mobileViewportPixels) {
|
if (viewportWidth > utils.mobileViewportPixels) {
|
||||||
slideoutMenu.toggle(storage.get("thelounge.state.sidebar") !== "false");
|
vueApp.setSidebar(storage.get("thelounge.state.sidebar") !== "false");
|
||||||
}
|
}
|
||||||
|
|
||||||
// If The Lounge is opened on a small screen (less than 1024px), and we don't have stored
|
// If The Lounge is opened on a small screen (less than 1024px), and we don't have stored
|
||||||
@ -45,7 +41,7 @@ socket.on("init", function(data) {
|
|||||||
isUserlistOpen = "true";
|
isUserlistOpen = "true";
|
||||||
}
|
}
|
||||||
|
|
||||||
viewport.toggleClass("userlist-open", isUserlistOpen === "true");
|
vueApp.setUserlist(isUserlistOpen === "true");
|
||||||
|
|
||||||
$(document.body).removeClass("signed-out");
|
$(document.body).removeClass("signed-out");
|
||||||
$("#loading").remove();
|
$("#loading").remove();
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import Vue from "vue";
|
import Vue from "vue";
|
||||||
import Vuex from "vuex";
|
import Vuex from "vuex";
|
||||||
|
const storage = require("./localStorage");
|
||||||
|
|
||||||
Vue.use(Vuex);
|
Vue.use(Vuex);
|
||||||
|
|
||||||
@ -9,6 +10,8 @@ export default new Vuex.Store({
|
|||||||
isNotified: false,
|
isNotified: false,
|
||||||
activeWindow: null,
|
activeWindow: null,
|
||||||
sessions: [],
|
sessions: [],
|
||||||
|
sidebarOpen: false,
|
||||||
|
userlistOpen: storage.get("thelounge.state.userlist") !== "false",
|
||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
isConnected(state, payload) {
|
isConnected(state, payload) {
|
||||||
@ -26,6 +29,12 @@ export default new Vuex.Store({
|
|||||||
sessions(state, payload) {
|
sessions(state, payload) {
|
||||||
state.sessions = payload;
|
state.sessions = payload;
|
||||||
},
|
},
|
||||||
|
sidebarOpen(state, payload) {
|
||||||
|
state.sidebarOpen = payload;
|
||||||
|
},
|
||||||
|
userlistOpen(state, payload) {
|
||||||
|
state.userlistOpen = payload;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {
|
||||||
currentSession: (state) => state.sessions.find((item) => item.current),
|
currentSession: (state) => state.sessions.find((item) => item.current),
|
||||||
|
@ -7,6 +7,8 @@ const roundBadgeNumber = require("./libs/handlebars/roundBadgeNumber");
|
|||||||
const localetime = require("./libs/handlebars/localetime");
|
const localetime = require("./libs/handlebars/localetime");
|
||||||
const friendlysize = require("./libs/handlebars/friendlysize");
|
const friendlysize = require("./libs/handlebars/friendlysize");
|
||||||
const colorClass = require("./libs/handlebars/colorClass");
|
const colorClass = require("./libs/handlebars/colorClass");
|
||||||
|
const slideoutMenu = require("../js/slideout");
|
||||||
|
const storage = require("./localStorage");
|
||||||
|
|
||||||
Vue.filter("localetime", localetime);
|
Vue.filter("localetime", localetime);
|
||||||
Vue.filter("friendlysize", friendlysize);
|
Vue.filter("friendlysize", friendlysize);
|
||||||
@ -48,6 +50,38 @@ const vueApp = new Vue({
|
|||||||
mounted() {
|
mounted() {
|
||||||
Vue.nextTick(() => window.vueMounted());
|
Vue.nextTick(() => window.vueMounted());
|
||||||
},
|
},
|
||||||
|
methods: {
|
||||||
|
onSocketInit() {
|
||||||
|
this.initialized = true;
|
||||||
|
this.$store.commit("isConnected", true);
|
||||||
|
|
||||||
|
// TODO: handle slideut in vue
|
||||||
|
slideoutMenu.enable();
|
||||||
|
},
|
||||||
|
setSidebar(state) {
|
||||||
|
const utils = require("./utils");
|
||||||
|
|
||||||
|
this.$store.commit("sidebarOpen", state);
|
||||||
|
slideoutMenu.toggle(false);
|
||||||
|
|
||||||
|
if (window.outerWidth > utils.mobileViewportPixels) {
|
||||||
|
storage.set("thelounge.state.sidebar", state);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$emit("resize");
|
||||||
|
},
|
||||||
|
toggleSidebar() {
|
||||||
|
this.setSidebar(!this.$store.state.sidebarOpen);
|
||||||
|
},
|
||||||
|
setUserlist(state) {
|
||||||
|
storage.set("thelounge.state.userlist", state);
|
||||||
|
this.$store.commit("userlistOpen", state);
|
||||||
|
this.$emit("resize");
|
||||||
|
},
|
||||||
|
toggleUserlist() {
|
||||||
|
this.setUserlist(!this.$store.state.userlistOpen);
|
||||||
|
},
|
||||||
|
},
|
||||||
render(createElement) {
|
render(createElement) {
|
||||||
return createElement(App, {
|
return createElement(App, {
|
||||||
ref: "app",
|
ref: "app",
|
||||||
|
Loading…
Reference in New Issue
Block a user