mirror of
https://github.com/danbulant/Nertivia-Client
synced 2026-06-15 04:21:19 +00:00
417 lines
9.7 KiB
Vue
417 lines
9.7 KiB
Vue
<template>
|
|
<div id="app" ref="app">
|
|
<vue-headful :title="title" description="Nertivia Chat Client"/>
|
|
<div class="background-image halloween-background"></div>
|
|
<transition name="fade-between-two" appear>
|
|
<ConnectingScreen v-if="!loggedIn"/>
|
|
<div class="box" v-if="loggedIn">
|
|
<div class="frame">
|
|
<div class="tabs">
|
|
|
|
<div :class="`tab ${currentTab === 0 ? 'selected' : ''}`" @click="switchTab(0)">
|
|
<i class="material-icons">explore</i>
|
|
Explore
|
|
</div>
|
|
|
|
<div :class="{tab: true, selected: currentTab === 1, notifyAnimation: DMNotification || friendRequestExists}" @click="switchTab(1)">
|
|
<i class="material-icons">chat</i>
|
|
Direct Message
|
|
</div>
|
|
|
|
<div :class="{tab: true, selected: currentTab === 2, notifyAnimation: serverNotification}" @click="switchTab(2)">
|
|
<i class="material-icons">forum</i>
|
|
Servers
|
|
</div>
|
|
|
|
<div :class="`tab ${currentTab === 3 ? 'selected' : ''}`" @click="switchTab(3)">
|
|
<i class="material-icons">list_alt</i>
|
|
Changelog
|
|
</div>
|
|
|
|
|
|
<!-- <div :class="`tab ${currentTab === 4 ? 'selected' : ''}`" @click="switchTab(4)">
|
|
<i class="material-icons">info</i>
|
|
Ad
|
|
</div> -->
|
|
</div>
|
|
<div class="window-buttons" v-if="isElectron">
|
|
<electron-frame-buttons />
|
|
</div>
|
|
|
|
</div>
|
|
<div class="panel-layout">
|
|
<news v-if="currentTab == 3"/>
|
|
<direct-message v-if="currentTab == 1"/>
|
|
<servers v-if="currentTab == 2"/>
|
|
<explore v-if="currentTab == 0"/>
|
|
</div>
|
|
</div>
|
|
</transition>
|
|
<Popouts v-if="loggedIn"/>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import { bus } from "../main";
|
|
import Popouts from "@/components/app/Popouts/Popouts.vue";
|
|
import windowProperties from "@/utils/windowProperties";
|
|
import changelog from "@/utils/changelog.js";
|
|
import ConnectingScreen from "./../components/app/ConnectingScreen.vue";
|
|
import Spinner from "./../components/Spinner.vue";
|
|
|
|
|
|
const ElectronFrameButtons = () =>
|
|
import("@/components/ElectronJS/FrameButtons.vue");
|
|
|
|
const News = () =>
|
|
import(/* webpackChunkName: "News" */ "./../components/app/Tabs/News.vue");
|
|
|
|
const DirectMessage = () => ({
|
|
component: import("./../components/app/Tabs/DirectMessage.vue"),
|
|
loading: Spinner,
|
|
delay: 0
|
|
});
|
|
|
|
const Servers = () => ({
|
|
component: import("./../components/app/Tabs/Servers.vue"),
|
|
loading: Spinner,
|
|
delay: 0
|
|
});
|
|
|
|
const Explore = () => ({
|
|
component: import("./../components/app/Tabs/Explore.vue"),
|
|
loading: Spinner,
|
|
delay: 0
|
|
});
|
|
|
|
export default {
|
|
name: "app",
|
|
components: {
|
|
|
|
DirectMessage,
|
|
Servers,
|
|
ConnectingScreen,
|
|
Popouts,
|
|
News,
|
|
ElectronFrameButtons,
|
|
Explore
|
|
},
|
|
data() {
|
|
return {
|
|
currentTab: 0,
|
|
title: "Nertivia",
|
|
isElectron: window && window.process && window.process.type
|
|
};
|
|
},
|
|
methods: {
|
|
|
|
dismissNotification (channelID) {
|
|
const notifications = this.$store.getters.notifications.find(function(e) {
|
|
return e.channelID === channelID
|
|
})
|
|
|
|
if (notifications && notifications.count >= 1 && document.hasFocus()) {
|
|
this.$socket.emit('notification:dismiss', {channelID});
|
|
}
|
|
},
|
|
switchChannel(isServer) {
|
|
const serverChannelID = this.$store.state.channelModule.serverChannelID;
|
|
const DMChannelID = this.$store.state.channelModule.DMChannelID;
|
|
|
|
if (isServer) {
|
|
this.$store.dispatch('selectedChannelID', serverChannelID)
|
|
const channel = this.$store.state.channelModule.channels[serverChannelID];
|
|
this.$store.dispatch("setChannelName", channel ? channel.name : "")
|
|
this.dismissNotification(serverChannelID)
|
|
} else {
|
|
const channel = this.$store.state.channelModule.channels[DMChannelID];
|
|
this.$store.dispatch("setChannelName", channel ? channel.recipients[0].username : "");
|
|
this.$store.dispatch('selectedChannelID', DMChannelID)
|
|
this.dismissNotification(DMChannelID)
|
|
}
|
|
|
|
},
|
|
switchTab(index) {
|
|
localStorage.setItem("currentTab", index);
|
|
this.currentTab = index;
|
|
if (index == 1) { //1: direct message tab.
|
|
this.switchChannel(false)
|
|
} else if (index === 2) { //2: server tab
|
|
this.switchChannel(true)
|
|
}
|
|
},
|
|
resizeEvent(dimensions) {
|
|
const width = dimensions.width;
|
|
const height = dimensions.height;
|
|
this.$refs.app.style.height = height + 'px';
|
|
this.$refs.app.style.width = width + 'px';
|
|
}
|
|
},
|
|
watch: {
|
|
getWindowWidth(dimensions) {
|
|
this.resizeEvent(dimensions)
|
|
}
|
|
},
|
|
mounted() {
|
|
|
|
const currentTab = localStorage.getItem("currentTab");
|
|
if(currentTab) {
|
|
this.currentTab = parseInt(currentTab);
|
|
}
|
|
// check if changelog is updated
|
|
const seenVersion = localStorage.getItem("changelog-version-seen");
|
|
if (seenVersion && seenVersion < changelog[0].version) {
|
|
localStorage.setItem("currentTab", 3);
|
|
this.currentTab = 3;
|
|
}
|
|
localStorage.setItem("changelog-version-seen", changelog[0].version);
|
|
bus.$on("title:change", title => {
|
|
this.title = title;
|
|
});
|
|
|
|
bus.$on('changeTab', this.switchTab)
|
|
},
|
|
destroyed() {
|
|
bus.$off('changeTab', this.switchTab)
|
|
},
|
|
computed: {
|
|
loggedIn() {
|
|
return this.$store.getters.loggedIn;
|
|
},
|
|
serverNotification() {
|
|
const notifications = this.$store.getters.notifications;
|
|
const channels = this.$store.getters.channels
|
|
const notification = notifications.find(e => {
|
|
return channels[e.channelID] && channels[e.channelID].server_id && e.channelID !== this.$store.getters.selectedChannelID
|
|
})
|
|
return notification;
|
|
},
|
|
DMNotification() {
|
|
const notifications = this.$store.getters.notifications;
|
|
const channels = this.$store.getters.channels
|
|
const notification = notifications.find(e => {
|
|
return channels[e.channelID] && !channels[e.channelID].server_id && e.channelID !== this.$store.getters.selectedChannelID
|
|
})
|
|
// unopened dm
|
|
if (!notification) {
|
|
return notifications.find(e => {
|
|
return !channels[e.channelID]
|
|
})
|
|
}
|
|
return notification;
|
|
},
|
|
friendRequestExists() {
|
|
const allFriend = this.$store.getters.user.friends;
|
|
const result = Object.keys(allFriend).map(function(key) {
|
|
return allFriend[key];
|
|
});
|
|
return result.find(friend => friend.status === 1);
|
|
},
|
|
getWindowWidth() {
|
|
return {width: windowProperties.resizeWidth, height: windowProperties.resizeHeight};
|
|
},
|
|
}
|
|
};
|
|
</script>
|
|
|
|
|
|
<style scoped>
|
|
#app {
|
|
position: fixed;
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
.notifyAnimation{
|
|
animation: notifyAnime;
|
|
animation-duration: 1s;
|
|
animation-iteration-count: infinite;
|
|
animation-fill-mode: forwards;
|
|
}
|
|
.box {
|
|
display: flex;
|
|
flex-direction: column;
|
|
height: 100%;
|
|
width: 100%;
|
|
}
|
|
@keyframes notifyAnime {
|
|
0%{
|
|
background: rgba(121, 3, 3, 0.541);
|
|
}
|
|
40%{
|
|
background: rgba(255, 0, 0, 0.568);
|
|
}
|
|
60%{
|
|
background: rgba(255, 0, 0, 0.568);
|
|
}
|
|
100%{
|
|
background: rgba(121, 3, 3, 0.541);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.coming-soon {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
flex-direction: column;
|
|
width: 100%;
|
|
height: 100%;
|
|
background: rgba(0, 0, 0, 0.39);
|
|
color: white;
|
|
}
|
|
|
|
.coming-soon .material-icons {
|
|
font-size: 100px;
|
|
}
|
|
|
|
.direct-message-tab {
|
|
position: relative;
|
|
display: flex;
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
.frame {
|
|
display: flex;
|
|
-webkit-app-region: drag;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.window-buttons {
|
|
position: relative;
|
|
min-width: 175px;
|
|
flex: 1;
|
|
}
|
|
|
|
.tabs {
|
|
display: flex;
|
|
overflow-y: hidden;
|
|
overflow-x: auto;
|
|
max-width: 500px;
|
|
flex-basis: auto; /* default value */
|
|
flex-grow: 1;
|
|
}
|
|
|
|
.tabs::-webkit-scrollbar {
|
|
height: 5px;
|
|
}
|
|
.tabs {
|
|
scrollbar-width: thin;
|
|
}
|
|
|
|
.tab {
|
|
flex-shrink: 0;
|
|
margin-bottom: 0;
|
|
background: rgba(0, 0, 0, 0.253);
|
|
color: rgba(255, 255, 255, 0.822);
|
|
padding: 10px;
|
|
padding-left: 14px;
|
|
padding-right: 14px;
|
|
cursor: default;
|
|
user-select: none;
|
|
transition: 0.3s;
|
|
-webkit-app-region: no-drag;
|
|
cursor: pointer;
|
|
position: relative;
|
|
border-right:solid 1px rgba(0, 0, 0, 0.5);
|
|
}
|
|
|
|
.tab:hover {
|
|
background: rgba(0, 0, 0, 0.418);
|
|
}
|
|
|
|
.tab.selected {
|
|
background: rgba(0, 0, 0, 0.671);
|
|
color: white;
|
|
}
|
|
|
|
|
|
|
|
.tab .material-icons {
|
|
font-size: 15px;
|
|
vertical-align: -2px;
|
|
}
|
|
|
|
.slidein-enter-active,
|
|
.slidein-leave-active {
|
|
transition: 0.5s;
|
|
}
|
|
.slidein-enter, .slidein-leave-to /* .fade-leave-active below version 2.1.8 */ {
|
|
margin-left: -300px;
|
|
}
|
|
|
|
.fade-between-two-enter-active,
|
|
.fade-between-two-leave-active {
|
|
transition: 0.3s;
|
|
}
|
|
.fade-between-two-enter,
|
|
.fade-between-two-leave-to {
|
|
opacity: 0 !important;
|
|
}
|
|
|
|
.fade-enter-active,
|
|
.fade-leave-active {
|
|
transition: opacity 0.2s;
|
|
}
|
|
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
|
|
opacity: 0;
|
|
}
|
|
|
|
</style>
|
|
|
|
|
|
|
|
<style>
|
|
|
|
textarea {
|
|
font-family: "Roboto", sans-serif;
|
|
}
|
|
|
|
.background-image {
|
|
background: url(./../assets/background.jpg);
|
|
position: fixed;
|
|
z-index: -1;
|
|
width: 100%;
|
|
height: 100%;
|
|
background-repeat: no-repeat;
|
|
background-position: bottom;
|
|
background-size: cover;
|
|
filter: blur(15px);
|
|
transform: scale(1.1);
|
|
}
|
|
.halloween-background {
|
|
background: url(./../assets/halloween_background.jpg);
|
|
filter: blur(10px);
|
|
|
|
background-position: center;
|
|
}
|
|
|
|
.panel-layout {
|
|
display: flex;
|
|
overflow: auto;
|
|
height: 100%;
|
|
}
|
|
|
|
input {
|
|
padding: 10px;
|
|
background: rgba(0, 0, 0, 0.301);
|
|
outline: none;
|
|
border: none;
|
|
color: white;
|
|
margin-top: 5px;
|
|
margin-bottom: 10px;
|
|
width: 200px;
|
|
transition: 0.3s;
|
|
}
|
|
|
|
input:hover {
|
|
background: rgba(0, 0, 0, 0.452);
|
|
}
|
|
|
|
input:focus {
|
|
background: rgba(0, 0, 0, 0.603);
|
|
}
|
|
</style>
|
|
|