merged server and dm tab component

This commit is contained in:
supertiger1234 2020-02-17 17:52:49 +00:00
parent 7f527a8627
commit fabbdc57c0
17 changed files with 419 additions and 555 deletions

View file

@ -1,62 +1,61 @@
<template>
<div class="left-panel">
<navigation />
<div class="content">
<MyMiniInformation />
<div class="tabs">
<div
class="tab"
:class="{ notify: friendRequestExists, selected: currentTab === 0 }"
@click="currentTab = 0"
>
<div class="material-icons">group</div>
Friends
</div>
<div
class="tab"
:class="{ notify: DMNotification, selected: currentTab === 1 }"
@click="currentTab = 1"
>
<div class="material-icons">access_time</div>
Recents
</div>
</div>
<div v-if="currentTab === 0" class="list">
<pending-friends />
<online-friends />
<offline-friends />
</div>
<div v-else class="list">
<recent-friends />
<div class="friend-left-panel">
<!-- <navigation /> -->
<MyMiniInformation />
<div class="tabs">
<div
class="tab"
:class="{ notify: friendRequestExists, selected: currentTab === 0 }"
@click="currentTab = 0"
>
<div class="material-icons">group</div>
Friends
</div>
<div
class="button"
:class="{ selected: uniqueIDSelected }"
@click="saveNotesBtn"
class="tab"
:class="{ notify: DMNotification, selected: currentTab === 1 }"
@click="currentTab = 1"
>
<div class="material-icons">notes</div>
<div class="name">Saved Notes</div>
<div class="material-icons">access_time</div>
Recents
</div>
</div>
<div v-if="currentTab === 0" class="list">
<!-- <pending-friends />
<online-friends />
<offline-friends /> -->
<friends-tab />
</div>
<div v-else class="list">
<recent-friends-tab />
</div>
<div
class="button"
:class="{ selected: uniqueIDSelected }"
@click="saveNotesBtn"
>
<div class="material-icons">notes</div>
<div class="name">Saved Notes</div>
</div>
</div>
</template>
<script>
import MyMiniInformation from "../../components/app/MyMiniInformation.vue";
import PendingFriends from "./relationships/PendingFriends.vue";
import OnlineFriends from "./relationships/OnlineFriends.vue";
import OfflineFriends from "./relationships/OfflineFriends.vue";
import RecentFriends from "./relationships/RecentFriends.vue";
import Navigation from "@/components/app/Navigation";
// import PendingFriends from "./relationships/PendingFriends.vue";
// import OnlineFriends from "./relationships/OnlineFriends.vue";
// import OfflineFriends from "./relationships/OfflineFriends.vue";
import RecentFriendsTab from "./relationships/RecentFriendsTab.vue";
import FriendsTab from "./relationships/FriendsTab.vue";
export default {
components: {
MyMiniInformation,
PendingFriends,
OnlineFriends,
OfflineFriends,
RecentFriends,
Navigation
// PendingFriends,
// OnlineFriends,
// OfflineFriends,
FriendsTab,
RecentFriendsTab
},
data() {
return {
@ -119,23 +118,17 @@ export default {
};
</script>
<style scoped lang="scss">
.left-panel {
.friend-left-panel {
height: 100%;
width: 340px;
max-width: calc(100% - 60px);
width: 100%;
flex-shrink: 0;
display: flex;
flex-direction: row;
z-index: 1;
}
.content {
display: flex;
flex-direction: column;
flex-shrink: 0;
z-index: 1;
flex: 1;
overflow: hidden;
background: rgba(0, 0, 0, 0.14);
border-top-left-radius: 10px;
overflow: hidden;
}
.list {
flex: 1;
@ -165,7 +158,7 @@ export default {
cursor: pointer;
position: relative;
}
.tab:hover{
.tab:hover {
color: white;
}
.tab.selected {
@ -259,7 +252,7 @@ export default {
}
@media (max-width: 600px) {
.content {
.friend-left-panel {
border-radius: 0;
}
}

View file

@ -1,5 +1,5 @@
<template>
<div class="navigation" ref="navigation">
<div class="main navigation" ref="navigation">
<div
class="tool-tip"
ref="toolTip"

View file

@ -167,7 +167,6 @@ export default {
width: 300px;
max-width: calc(100% - 60px);
height: 100%;
background: rgba(0, 0, 0, 0.14);
}
.header {
height: 50px;

View file

@ -125,16 +125,15 @@ export default {
margin-right: 10px;
margin-left: 5px;
flex-shrink: 0;
transition: 0.3s;
transition: background-color 0.2s, box-shadow 0.2s;
}
.clickable {
color: white;
transition: 0.3s;
cursor: default;
color: rgba(255, 255, 255, 0.9);
transition: 0.2s;
cursor: pointer;
}
.clickable:hover {
color: rgb(219, 219, 219);
text-decoration: underline;
color: white;
}
@media (max-width: 949px) {

View file

@ -1,35 +1,33 @@
<template>
<div class="left-panel">
<navigation />
<div class="right">
<MyMiniInformation />
<div
class="server-banner"
@mouseenter="bannerHover = true"
@mouseleave="bannerHover = false"
:class="{ extendBanner: server && server.banner }"
v-if="selectedServerID"
>
<img
class="banner-image"
@click="bannerImageClicked"
v-if="server && server.banner"
:src="
`${bannerDomain}${server.banner}${bannerHover ? '' : '?type=webp'}`
"
/>
<div class="sub-banner">
<div class="text" :title="servers[selectedServerID].name">
{{ servers[selectedServerID].name }}
</div>
<div class="options-button material-icons" @click="openServerContext">
more_vert
</div>
<div class="server-left-panel">
<!-- <navigation /> -->
<MyMiniInformation />
<div
class="server-banner"
@mouseenter="bannerHover = true"
@mouseleave="bannerHover = false"
:class="{ extendBanner: server && server.banner }"
v-if="selectedServerID"
>
<img
class="banner-image"
@click="bannerImageClicked"
v-if="server && server.banner"
:src="
`${bannerDomain}${server.banner}${bannerHover ? '' : '?type=webp'}`
"
/>
<div class="sub-banner">
<div class="text" :title="servers[selectedServerID].name">
{{ servers[selectedServerID].name }}
</div>
<div class="options-button material-icons" @click="openServerContext">
more_vert
</div>
</div>
<div class="channels-list">
<channels-list v-if="selectedServerID" :server-i-d="selectedServerID" />
</div>
</div>
<div class="channels-list">
<channels-list v-if="selectedServerID" :server-i-d="selectedServerID" />
</div>
</div>
</template>
@ -37,14 +35,12 @@
<script>
import MyMiniInformation from "@/components/app/MyMiniInformation.vue";
import ChannelsList from "@/components/app/ServerTemplate/ChannelsList.vue";
import Navigation from "@/components/app/Navigation.vue";
import config from "@/config";
export default {
components: {
MyMiniInformation,
ChannelsList,
Navigation
ChannelsList
},
data() {
return {
@ -120,22 +116,17 @@ export default {
</script>
<style scoped lang="scss">
.left-panel {
.server-left-panel {
height: 100%;
width: 340px;
max-width: calc(100% - 60px);
width: 100%;
flex-shrink: 0;
display: flex;
flex-direction: row;
flex-direction: column;
z-index: 1;
}
.seperater {
height: 1px;
width: calc(100% - 10px);
align-self: center;
background-color: #a0c8d5;
flex-shrink: 0;
flex: 1;
background: rgba(0, 0, 0, 0.14);
overflow: hidden;
border-top-left-radius: 10px;
}
.channels-list {
@ -144,17 +135,6 @@ export default {
height: 100%;
overflow: auto;
}
.right {
display: flex;
flex-direction: column;
flex: 1;
width: 100%;
height: 100%;
overflow: hidden;
background: rgba(0, 0, 0, 0.14);
border-top-left-radius: 10px;
}
.server-banner {
display: flex;
overflow: hidden;
@ -228,7 +208,7 @@ export default {
}
@media (max-width: 600px) {
.right {
.server-left-panel {
border-radius: 0;
}
}

View file

@ -1,85 +0,0 @@
<template>
<div class="direct-message-tab" :class="{ darken: showLeftPanel }">
<transition name="slidein">
<friends-list
v-show="($mq === 'mobile' && showLeftPanel) || $mq !== 'mobile'"
v-click-outside="hideLeftPanel"
class="left-panel"
/>
</transition>
<message-panel :type="0" />
</div>
</template>
<script>
import { bus } from "@/main";
import FriendsList from "@/components/app/FriendsList.vue";
import MessagePanel from "@/components/app/MessagePanel.vue";
export default {
components: {
FriendsList,
MessagePanel
},
data() {
return {
showLeftPanel: false
};
},
mounted() {
bus.$on("toggleLeftMenu", () => {
this.showLeftPanel = !this.showLeftPanel;
});
bus.$on("closeLeftMenu", () => {
this.showLeftPanel = false;
});
},
methods: {
hideLeftPanel(event) {
if (this.showLeftPanel) {
if (event.target.closest(".show-menu-button") == null) {
this.showLeftPanel = false;
}
}
}
}
};
</script>
<style scoped>
.direct-message-tab {
overflow: hidden;
height: 100%;
width: 100%;
}
.left-panel {
z-index: 2;
}
.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; */
transform: translateX(-340px);
}
@media (max-width: 600px) {
.left-panel {
position: absolute;
bottom: 0;
z-index: 2;
background: linear-gradient(to bottom, #00477e 0, #016dc0);
}
.darken::after {
content: "";
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
z-index: 1;
background: rgba(0, 0, 0, 0.4);
}
}
</style>

View file

@ -371,6 +371,9 @@ export default {
background: linear-gradient(to bottom, #00477e 0, #016dc0);
height: 100%;
}
.left-panel .content {
border-radius: 0;
}
.darken::after {
content: "";
position: absolute;
@ -382,4 +385,5 @@ export default {
background: rgba(0, 0, 0, 0.4);
}
}
</style>

View file

@ -3,18 +3,23 @@
class="direct-message-tab"
:class="{ darken: showLeftPanel || showMembersPanel }"
>
<transition name="slide-left">
<server-list
<transition :name="$mq === 'mobile' ? 'slide-left' : null">
<div
class="left-panel"
v-show="($mq === 'mobile' && showLeftPanel) || $mq !== 'mobile'"
v-click-outside="hideLeftPanel"
class="left-panel"
/>
>
<navigation />
<server-list v-if="currentTab === 2" />
<friends-list v-if="currentTab === 1" />
</div>
</transition>
<message-panel :type="1" />
<message-panel :type="currentTab === 1 ? 0 : currentTab === 2 ? 1 : null" />
<transition :name="$mq !== 'desktop' ? 'slide-right' : 'none'">
<members-list
v-if="
selectedServerID &&
currentTab === 2 &&
((($mq === 'members_panel' || $mq === 'mobile') &&
showMembersPanel) ||
$mq === 'desktop')
@ -28,16 +33,20 @@
<script>
import { bus } from "@/main";
import ServerList from "@/components/app/ServerList.vue";
import MessagePanel from "@/components/app/MessagePanel.vue";
import MembersList from "@/components/app/MembersList.vue";
import Navigation from "@/components/app/Navigation.vue";
const FriendsList = () => import("@/components/app/FriendsList.vue");
const MembersList = () => import("@/components/app/MembersList.vue");
const ServerList = () => import("@/components/app/ServerList.vue");
export default {
components: {
ServerList,
FriendsList,
MessagePanel,
MembersList
MembersList,
Navigation
},
data() {
return {
@ -59,7 +68,9 @@ export default {
methods: {
hideLeftPanel(event) {
if (this.showLeftPanel) {
if (event.target.closest(".show-menu-button") == null) {
const closestMenuBtn = event.target.closest(".show-menu-button");
const closestNavBtn = event.target.closest(".main.navigation");
if (closestMenuBtn === null && closestNavBtn === null) {
this.showLeftPanel = false;
}
}
@ -73,6 +84,9 @@ export default {
}
},
computed: {
currentTab() {
return this.$store.getters.currentTab;
},
selectedServerID() {
return this.$store.getters["servers/selectedServerID"];
}
@ -86,6 +100,13 @@ export default {
}
.left-panel {
z-index: 2;
height: 100%;
width: 340px;
max-width: calc(100% - 60px);
flex-shrink: 0;
display: flex;
flex-direction: row;
z-index: 1;
}
.slide-left-enter-active,

View file

@ -0,0 +1,181 @@
<template>
<div class="friends">
<virtual-list :size="50" :remain="15" v-if="loaded" :variable="true">
<div class="tab" v-if="friends[0].length" :style="{ height: '25px' }">
Pending
</div>
<pending-template
v-for="friend of friends[0]"
:key="friend.recipient.uniqueID"
:friend="friend"
:style="{ height: '55px' }"
/>
<div class="tab" v-if="friends[1].length || friends[2].length">
Online
</div>
<div
class="none-online"
:style="{ height: '29px' }"
v-if="!friends[1].length && friends[2].length"
>
All of your friends are offline.
</div>
<friends-template
v-for="friend of friends[1]"
:key="friend.recipient.uniqueID"
:friend="friend"
:recipient="friend.recipient"
:style="{ height: '50px' }"
/>
<div class="tab">Offline</div>
<div
class="none-online"
:style="{ height: '29px' }"
v-if="!friends[2].length && !friends[1].length"
>
Add some friends.
</div>
<friends-template
v-for="friend of friends[2]"
:key="friend.recipient.uniqueID"
:friend="friend"
:recipient="friend.recipient"
:style="{ height: '50px' }"
/>
</virtual-list>
</div>
</template>
<script>
import VirtualList from "vue-virtual-scroll-list";
import FriendsTemplate from "./FriendsTemplate.vue";
import PendingTemplate from "./PendingTemplate.vue";
export default {
components: {
FriendsTemplate,
PendingTemplate,
VirtualList
},
data() {
return {
loaded: false
};
},
mounted() {
setTimeout(() => (this.loaded = true));
},
computed: {
user() {
return this.$store.getters.user;
},
channels() {
const json = this.$store.getters.channels;
const notifications = this.$store.getters.notifications;
const keys = Object.keys(json);
let result = [];
keys.forEach(key => {
if (
json[key].recipients &&
json[key].recipients.length > 0 &&
!json[key].server_id &&
json[key].recipients[0].uniqueID !== this.user.uniqueID
)
result.push(json[key]);
});
result.sort(function(a, b) {
const notificationA = notifications.find(item => {
return item.channelID === a.channelID;
});
const notificationB = notifications.find(item => {
return item.channelID === b.channelID;
});
// make notifications more prority.
if (notificationA) return -1;
if (notificationB) return 1;
if (a.lastMessaged === undefined) return 1;
if (b.lastMessaged === undefined) return -1;
return b.lastMessaged - a.lastMessaged;
});
// gets unopened dms
const notificationsFiltered = notifications.filter(item => {
if (json[item.channelID] && json[item.channelID].server_id) return;
const find = result.find(resFind => {
return resFind.channelID === item.channelID;
});
if (!find) {
return true;
}
});
for (let index in notificationsFiltered) {
notificationsFiltered[index].creator = "dummy";
notificationsFiltered[index].recipients = [
notificationsFiltered[index].sender
];
}
result = notificationsFiltered.concat(result);
return result;
},
friends() {
const allFriends = Object.values(this.$store.getters.user.friends);
const members = this.$store.getters["members/members"];
const presences = this.$store.getters["members/presences"];
let pendingFriends = [];
let onlineFriends = [];
let offlineFriends = [];
for (let index = 0; index < allFriends.length; index++) {
let friend = allFriends[index];
const presence = presences[friend.uniqueID];
friend.recipient = members[friend.uniqueID];
if (friend.status < 2) {
pendingFriends.push(friend);
continue;
}
if (!presence || presence === 0) {
offlineFriends.push(friend);
continue;
}
onlineFriends.push(friend);
}
return [pendingFriends, onlineFriends, offlineFriends];
}
}
};
</script>
<style scoped>
.friends {
background-color: rgba(0, 0, 0, 0);
user-select: none;
transition: 0.3s;
display: flex;
flex-direction: column;
height: 100%;
flex-shrink: 0;
overflow: hidden;
}
.tab {
display: flex;
align-items: center;
height: 25px;
color: rgba(255, 255, 255, 0.9);
padding-left: 10px;
}
.none-online {
color: rgba(255, 255, 255, 0.7);
align-self: center;
padding: 5px;
text-align: center;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.spacer {
display: flex;
height: 5px;
}
</style>

View file

@ -1,36 +1,38 @@
<template>
<div
class="friend"
:class="{ selected: uniqueIDSelected, tree }"
@click="openChat"
@mouseover="mouseOverEvent"
@mouseleave="hover = false"
>
<div class="friend">
<div
class="profile-picture"
:style="`border-color: ${status.statusColor};`"
@click="openUserInformation"
class="wrapper"
:class="{ selected: uniqueIDSelected }"
@click="openChat"
@mouseover="mouseOverEvent"
@mouseleave="hover = false"
>
<img
class="avatar"
:src="`${userAvatar}${hover || !isGif ? '' : '?type=webp'}`"
/>
<div
class="status"
:style="`background-image: url(${status.statusURL})`"
/>
</div>
<div class="information">
<div class="username">{{ recipient.username }}</div>
<div class="status-name">{{ status.statusName }}</div>
</div>
<div v-if="notifications && notifications > 0" class="notification">
<div class="notification-inner">{{ notifications }}</div>
</div>
<!-- doesnt work properly. if both channels closed, the chat gets wiped. -->
<!-- <div v-else-if="recents" class="material-icons close-button" @click="closeChannel">
class="profile-picture"
:style="`border-color: ${status.statusColor};`"
@click="openUserInformation"
>
<img
class="avatar"
:src="`${userAvatar}${hover || !isGif ? '' : '?type=webp'}`"
/>
<div
class="status"
:style="`background-image: url(${status.statusURL})`"
/>
</div>
<div class="information">
<div class="username">{{ recipient.username }}</div>
<div class="status-name">{{ status.statusName }}</div>
</div>
<div v-if="notifications && notifications > 0" class="notification">
<div class="notification-inner">{{ notifications }}</div>
</div>
<!-- doesnt work properly. if both channels closed, the chat gets wiped. -->
<!-- <div v-else-if="recents" class="material-icons close-button" @click="closeChannel">
close
</div> -->
</div>
</div>
</template>
@ -41,16 +43,7 @@ import statuses from "@/utils/statuses";
import { bus } from "@/main";
export default {
// tree will add padding to the left.
props: [
"username",
"tag",
"channelID",
"uniqueID",
"recipient",
"tree",
"recents"
],
props: ["friend", "recents", "recipient"],
data() {
return {
hover: false,
@ -62,15 +55,18 @@ export default {
},
computed: {
notifications() {
const channelID = this.$props.channelID;
const channels = this.$store.getters.channels;
const recipient = this.recipient;
const notifications = this.$store.getters.notifications.find(function(e) {
if (channels[e.channelID] && channels[e.channelID].server_id) return;
return e.channelID == channelID;
const channel = channels[e.channelID];
if (channel && channel.server_id) return;
return e.sender.uniqueID === recipient.uniqueID;
});
if (
!notifications ||
(this.$props.channelID === this.$store.getters.selectedChannelID &&
(this.friend.channelID === this.$store.getters.selectedChannelID &&
document.hasFocus())
)
return;
@ -107,8 +103,7 @@ export default {
}
},
async closeChannel() {
this.channelID;
await channelService.delete(this.channelID);
await channelService.delete(this.friend.channelID);
},
async openChat(event) {
if (
@ -125,12 +120,12 @@ export default {
document.hasFocus()
) {
this.$socket.client.emit("notification:dismiss", {
channelID: this.channelID
channelID: this.friend.channelID
});
}
this.$store.dispatch("openChat", {
uniqueID: this.recipient.uniqueID,
channelID: this.channelID,
channelID: this.friend.channelID,
channelName: this.recipient.username
});
},
@ -149,26 +144,32 @@ export default {
text-overflow: ellipsis;
}
.friend {
color: rgba(255, 255, 255, 0.7);
padding: 5px;
height: 50px;
flex-shrink: 0;
display: flex;
height: 34px;
align-items: center;
width: 100%;
}
.wrapper {
color: rgba(255, 255, 255, 0.7);
display: flex;
height: 45px;
width: 100%;
transition: 0.3s;
position: relative;
overflow: hidden;
cursor: pointer;
margin: 5px;
border-radius: 4px;
}
.tree {
padding-left: 22px;
padding-left: 10px;
margin-left: 3px;
margin-right: 3px;
}
.friend:hover {
.wrapper:hover {
background-color: rgba(0, 0, 0, 0.2);
color: white;
}
.friend.selected {
.wrapper.selected {
background-color: rgba(0, 0, 0, 0.4);
color: white;
}
@ -227,7 +228,7 @@ export default {
transition: 0.3s;
}
.friend:hover .status {
.wrapper:hover .status {
opacity: 1;
bottom: -4px;
}
@ -239,7 +240,7 @@ export default {
color: #b7cbce;
height: 0;
}
.friend:hover .status-name {
.wrapper:hover .status-name {
opacity: 1;
height: 13px;
}
@ -256,7 +257,7 @@ export default {
.close-button:hover {
color: white;
}
.friend:hover .close-button {
.wrapper:hover .close-button {
display: flex;
}
</style>

View file

@ -1,78 +0,0 @@
<template>
<div class="friends">
<Tab
@click.native="expanded = !expanded"
:expanded="expanded"
tabname="Offline"
/>
<transition name="list">
<div v-if="expanded" class="list">
<FriendsTemplate
v-for="(friend, key) of friends"
:key="key"
:channel-i-d="friend.channelID"
:recipient="friends[key].recipient"
:tree="true"
/>
</div>
</transition>
</div>
</template>
<script>
import Tab from "./Tab.vue";
import FriendsTemplate from "./FriendsTemplate.vue";
export default {
components: {
Tab,
FriendsTemplate
},
data() {
return {
expanded: true
};
},
computed: {
friends() {
const allFriend = this.$store.getters.user.friends;
const members = this.$store.getters["members/members"];
const presences = this.$store.getters["members/presences"];
const result = Object.keys(allFriend).map(function(key) {
allFriend[key].recipient = members[allFriend[key].uniqueID];
return allFriend[key];
});
return result.filter(
friend =>
friend.status == 2 &&
(!presences[friend.uniqueID] || presences[friend.uniqueID] == 0)
);
}
}
};
</script>
<style scoped>
.list-enter-active,
.list-leave-active {
transition: 0.3s;
}
.list-enter, .list-leave-to /* .fade-leave-active below version 2.1.8 */ {
transform: translateY(-20px);
opacity: 0;
}
.friends {
background-color: rgba(0, 0, 0, 0);
user-select: none;
padding-bottom: 3px;
border-radius: 5px;
transition: 0.3s;
}
.tab {
transition: 0.3s;
margin: 4px;
border-radius: 4px;
}
.tab:hover {
background-color: rgba(0, 0, 0, 0.2);
}
</style>

View file

@ -1,95 +0,0 @@
<template>
<div class="friends">
<Tab
@click.native="expanded = !expanded"
:expanded="expanded"
tabname="Online"
/>
<transition name="list">
<div v-if="expanded" class="list">
<FriendsTemplate
v-for="(friend, key) of friends"
:key="key"
:channel-i-d="friend.channelID"
:recipient="friends[key].recipient"
:tree="true"
/>
</div>
</transition>
</div>
</template>
<script>
import Tab from "./Tab.vue";
import FriendsTemplate from "./FriendsTemplate.vue";
export default {
components: {
Tab,
FriendsTemplate
},
data() {
return {
expanded: true
};
},
computed: {
friends() {
const allFriend = this.$store.getters.user.friends;
const members = this.$store.getters["members/members"];
const presences = this.$store.getters["members/presences"];
const notifications = this.$store.getters.notifications;
const channels = this.$store.getters.channels;
const result = Object.keys(allFriend).map(function(key) {
const friend = allFriend[key];
friend.recipient = members[friend.uniqueID];
const findNotification = notifications.find(e => {
return (
e.sender.uniqueID === friend.recipient.uniqueID &&
!channels[e.channelID].server_id
);
});
if (findNotification) {
friend.channelID = findNotification.channelID;
}
return friend;
});
return result.filter(
friend =>
friend.status == 2 &&
presences[friend.uniqueID] &&
presences[friend.uniqueID] > 0
);
}
},
methods: {}
};
</script>
<style scoped>
.list-enter-active,
.list-leave-active {
transition: 0.3s;
}
.list-enter, .list-leave-to /* .fade-leave-active below version 2.1.8 */ {
transform: translateY(-20px);
opacity: 0;
}
.friends {
background-color: rgba(0, 0, 0, 0);
user-select: none;
padding-bottom: 3px;
transition: 0.3s;
}
.tab {
transition: 0.3s;
margin: 4px;
border-radius: 4px;
}
.tab:hover {
background-color: rgba(0, 0, 0, 0.2);
}
</style>

View file

@ -1,73 +0,0 @@
<template>
<div class="pending-friends" v-if="friends && friends.length">
<Tab
@click.native="expanded = !expanded"
:expanded="expanded"
tabname="Pending requests"
/>
<transition name="list">
<div v-if="expanded" class="list">
<PendingTemplate
v-for="(friend, key) of friends"
:key="key"
:unique-i-d="friend.recipient.uniqueID"
:status="friend.status"
:username="friend.recipient.username"
:tag="friend.recipient.tag"
/>
</div>
</transition>
</div>
</template>
<script>
import Tab from "./Tab.vue";
import PendingTemplate from "./PendingTemplate.vue";
export default {
components: {
Tab,
PendingTemplate
},
data() {
return {
expanded: true
};
},
computed: {
friends() {
const allFriend = this.$store.getters.user.friends;
const members = this.$store.getters["members/members"];
const result = Object.keys(allFriend).map(function(key) {
allFriend[key].recipient = members[allFriend[key].uniqueID];
return allFriend[key];
});
return result.filter(friend => friend.status < 2);
}
}
};
</script>
<style scoped>
.list-enter-active,
.list-leave-active {
transition: 0.3s;
}
.list-enter, .list-leave-to /* .fade-leave-active below version 2.1.8 */ {
transform: translateY(-20px);
opacity: 0;
}
.pending-friends {
background-color: rgba(0, 0, 0, 0);
user-select: none;
padding-bottom: 3px;
transition: 0.3s;
}
.tab {
transition: 0.3s;
margin: 4px;
border-radius: 4px;
}
.tab:hover {
background-color: rgba(0, 0, 0, 0.2);
}
</style>

View file

@ -7,13 +7,13 @@
/>
<div class="information">
<div class="username">
{{ $props.username }}
{{ friend.recipient.username }}
</div>
<div class="tag">@{{ $props.tag }}</div>
<div class="tag">@{{ friend.recipient.tag }}</div>
</div>
<div class="buttons">
<div
:class="{ button: true, accept: true, hide: $props.status == 0 }"
:class="{ button: true, accept: true, hide: friend.status == 0 }"
@click="accept"
>
<i class="material-icons">
@ -34,10 +34,11 @@ import RelationshipService from "@/services/RelationshipService.js";
import config from "@/config.js";
export default {
props: ["username", "tag", "status", "uniqueID"],
props: ["friend"],
computed: {
user() {
return this.$store.getters.user.friends[this.$props.uniqueID].recipient;
return this.$store.getters.user.friends[this.friend.recipient.uniqueID]
.recipient;
},
userAvatar() {
return config.domain + "/avatars/" + this.user.avatar;
@ -45,13 +46,16 @@ export default {
},
methods: {
deny() {
RelationshipService.delete(this.$props.uniqueID);
RelationshipService.delete(this.friend.recipient.uniqueID);
},
accept() {
RelationshipService.put(this.$props.uniqueID);
RelationshipService.put(this.friend.recipient.uniqueID);
},
openUserInformation() {
this.$store.dispatch("setUserInformationPopout", this.uniqueID);
this.$store.dispatch(
"setUserInformationPopout",
this.friend.recipient.uniqueID
);
}
}
};
@ -59,7 +63,7 @@ export default {
<style scoped>
.username {
width: 80px;
width: 119px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
@ -67,16 +71,11 @@ export default {
}
.pending-friend {
color: white;
padding: 5px;
padding-left: 22px;
padding-left: 15px;
display: flex;
transition: 0.3s;
}
.pending-friend:hover {
background-color: rgba(0, 0, 0, 0.246);
}
.profile-picture {
height: 30px;
width: 30px;
@ -88,6 +87,7 @@ export default {
background-size: cover;
background-repeat: no-repeat;
flex-shrink: 0;
cursor: pointer;
}
.information {
margin: auto;
@ -96,18 +96,17 @@ export default {
flex: 1;
}
.tag {
color: rgb(173, 173, 173);
color: rgba(173, 173, 173, 0.8);
font-size: 15px;
}
.buttons {
display: flex;
margin: auto;
margin-right: 5px;
margin-right: 10px;
}
.button {
background-color: rgba(0, 0, 0, 0.2);
border-radius: 4px;
width: 30px;
height: 30px;
@ -119,14 +118,15 @@ export default {
.hide {
display: none;
}
.button:hover {
background-color: rgba(0, 255, 0, 0.281);
}
.button .material-icons {
margin: auto;
color: rgba(255, 255, 255, 0.747);
color: rgba(255, 255, 255, 0.7);
transition: 0.2s;
}
.button.decline:hover {
background-color: rgba(255, 0, 0, 0.281);
.button:hover .material-icons {
color: white;
}
.button.decline:hover .material-icons {
color: rgb(255, 80, 80);
}
</style>

View file

@ -1,11 +1,11 @@
<template>
<div class="recents">
<virtual-list :size="49" :remain="20">
<virtual-list :size="50" :remain="20" v-if="loaded" >
<FriendsTemplate
v-for="(channel, key) of channels"
:key="key"
:recents="true"
:channel-i-d="channel.channelID"
:friend="channel.channelID"
:recipient="channel.recipients[0]"
/>
</virtual-list>
@ -20,6 +20,14 @@ export default {
FriendsTemplate,
VirtualList
},
data() {
return {
loaded: false
};
},
mounted() {
setTimeout(() => (this.loaded = true));
},
computed: {
user() {
return this.$store.getters.user;
@ -78,8 +86,6 @@ export default {
};
</script>
<style scoped>
.recents {
background-color: rgba(0, 0, 0, 0);
user-select: none;
@ -97,4 +103,8 @@ export default {
.tab:hover {
background-color: rgba(0, 0, 0, 0.123);
}
.spacer {
display: flex;
height: 5px;
}
</style>

View file

@ -1,4 +1,11 @@
const config = [
{
version: "1.0.2",
title: "More performance improvements!",
shortTitle: "",
date: "17/02/2020",
fix: ["Improved performance by making code more efficient."]
},
{
version: "1.0.1",
title: "Grouped messages + message performance",

View file

@ -13,8 +13,8 @@
<main-nav />
<div class="panel-layout">
<news v-if="currentTab == 3" />
<direct-message v-if="currentTab == 1" />
<servers v-if="currentTab == 2" />
<servers v-if="currentTab == 1 || currentTab == 2" />
<!-- <servers v-if="currentTab == 2" /> -->
<explore v-if="currentTab == 0" />
<admin-panel v-if="currentTab == 4" />
</div>
@ -43,14 +43,14 @@ const ElectronFrameButtons = () =>
const News = () =>
import(/* webpackChunkName: "News" */ "./../components/app/Tabs/News.vue");
const DirectMessage = () => ({
component: import("./../components/app/Tabs/DirectMessage.vue"),
loading: Spinner,
delay: 0
});
// const DirectMessage = () => ({
// component: import("./../components/app/Tabs/DirectMessage.vue"),
// loading: Spinner,
// delay: 0
// });
const Servers = () => ({
component: import("./../components/app/Tabs/Servers.vue"),
component: import("./../components/app/Tabs/ServerAndDMTab"),
loading: Spinner,
delay: 0
});
@ -69,7 +69,7 @@ const AdminPanel = () => ({
export default {
name: "app",
components: {
DirectMessage,
// DirectMessage,
Servers,
ConnectingScreen,
Popouts,