upload banners + design changes

This commit is contained in:
supertiger1234 2019-11-03 13:38:26 +00:00
parent 747abcb510
commit 46533fa53a
11 changed files with 528 additions and 324 deletions

View file

@ -3,16 +3,26 @@
<div class="title">{{name}}</div>
<div class="current-select-box" ref="dropDown" @click="dropped = !dropped">
<div class="name" v-if="noneSelect && selectedItem || !noneSelect">
<div class="emoji" v-if="selectedItemSorted.emoji || items[0].emoji" v-html="selectedItem ? selectedItemSorted.emoji : items[0].emoji"></div>
<div
class="emoji"
v-if="selectedItemSorted.emoji || items[0].emoji"
v-html="selectedItem ? selectedItemSorted.emoji : items[0].emoji"
></div>
<div class="item-name">{{selectedItem ? selectedItemSorted.name : items[0].name}}</div>
</div>
<div class="name" v-if="noneSelect && !selectedItem">Select</div>
<div class="material-icons">expand_more</div>
</div>
<div class="drop" v-if="dropped">
<div class="drop-container">
<div v-for="(item, index) of itemEmojified" :key="index" class="item" :class="{selected: selectedItemSorted === item}" @click="itemClick(item)">
<div
v-for="(item, index) of itemEmojified"
:key="index"
class="item"
:class="{selected: selectedItemSorted === item}"
@click="itemClick(item)"
>
<div class="emoji" v-if="item.emoji" v-html="item.emoji"></div>
<div class="name">{{item.name}}</div>
</div>
@ -25,60 +35,58 @@
import emojiParser from "@/utils/emojiParser.js";
export default {
props: ['items', 'name', 'selectedItem', 'noneSelect', 'selectBy'], // noneSelect: by default, nothing will be selected.
props: ["items", "name", "selectedItem", "noneSelect", "selectBy"], // noneSelect: by default, nothing will be selected.
data() {
return {
dropped: false
}
};
},
methods: {
itemClick(item) {
this.$emit('change', item)
this.$emit("change", item);
},
documentClick(e) {
const target = e.target;
const el = this.$refs.dropDown
if (((el !== target) && !el.contains(target)) && this.dropped) {
this.dropped = false;
const el = this.$refs.dropDown;
if (el !== target && !el.contains(target) && this.dropped) {
this.dropped = false;
}
},
}
},
created() {
document.addEventListener('click', this.documentClick);
document.addEventListener("click", this.documentClick);
},
destroyed() {
document.removeEventListener('click', this.documentClick);
document.removeEventListener("click", this.documentClick);
},
computed: {
selectedItemSorted() {
let item = null;
if (this.selectBy){
if (this.selectBy) {
item = this.items.find(i => i[this.selectBy] === this.selectedItem);
} else {
item = this.selectedItem
item = this.selectedItem;
}
if (item && item.emoji && !item.emoji.startsWith('<img')) {
item.emoji = emojiParser.replaceEmojis(item.emoji)
if (item && item.emoji && !item.emoji.startsWith("<img")) {
item.emoji = emojiParser.replaceEmojis(item.emoji);
}
return item
return item;
},
itemEmojified(){
itemEmojified() {
return this.items.map(i => {
if (i && i.emoji && !i.emoji.startsWith('<img')) {
i.emoji = emojiParser.replaceEmojis(i.emoji)
if (i && i.emoji && !i.emoji.startsWith("<img")) {
i.emoji = emojiParser.replaceEmojis(i.emoji);
}
return i
})
return i;
});
}
}
}
};
</script>
<style scoped>
.drop-down {
background-color: rgb(44, 44, 44);
border-radius: 10px;
background-color: #06454d;
padding: 10px;
user-select: none;
cursor: default;
@ -89,15 +97,14 @@ export default {
margin-bottom: 2px;
}
.current-select-box {
background: rgba(22, 22, 22, 0.411);
border-radius: 5px;
background: #05353b;
padding: 5px;
cursor: pointer;
display: flex;
transition: 0.3s;
}
.current-select-box:hover {
background: rgba(22, 22, 22, 0.788);
background: #0f292c;
}
.current-select-box div {
align-self: center;
@ -106,7 +113,7 @@ export default {
white-space: nowrap;
display: flex;
}
.current-select-box .emoji{
.current-select-box .emoji {
margin-right: 5px;
}
.current-select-box .name {
@ -116,8 +123,7 @@ export default {
.drop {
position: absolute;
background: rgb(39, 39, 39);
border-radius: 5px;
background-color: #06454d;
left: 0;
right: 0;
z-index: 11111;
@ -126,7 +132,6 @@ export default {
margin-top: 5px;
}
.drop-container {
border-radius: 5px;
overflow: auto;
max-height: 100px;
}
@ -135,9 +140,6 @@ export default {
}
.item {
padding: 5px;
border-radius: 5px;
margin-top: 2px;
margin-bottom: 2px;
transition: 0.2s;
overflow: hidden;
text-overflow: ellipsis;
@ -152,12 +154,12 @@ export default {
}
.item:hover {
background: rgb(46, 46, 46);
background: #0f292c;
}
.item.selected {
background: rgb(63, 63, 63);
background: #021c1f;
}
.material-icons{
.material-icons {
flex-shrink: 0;
}
</style>

View file

@ -1,34 +1,52 @@
<template>
<div class="content">
<errors-list-template :errors="errors" v-if="errors" />
<errors-list-template :errors="errors" v-if="errors" />
<div class="content-inner" :key="key">
<div class="top">
<profile-picture
class="server-avatar"
size="100px"
:url="update.avatar || `${avatarDomain}/${server.avatar}`"
/>
<div class="button" @click="$refs.avatarBrowser.click()">Edit Avatar</div>
<input
ref="avatarBrowser"
type="file"
accept=".jpeg, .jpg, .png, .gif"
class="hidden"
@change="avatarChangeEvent"
/>
<div class="input">
<div class="input-title">Server Name</div>
<div class="avatar">
<profile-picture
class="server-avatar"
size="100px"
:url="update.avatar || `${avatarDomain}/${server.avatar}`"
/>
<div class="button" @click="$refs.avatarBrowser.click()">Edit Avatar</div>
<input
type="text"
ref="name"
placeholder="Channel Name"
:default-value.prop="server.name"
@input="inputEvent('name', $event)"
ref="avatarBrowser"
type="file"
accept=".jpeg, .jpg, .png, .gif"
class="hidden"
@change="imageChangeEvent('avatar', $event)"
/>
</div>
<div class="banner">
<div
class="banner-image"
:style="{backgroundImage: `url(${update.banner || `${bannerDomain}${server.banner}` })`}"
>
<div class="banner-text"></div>
</div>
<div class="button" @click="$refs.bannerBrowser.click()">Edit Banner</div>
<input
ref="bannerBrowser"
type="file"
accept=".jpeg, .jpg, .png, .gif"
class="hidden"
@change="imageChangeEvent('banner', $event)"
/>
</div>
</div>
<div class="details">
<div class="options">
<div class="input">
<div class="input-title">Server Name</div>
<input
type="text"
ref="name"
placeholder="Channel Name"
:default-value.prop="server.name"
@input="inputEvent('name', $event)"
/>
</div>
<drop-down
:items="channels"
:selected-item="defaultChannel"
@ -65,8 +83,9 @@ export default {
changed: false,
errors: null,
avatarDomain: config.domain + "/avatars/",
bannerDomain: config.domain + "/media/",
update: {},
key: 1,
key: 1
};
},
methods: {
@ -85,7 +104,7 @@ export default {
);
if (!ok) {
if (error.response) {
if (error.response.data.message)
if (error.response.data.message)
this.errors = [{ msg: error.response.data.message }];
else this.errors = error.response.data.errors;
} else {
@ -98,7 +117,8 @@ export default {
this.update = {};
this.requestSent = false;
},
avatarChangeEvent(e) {
//type: avatar || banner
imageChangeEvent(type, e) {
if (!this.googleDriveLinked) {
event.target.value = "";
return this.$store.dispatch("setPopoutVisibility", {
@ -127,7 +147,7 @@ export default {
reader.readAsDataURL(file);
reader.onload = function() {
_this.$set(_this.update, "avatar", reader.result);
_this.$set(_this.update, type, reader.result);
};
reader.onerror = function(error) {
console.log("Error: ", error);
@ -146,6 +166,9 @@ export default {
this.changed = true;
}
},
mounted() {
console.log(this.server);
},
computed: {
googleDriveLinked() {
return this.$store.getters["settingsModule/settings"].GDriveLinked;
@ -178,7 +201,7 @@ export default {
};
</script>
<style scoped>
<style scoped lang="scss">
.content-inner {
height: 100%;
overflow: auto;
@ -194,11 +217,54 @@ export default {
}
.top {
display: flex;
flex-direction: column;
width: 100%;
align-self: center;
margin-top: 10px;
justify-content: center;
flex-shrink: 0;
background-color: #06454d;
.avatar {
display: flex;
flex-direction: column;
height: 100%;
flex-shrink: 0;
.server-avatar {
height: 100%;
margin-top: 35px;
}
.button {
margin-bottom: 10px;
}
}
.banner {
display: flex;
flex-direction: column;
justify-content: center;
align-self: center;
flex-shrink: 0;
margin-top: 10px;
padding: 5px;
margin-left: 2px;
.banner-image {
position: relative;
width: 240px;
height: 150px;
background: rgba(0, 0, 0, 0.4);
background-position: center;
background-size: cover;
.banner-text {
position: absolute;
bottom: 0;
left: 0;
right: 0;
width: 100%;
height: 35px;
backdrop-filter: blur(15px);
background: rgba(0, 0, 0, 0.5);
}
}
}
}
.details {
display: flex;
flex-direction: column;
@ -220,8 +286,7 @@ export default {
.input {
display: flex;
flex-direction: column;
background-color: rgb(44, 44, 44);
border-radius: 10px;
background-color: #06454d;
padding: 10px;
align-self: center;
margin: 10px;
@ -230,13 +295,12 @@ export default {
.input input {
margin-top: 2px;
margin-bottom: 0;
border-radius: 5px;
width: 190px;
background: #05353b;
}
.button {
background: rgba(17, 148, 255, 0.692);
background: #05353b;
padding: 10px;
border-radius: 5px;
align-self: center;
margin: 5px;
cursor: pointer;
@ -244,18 +308,26 @@ export default {
transition: 0.3s;
}
.button:hover {
background: rgb(17, 148, 255);
background: #0f292c;
}
.save-button {
margin-top: 50px;
margin-top: 10px;
}
.save-button.disabled {
background: rgba(59, 59, 59, 0.692);
background: rgba(0, 0, 0, 0.692);
}
.hidden {
display: none;
}
@media (max-width: 390px) {
.top {
flex-direction: column;
.avatar {
height: initial;
}
}
}
</style>

View file

@ -2,20 +2,30 @@
<div class="dark-background" @mousedown="backgroundClick">
<div class="inner">
<div class="tabs">
<div class="tab" v-for="(tab, _index) in tabs" :key="_index" :class="{selected: index === _index, critical: tab.critical}" @click="index = _index"><div class="material-icons">{{tab.icon}}</div><div>{{tab.title}}</div></div>
<div
class="tab"
v-for="(tab, _index) in tabs"
:key="_index"
:class="{selected: index === _index, critical: tab.critical}"
@click="index = _index"
>
<div class="material-icons">{{tab.icon}}</div>
<div>{{tab.title}}</div>
</div>
</div>
<div class="content">
<div class="header" :class="{critical: tabs[index].critical}">
<div class="material-icons">{{tabs[index].icon}}</div><div>{{tabs[index].title}}</div>
<div class="close-button" @click="closeMenu">
<div class="material-icons">close</div>
</div>
<div class="material-icons">{{tabs[index].icon}}</div>
<div>{{tabs[index].title}}</div>
<div class="close-button" @click="closeMenu">
<div class="material-icons">close</div>
</div>
</div>
<general v-if="index === 0"/>
<manage-channels v-if="index === 1"/>
<manage-bans v-if="index === 2"/>
<server-visibility v-if="index === 3"/>
<delete-server v-if="index === 4"/>
<general v-if="index === 0" />
<manage-channels v-if="index === 1" />
<manage-bans v-if="index === 2" />
<server-visibility v-if="index === 3" />
<delete-server v-if="index === 4" />
</div>
</div>
</div>
@ -28,25 +38,31 @@ import ServerService from "@/services/ServerService";
import { mapState } from "vuex";
// panels
import General from './General.vue'
import DeleteServer from './DeleteServer.vue'
import ManageChannels from './ManageChannels.vue'
import ManageBans from './ManageBans.vue'
import ServerVisibility from './ServerVisibility.vue'
import General from "./General.vue";
import DeleteServer from "./DeleteServer.vue";
import ManageChannels from "./ManageChannels.vue";
import ManageBans from "./ManageBans.vue";
import ServerVisibility from "./ServerVisibility.vue";
export default {
components: { General, DeleteServer, ManageChannels, ServerVisibility, ManageBans},
components: {
General,
DeleteServer,
ManageChannels,
ServerVisibility,
ManageBans
},
data() {
return {
index: 0,
tabs: [
{title: "General", icon: "info"},
{title: "Manage Channels", icon: "storage"},
{ title: "General", icon: "info" },
{ title: "Manage Channels", icon: "storage" },
// {title: "Manage Invites", icon: "local_post_office"},
{title: "Banned Members", icon: "lock"},
{title: "Server Visibility", icon: "visibility"},
{title: "Delete Server", icon: "warning", critical: true},
{ title: "Banned Members", icon: "lock" },
{ title: "Server Visibility", icon: "visibility" },
{ title: "Delete Server", icon: "warning", critical: true }
]
}
};
},
methods: {
@ -59,19 +75,19 @@ export default {
if (e.target.classList.contains("dark-background")) {
this.closeMenu();
}
},
}
},
computed: {
server() {
const serverID = this.$store.state.popoutsModule.serverSettings.serverID
return this.$store.getters['servers/servers'][serverID]
const serverID = this.$store.state.popoutsModule.serverSettings.serverID;
return this.$store.getters["servers/servers"][serverID];
}
}
};
</script>
<style scoped>
<style scoped lang="scss">
.dark-background {
position: absolute;
top: 0;
@ -85,17 +101,18 @@ export default {
.inner {
margin: auto;
height: 100%;
max-height: 500px;
max-height: 550px;
width: 700px;
background: rgba(32, 32, 32, 0.87);
display: flex;
color: white;
overflow: hidden;
border-radius: 10px;
position: relative;
background-image: url("../../../../../assets/leftPanelBackground.jpg");
background-repeat: no-repeat;
background-position: center;
background-size: cover;
}
.content {
width: 100%;
height: 100%;
@ -106,14 +123,12 @@ export default {
.tabs {
display: flex;
flex-direction: column;
background: rgba(26, 26, 26, 0.897);
background: #144a59;
height: 100%;
width: 180px;
flex-shrink: 0;
}
.tab {
border-radius: 5px;
margin: 5px;
padding: 5px;
transition: 0.2s;
cursor: pointer;
@ -121,24 +136,29 @@ export default {
display: flex;
align-content: center;
flex-shrink: 0;
font-size: 15px;
.material-icons {
font-size: 24px;
color: rgba(255, 255, 255, 0.8);
}
}
.tab .material-icons {
margin-right: 3px;
margin-right: 5px;
}
.tab div {
align-self: center;
}
.tab:hover {
background: rgb(39, 39, 39);
background: #103a45;
}
.critical {
color: red;
}
.tab.selected {
background: rgb(59, 59, 59);
background: #0c2c35;
}
.header{
background: rgb(47, 47, 47);
.header {
background: #063e45;
display: flex;
height: 50px;
flex-shrink: 0;
@ -161,7 +181,6 @@ export default {
position: absolute;
top: 5px;
right: 5px;
}
.close-button:hover {
background: rgba(37, 37, 37, 0.692);
@ -191,5 +210,4 @@ export default {
height: 5px;
}
}
</style>

View file

@ -1,36 +1,69 @@
<template>
<div class="survey">
<div class="inner-content">
<div class="title"><i class="material-icons">error</i>Take Survey</div>
<div class="title">
<i class="material-icons">error</i>Take Survey
</div>
<div class="notice">Note: Everyone will be able to see your survey in your profile.</div>
<spinner v-if="!loaded"/>
<spinner v-if="!loaded" />
<div class="survey-inner" v-if="loaded">
<div class="survey-content">
<div class="left">
<!-- name -->
<div class="input">
<div class="input-title">Name</div>
<input type="text" placeholder="Name" v-model="items.name">
<input type="text" placeholder="Name" v-model="items.name" />
</div>
<!-- Gender -->
<drop-down class="dropdown" :items="surveyItems.gender" selectBy="name" :selectedItem="items.gender" :noneSelect="true" name="Gender" @change="changeEvent('gender', $event)"/>
<drop-down
class="dropdown"
:items="surveyItems.gender"
selectBy="name"
:selectedItem="items.gender"
:noneSelect="true"
name="Gender"
@change="changeEvent('gender', $event)"
/>
<!-- Age -->
<drop-down class="dropdown" :items="surveyItems.age" selectBy="name" :selectedItem="items.age" :noneSelect="true" name="Age" @change="changeEvent('age', $event)"/>
<drop-down
class="dropdown"
:items="surveyItems.age"
selectBy="name"
:selectedItem="items.age"
:noneSelect="true"
name="Age"
@change="changeEvent('age', $event)"
/>
</div>
<div class="right">
<!-- Continent -->
<drop-down class="dropdown" :items="surveyItems.continents" selectBy="name" :selectedItem="items.continent" :noneSelect="true" name="Continent" @change="changeEvent('continent', $event)"/>
<drop-down
class="dropdown"
:items="surveyItems.continents"
selectBy="name"
:selectedItem="items.continent"
:noneSelect="true"
name="Continent"
@change="changeEvent('continent', $event)"
/>
<!-- Countries -->
<drop-down class="dropdown" v-if="filterCountries" :items="filterCountries" selectBy="name" :selectedItem="items.country" :noneSelect="true" name="Country" @change="changeEvent('country', $event)"/>
<!-- About me -->
<drop-down
class="dropdown"
v-if="filterCountries"
:items="filterCountries"
selectBy="name"
:selectedItem="items.country"
:noneSelect="true"
name="Country"
@change="changeEvent('country', $event)"
/>
<!-- About me -->
<div class="input">
<div class="input-title">About me</div>
<textarea placeholder="I like cats and dogs." v-model="items.about_me" />
</div>
<textarea placeholder="I like cats and dogs." v-model="items.about_me" />
</div>
</div>
</div>
</div>
</div>
<div class="survey-warning" v-if="surveyErrorMessage">{{ surveyErrorMessage }}</div>
@ -40,10 +73,10 @@
</template>
<script>
import DropDown from './../ServerSettingsPanels/DropDownMenu';
import DropDown from "./../ServerSettingsPanels/DropDownMenu";
import surveyItems from "@/utils/surveyItems.js";
import userService from "@/services/userService.js";
import Spinner from '@/components/Spinner';
import Spinner from "@/components/Spinner";
export default {
components: { DropDown, Spinner },
data() {
@ -54,9 +87,8 @@ export default {
loaded: false,
items: {
about_me: null,
name: null,
},
name: null
}
};
},
async mounted() {
@ -68,23 +100,23 @@ export default {
this.loaded = true;
return;
}
this.$set(this, 'items', Object.assign({}, this.items, result.data.result))
this.$set(this, "items", Object.assign({}, this.items, result.data.result));
this.loaded = true;
},
methods: {
changeEvent(name, item) {
if (name === 'continent'){
this.$set(this.items, 'country', null)
if (name === "continent") {
this.$set(this.items, "country", null);
}
this.$set(this.items, name, item.name);
},
async surveySubmitButton() {
this.surveyValidMessage = null;
this.surveyErrorMessage = null;
this.surveyValidMessage = "Saving...";
//gets the country index after unfiltering.
if (this.items.name && this.items.name.length > 100) {
this.surveyErrorMessage = "Name must be less that 100 characters.";
this.surveyValidMessage = null;
@ -101,16 +133,23 @@ export default {
this.surveyValidMessage = "Saved!";
} else {
this.surveyValidMessage = null;
this.surveyErrorMessage = error.response.data.message || error.response.data;
this.surveyErrorMessage =
error.response.data.message || error.response.data;
}
}
},
computed: {
filterCountries(){
if (!this.items.continent || this.items.continent === "Rather not say") return null;
const continent = this.surveyItems.continents.find(c => c.name === this.items.continent);
filterCountries() {
if (!this.items.continent || this.items.continent === "Rather not say")
return null;
const continent = this.surveyItems.continents.find(
c => c.name === this.items.continent
);
if (!continent) return null;
return [...this.surveyItems.countries.filter(c => c.code === continent.code), ...[{emoji: "😶",name: 'Rather not say', code: 'no'}]];
return [
...this.surveyItems.countries.filter(c => c.code === continent.code),
...[{ emoji: "😶", name: "Rather not say", code: "no" }]
];
}
}
};
@ -145,7 +184,6 @@ export default {
flex-direction: column;
width: 100%;
height: 100%;
}
.inner-content {
display: flex;
@ -159,14 +197,14 @@ export default {
display: flex;
}
.left{
.left {
display: flex;
flex-direction: column;
flex: 1;
flex-shrink: 0;
}
.right {
display: flex;
display: flex;
flex-direction: column;
flex: 1;
flex-shrink: 0;
@ -202,7 +240,6 @@ export default {
background: rgb(0, 98, 255);
}
.title {
margin-top: 20px;
display: flex;
@ -221,8 +258,7 @@ export default {
.input {
display: flex;
flex-direction: column;
background-color: rgb(44, 44, 44);
border-radius: 10px;
background-color: #06454d;
padding: 10px;
margin: 10px;
margin-left: 30px;
@ -231,13 +267,13 @@ export default {
}
.input input {
width: initial;
border-radius: 5px;
margin-top: 2px;
background: #05353b;
}
textarea {
padding: 10px;
resize: none;
background: rgba(0, 0, 0, 0.301);
background: #05353b;
border: none;
outline: none;
border-radius: 5px;
@ -252,7 +288,7 @@ textarea:hover {
}
@media (max-width: 764px) {
.survey-content{
.survey-content {
flex-direction: column;
}
}

View file

@ -2,8 +2,19 @@
<div class="left-panel">
<navigation />
<div class="right">
<div class="server-banner" v-if="selectedServerID">
<div class="banner-image"></div>
<div
class="server-banner"
@mouseenter="bannerHover = true"
@mouseleave="bannerHover = false"
:class="{extendBanner: server && server.banner}"
v-if="selectedServerID"
>
<div
class="banner-image"
@click="bannerImageClicked"
v-if="server && server.banner"
:style="{backgroundImage: `url(${bannerDomain}${server.banner}${bannerHover ? '' : '?type=png'})`}"
/>
<div class="sub-banner">
<div
class="text"
@ -25,6 +36,7 @@
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";
import { bus } from "@/main";
export default {
@ -35,7 +47,9 @@ export default {
},
data() {
return {
openedServer: null
openedServer: null,
bannerDomain: config.domain + "/media/",
bannerHover: false
};
},
methods: {
@ -69,6 +83,12 @@ export default {
x: rect.left - 30,
y: rect.top + 35
});
},
bannerImageClicked() {
this.$store.dispatch(
"setImagePreviewURL",
this.bannerDomain + this.server.banner
);
}
},
computed: {
@ -87,6 +107,9 @@ export default {
selectedServerID() {
return this.$store.getters["servers/selectedServerID"];
},
server() {
return this.servers[this.selectedServerID];
},
checkServerContextOpened() {
const contextDetail = this.$store.getters.popouts.allPopout;
return contextDetail.show && contextDetail.type === "SERVER";
@ -136,8 +159,12 @@ export default {
overflow: hidden;
position: relative;
flex-direction: row;
background-color: rgb(32, 32, 32);
background-color: rgba(32, 32, 32, 0.4);
height: 35px;
}
.extendBanner {
height: 150px;
background-color: rgb(32, 32, 32);
}
.banner-image {
position: absolute;
@ -147,6 +174,7 @@ export default {
height: 100%;
z-index: 2;
width: 100%;
cursor: pointer;
}
.sub-banner {
display: flex;

View file

@ -1,25 +1,29 @@
<template>
<div class="item">
<div class="item" @mouseenter="hover = true" @mouseleave="hover = false">
<div class="top">
<div class="background-dark"></div>
<profile-picture
size="90px"
:url="`${avatarDomain}/${server.server.avatar}`"
<div
class="background-dark"
v-if="server.server.banner"
:style="{backgroundImage: `url(${bannerDomain + server.server.banner}${hover ? '' : '?type=png'})`}"
/>
<profile-picture size="90px" :url="`${avatarDomain}/${server.server.avatar}`" />
<div class="name">
<div class="name-container">
<span class="inner-name">{{server.server.name}}</span>
<span class="material-icons" v-if="server.verified">check</span>
</div>
<span class="inner-name">{{server.server.name}}</span>
<span class="material-icons" v-if="server.verified">check</span>
</div>
</div>
</div>
<div class="bottom">
<div class="description">{{server.description}}</div>
<div class="buttons">
<div class="member-count"><div class="material-icons">account_box</div>{{server.total_members}}</div>
<div class="member-count">
<div class="material-icons">account_box</div>
{{server.total_members}}
</div>
<div class="button" :class="{selected: joined}" @click="joinButton">
<span v-if="joined">Joined</span>
<spinner v-else-if="joinClicked" :size="30"/>
<spinner v-else-if="joinClicked" :size="30" />
<span v-else-if="!joinClicked">Join Server</span>
</div>
</div>
@ -28,180 +32,190 @@
</template>
<script>
import {bus} from '@/main'
import { bus } from "@/main";
import Spinner from "@/components/Spinner";
import ServerService from "@/services/ServerService";
import config from "@/config.js";
import ProfilePicture from "@/components/ProfilePictureTemplate.vue";
export default {
components: {Spinner, ProfilePicture},
props: [
'server',
],
data() {
return {
components: { Spinner, ProfilePicture },
props: ["server"],
data() {
return {
joinClicked: false,
avatarDomain: config.domain + "/avatars"
}
},
methods: {
async joinButton(event) {
if (this.joinClicked|| this.joined) return;
this.joinClicked = true;
avatarDomain: config.domain + "/avatars",
bannerDomain: config.domain + "/media/",
hover: false
};
},
methods: {
async joinButton(event) {
if (this.joinClicked || this.joined) return;
this.joinClicked = true;
const { ok, error, result } = await ServerService.joinServerById(this.server.server.server_id, {
socketID: this.$socket.id
});
const { ok, error, result } = await ServerService.joinServerById(
this.server.server.server_id,
{
socketID: this.$socket.id
}
);
if (ok) {
this.joinClicked = false;
}
}
},
computed: {
joined() {
return this.$store.getters["servers/servers"][this.server.server.server_id];
},
computed: {
joined() {
return this.$store.getters["servers/servers"][
this.server.server.server_id
];
},
channels() {
return this.$store.getters.channels;
}
}
}
};
</script>
<style lang="scss" scoped>
.item {
position: relative;
width: 250px;
height: 300px;
background: rgba(0, 0, 0, 0.479);
opacity: 0.9;
margin: 5px;
flex-shrink: 0;
border-radius: 10px;
transition: 0.3s;
display: flex;
flex-shrink: 0;
flex-direction: column;
overflow: hidden;
&:hover {
opacity: 1;
}
.top {
display: flex;
flex-direction: column;
width: 100%;
height: 150px;
justify-content: center;
align-content: center;
align-items: center;
flex-shrink: 0;
position: relative;
.background-dark {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba(0, 0, 0, 0.6);
}
background-image: url('../../../../assets/background.jpg');
background-position: center;
background-size: cover;
.avatar {
background: rgb(26, 133, 255);
height: 80px;
width: 80px;
border-radius: 50%;
margin-bottom: 10px;
}
.name {
margin-top: 9px;
font-size: 21px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 100%;
text-align: center;
display: flex;
z-index: 999;
.name-container {
display: flex;
margin: auto;
}
.inner-name {
max-width: 200px;
overflow: hidden;
text-overflow: ellipsis
}
.material-icons {
color: #66e0ff;
margin-left: 5px;
}
}
}
.bottom {
display: flex;
flex-direction: column;
background: rgba(0, 0, 0, 0.541);
flex: 1;
.item {
position: relative;
width: 250px;
height: 300px;
background: rgba(0, 0, 0, 0.479);
opacity: 0.9;
margin: 5px;
flex-shrink: 0;
transition: 0.3s;
display: flex;
flex-shrink: 0;
flex-direction: column;
overflow: hidden;
&:hover {
opacity: 1;
}
.top {
display: flex;
flex-direction: column;
width: 100%;
height: 150px;
justify-content: center;
align-content: center;
align-items: center;
flex-shrink: 0;
position: relative;
.background-dark {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba(0, 0, 0, 0.6);
background-position: center;
background-size: cover;
&::before {
content: "";
position: absolute;
height: 100%;
flex-shrink: 0;
.description {
margin: 10px;
flex: 1;
opacity: 0.9;
overflow: auto;
font-size: 14px;
word-break: break-word;
white-space: pre-wrap;
overflow-wrap: anywhere;
flex-shrink: 0;
}
.buttons {
display: flex;
width: 100%;
flex-direction: row;
}
.member-count {
display: flex;
align-items: center;
align-content: center;
margin-left: 10px;
margin-top: 0px;
width: 100%;
.material-icons { margin-right: 5px;}
}
.button {
display: flex;
align-content: center;
align-items: center;
flex-direction: column;
justify-content: center;
flex-shrink: 0;
background: rgba(40, 140, 255, 0.8);
border-radius: 5px;
align-self: flex-end;
flex-shrink: 0;
margin: auto;
margin-right: 10px;
margin-left: 0;
margin-bottom: 10px;
padding: 7px;
transition: 0.3s;
width: 80px;
height: 20px;
cursor: pointer;
&:hover {
background: rgb(40, 140, 255);
}
&.selected {
background: grey;
}
}
width: 100%;
background: rgba(0, 0, 0, 0.6);
}
}
.avatar {
background: rgb(26, 133, 255);
height: 80px;
width: 80px;
border-radius: 50%;
margin-bottom: 10px;
}
.name {
margin-top: 9px;
font-size: 21px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 100%;
text-align: center;
display: flex;
z-index: 999;
.name-container {
display: flex;
margin: auto;
}
.inner-name {
max-width: 200px;
overflow: hidden;
text-overflow: ellipsis;
}
.material-icons {
color: #66e0ff;
margin-left: 5px;
}
}
}
.bottom {
display: flex;
flex-direction: column;
background: rgba(0, 0, 0, 0.541);
flex: 1;
height: 100%;
flex-shrink: 0;
.description {
margin: 10px;
flex: 1;
opacity: 0.9;
overflow: auto;
font-size: 14px;
word-break: break-word;
white-space: pre-wrap;
overflow-wrap: anywhere;
flex-shrink: 0;
}
.buttons {
display: flex;
width: 100%;
flex-direction: row;
}
.member-count {
display: flex;
align-items: center;
align-content: center;
margin-left: 10px;
margin-top: 0px;
width: 100%;
.material-icons {
margin-right: 5px;
}
}
.button {
display: flex;
align-content: center;
align-items: center;
flex-direction: column;
justify-content: center;
flex-shrink: 0;
background: rgba(40, 140, 255, 0.8);
align-self: flex-end;
flex-shrink: 0;
margin: auto;
margin-right: 10px;
margin-left: 0;
margin-bottom: 10px;
padding: 7px;
transition: 0.3s;
width: 80px;
height: 20px;
cursor: pointer;
&:hover {
background: rgb(40, 140, 255);
}
&.selected {
background: grey;
}
}
}
}
</style>

View file

@ -115,8 +115,7 @@ export default {
text-overflow: ellipsis;
overflow: hidden;
}
.embed.article {
}
.embed.website {
height: 100px;
}

View file

@ -9,12 +9,27 @@ const prototype = {
};
const config = [
{
version: 7.9,
title: "Server banner",
shortTitle: "",
date: "03/11/2019",
headColor: "#0c7b7f",
new: [
"You can now add banners to your server! These banners will be displayed in your server channels list and in the explore tab. To change your banner, go to your server settings page."
],
fix: [
"Fixed a bug where when pressing enter on the login or register key, it would not work properly."
],
next: [
"Re-design some popup menus starting from user settings. (Note that the survey kind of looks weird right now. It will be fixed in the next update hopefully :D"
]
},
{
version: 7.8,
title: "Redesigns!",
shortTitle: "",
date: "01/11/2019",
headColor: "#0c7b7f",
new: [
"Layout has been redesigned.",
"Added an option to mute notification sounds.",

View file

@ -258,7 +258,7 @@ export default {
-webkit-app-region: drag;
flex-shrink: 0;
height: 25px;
background: #1089ff;
background: #0a6f7b;
}
.window-buttons {

View file

@ -11,7 +11,12 @@
Login
</div>
<div class="info">Login to access Nertivia</div>
<form v-if="!showCaptcha" action="#" @submit.prevent="submitForm">
<form
v-if="!showCaptcha"
action="#"
@submit.prevent="submitForm"
@keydown.prevent="keyDownEvent"
>
<div class="input">
<div class="input-text">
Email
@ -97,6 +102,11 @@ export default {
submitForm() {
this.showCaptcha = true;
},
keyDownEvent(event) {
if (event.keyCode === 13) {
this.submitForm();
}
},
async login() {
if (this.deactive === true) return;
this.resetValues();

View file

@ -11,7 +11,12 @@
Register
</div>
<div class="info">Welcome, new user! I Hope you enjoy Nertivia!</div>
<form v-if="!showCaptcha" action="#" @submit.prevent="formSubmit">
<form
v-if="!showCaptcha"
action="#"
@submit.prevent="formSubmit"
@keydown.prevent="keyDownEvent"
>
<div class="input">
<div class="input-text">
Email
@ -109,6 +114,11 @@ export default {
formSubmit() {
this.showCaptcha = true;
},
keyDownEvent(event) {
if (event.keyCode === 13) {
this.formSubmit();
}
},
async register() {
this.resetValues();
const email = this.email.value.trim();