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

View file

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

View file

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

View file

@ -1,36 +1,69 @@
<template> <template>
<div class="survey"> <div class="survey">
<div class="inner-content"> <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> <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-inner" v-if="loaded">
<div class="survey-content"> <div class="survey-content">
<div class="left"> <div class="left">
<!-- name --> <!-- name -->
<div class="input"> <div class="input">
<div class="input-title">Name</div> <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> </div>
<!-- Gender --> <!-- 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 --> <!-- 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>
<div class="right"> <div class="right">
<!-- Continent --> <!-- 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 --> <!-- Countries -->
<drop-down class="dropdown" v-if="filterCountries" :items="filterCountries" selectBy="name" :selectedItem="items.country" :noneSelect="true" name="Country" @change="changeEvent('country', $event)"/> <drop-down
class="dropdown"
v-if="filterCountries"
:items="filterCountries"
selectBy="name"
:selectedItem="items.country"
:noneSelect="true"
name="Country"
@change="changeEvent('country', $event)"
/>
<!-- About me --> <!-- About me -->
<div class="input"> <div class="input">
<div class="input-title">About me</div> <div class="input-title">About me</div>
<textarea placeholder="I like cats and dogs." v-model="items.about_me" /> <textarea placeholder="I like cats and dogs." v-model="items.about_me" />
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="survey-warning" v-if="surveyErrorMessage">{{ surveyErrorMessage }}</div> <div class="survey-warning" v-if="surveyErrorMessage">{{ surveyErrorMessage }}</div>
@ -40,10 +73,10 @@
</template> </template>
<script> <script>
import DropDown from './../ServerSettingsPanels/DropDownMenu'; import DropDown from "./../ServerSettingsPanels/DropDownMenu";
import surveyItems from "@/utils/surveyItems.js"; import surveyItems from "@/utils/surveyItems.js";
import userService from "@/services/userService.js"; import userService from "@/services/userService.js";
import Spinner from '@/components/Spinner'; import Spinner from "@/components/Spinner";
export default { export default {
components: { DropDown, Spinner }, components: { DropDown, Spinner },
data() { data() {
@ -54,9 +87,8 @@ export default {
loaded: false, loaded: false,
items: { items: {
about_me: null, about_me: null,
name: null, name: null
}, }
}; };
}, },
async mounted() { async mounted() {
@ -68,13 +100,13 @@ export default {
this.loaded = true; this.loaded = true;
return; 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; this.loaded = true;
}, },
methods: { methods: {
changeEvent(name, item) { changeEvent(name, item) {
if (name === 'continent'){ if (name === "continent") {
this.$set(this.items, 'country', null) this.$set(this.items, "country", null);
} }
this.$set(this.items, name, item.name); this.$set(this.items, name, item.name);
}, },
@ -101,16 +133,23 @@ export default {
this.surveyValidMessage = "Saved!"; this.surveyValidMessage = "Saved!";
} else { } else {
this.surveyValidMessage = null; this.surveyValidMessage = null;
this.surveyErrorMessage = error.response.data.message || error.response.data; this.surveyErrorMessage =
error.response.data.message || error.response.data;
} }
} }
}, },
computed: { computed: {
filterCountries(){ filterCountries() {
if (!this.items.continent || this.items.continent === "Rather not say") return null; if (!this.items.continent || this.items.continent === "Rather not say")
const continent = this.surveyItems.continents.find(c => c.name === this.items.continent); return null;
const continent = this.surveyItems.continents.find(
c => c.name === this.items.continent
);
if (!continent) return null; 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; flex-direction: column;
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
.inner-content { .inner-content {
display: flex; display: flex;
@ -159,7 +197,7 @@ export default {
display: flex; display: flex;
} }
.left{ .left {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
flex: 1; flex: 1;
@ -202,7 +240,6 @@ export default {
background: rgb(0, 98, 255); background: rgb(0, 98, 255);
} }
.title { .title {
margin-top: 20px; margin-top: 20px;
display: flex; display: flex;
@ -221,8 +258,7 @@ export default {
.input { .input {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
background-color: rgb(44, 44, 44); background-color: #06454d;
border-radius: 10px;
padding: 10px; padding: 10px;
margin: 10px; margin: 10px;
margin-left: 30px; margin-left: 30px;
@ -231,13 +267,13 @@ export default {
} }
.input input { .input input {
width: initial; width: initial;
border-radius: 5px;
margin-top: 2px; margin-top: 2px;
background: #05353b;
} }
textarea { textarea {
padding: 10px; padding: 10px;
resize: none; resize: none;
background: rgba(0, 0, 0, 0.301); background: #05353b;
border: none; border: none;
outline: none; outline: none;
border-radius: 5px; border-radius: 5px;
@ -252,7 +288,7 @@ textarea:hover {
} }
@media (max-width: 764px) { @media (max-width: 764px) {
.survey-content{ .survey-content {
flex-direction: column; flex-direction: column;
} }
} }

View file

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

View file

@ -1,25 +1,29 @@
<template> <template>
<div class="item"> <div class="item" @mouseenter="hover = true" @mouseleave="hover = false">
<div class="top"> <div class="top">
<div class="background-dark"></div> <div
<profile-picture class="background-dark"
size="90px" v-if="server.server.banner"
:url="`${avatarDomain}/${server.server.avatar}`" :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">
<div class="name-container"> <div class="name-container">
<span class="inner-name">{{server.server.name}}</span> <span class="inner-name">{{server.server.name}}</span>
<span class="material-icons" v-if="server.verified">check</span> <span class="material-icons" v-if="server.verified">check</span>
</div> </div>
</div> </div>
</div> </div>
<div class="bottom"> <div class="bottom">
<div class="description">{{server.description}}</div> <div class="description">{{server.description}}</div>
<div class="buttons"> <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"> <div class="button" :class="{selected: joined}" @click="joinButton">
<span v-if="joined">Joined</span> <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> <span v-else-if="!joinClicked">Join Server</span>
</div> </div>
</div> </div>
@ -28,180 +32,190 @@
</template> </template>
<script> <script>
import {bus} from '@/main' import { bus } from "@/main";
import Spinner from "@/components/Spinner"; import Spinner from "@/components/Spinner";
import ServerService from "@/services/ServerService"; import ServerService from "@/services/ServerService";
import config from "@/config.js"; import config from "@/config.js";
import ProfilePicture from "@/components/ProfilePictureTemplate.vue"; import ProfilePicture from "@/components/ProfilePictureTemplate.vue";
export default { export default {
components: {Spinner, ProfilePicture}, components: { Spinner, ProfilePicture },
props: [ props: ["server"],
'server', data() {
], return {
data() {
return {
joinClicked: false, joinClicked: false,
avatarDomain: config.domain + "/avatars" avatarDomain: config.domain + "/avatars",
} bannerDomain: config.domain + "/media/",
}, hover: false
methods: { };
async joinButton(event) { },
if (this.joinClicked|| this.joined) return; methods: {
this.joinClicked = true; async joinButton(event) {
if (this.joinClicked || this.joined) return;
this.joinClicked = true;
const { ok, error, result } = await ServerService.joinServerById(this.server.server.server_id, { const { ok, error, result } = await ServerService.joinServerById(
socketID: this.$socket.id this.server.server.server_id,
}); {
socketID: this.$socket.id
}
);
if (ok) { if (ok) {
this.joinClicked = false; this.joinClicked = false;
} }
} }
}, },
computed: { computed: {
joined() { joined() {
return this.$store.getters["servers/servers"][this.server.server.server_id]; return this.$store.getters["servers/servers"][
this.server.server.server_id
];
}, },
channels() { channels() {
return this.$store.getters.channels; return this.$store.getters.channels;
} }
} }
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.item { .item {
position: relative; position: relative;
width: 250px; width: 250px;
height: 300px; height: 300px;
background: rgba(0, 0, 0, 0.479); background: rgba(0, 0, 0, 0.479);
opacity: 0.9; opacity: 0.9;
margin: 5px; margin: 5px;
flex-shrink: 0; flex-shrink: 0;
border-radius: 10px; transition: 0.3s;
transition: 0.3s; display: flex;
display: flex; flex-shrink: 0;
flex-shrink: 0; flex-direction: column;
flex-direction: column; overflow: hidden;
overflow: hidden; &:hover {
&:hover { opacity: 1;
opacity: 1; }
} .top {
.top { display: flex;
display: flex; flex-direction: column;
flex-direction: column; width: 100%;
width: 100%; height: 150px;
height: 150px; justify-content: center;
justify-content: center; align-content: center;
align-content: center; align-items: center;
align-items: center; flex-shrink: 0;
flex-shrink: 0; position: relative;
position: relative; .background-dark {
.background-dark { position: absolute;
position: absolute; top: 0;
top: 0; bottom: 0;
bottom: 0; left: 0;
left: 0; right: 0;
right: 0; background: rgba(0, 0, 0, 0.6);
background: rgba(0, 0, 0, 0.6); background-position: center;
} background-size: cover;
background-image: url('../../../../assets/background.jpg'); &::before {
background-position: center; content: "";
background-size: cover; position: absolute;
.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%; height: 100%;
flex-shrink: 0; width: 100%;
background: rgba(0, 0, 0, 0.6);
.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;
}
}
} }
} }
.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> </style>

View file

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

View file

@ -9,12 +9,27 @@ const prototype = {
}; };
const config = [ 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, version: 7.8,
title: "Redesigns!", title: "Redesigns!",
shortTitle: "", shortTitle: "",
date: "01/11/2019", date: "01/11/2019",
headColor: "#0c7b7f",
new: [ new: [
"Layout has been redesigned.", "Layout has been redesigned.",
"Added an option to mute notification sounds.", "Added an option to mute notification sounds.",

View file

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

View file

@ -11,7 +11,12 @@
Login Login
</div> </div>
<div class="info">Login to access Nertivia</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">
<div class="input-text"> <div class="input-text">
Email Email
@ -97,6 +102,11 @@ export default {
submitForm() { submitForm() {
this.showCaptcha = true; this.showCaptcha = true;
}, },
keyDownEvent(event) {
if (event.keyCode === 13) {
this.submitForm();
}
},
async login() { async login() {
if (this.deactive === true) return; if (this.deactive === true) return;
this.resetValues(); this.resetValues();

View file

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