mirror of
https://github.com/danbulant/Nertivia-Client
synced 2026-06-24 17:11:43 +00:00
made a template for profile picture
This commit is contained in:
parent
46668093ca
commit
16792cbf4b
6 changed files with 143 additions and 95 deletions
27
src/components/ProfilePictureTemplate.vue
Normal file
27
src/components/ProfilePictureTemplate.vue
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="profile-picture"
|
||||||
|
:style="`height: ${$props.height}; width: ${$props.width}; background-image: url(${$props.url})`"
|
||||||
|
></div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: ['url', 'height', 'width']
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.profile-picture {
|
||||||
|
background-color: rgba(0, 0, 0, 0.281);
|
||||||
|
margin: auto;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-right: 5px;
|
||||||
|
margin-left: 0;
|
||||||
|
flex-shrink: 0;
|
||||||
|
background-position: center;
|
||||||
|
background-size: cover;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div :class="{message: true, ownMessage: user.uniqueID === $props.uniqueID}">
|
<div :class="{message: true, ownMessage: user.uniqueID === $props.uniqueID}">
|
||||||
<div class="profile-picture" :style="`background-image: url(${userAvatar})`"></div>
|
<profile-picture :url="userAvatar" height="50px" width="50px"/>
|
||||||
<div class="triangle">
|
<div class="triangle">
|
||||||
<div class="triangle-inner"></div>
|
<div class="triangle-inner"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -33,12 +33,16 @@
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import ProfilePicture from "@/components/ProfilePictureTemplate.vue";
|
||||||
import messageFormatter from "@/messageFormatter.js";
|
import messageFormatter from "@/messageFormatter.js";
|
||||||
import config from "@/config.js";
|
import config from "@/config.js";
|
||||||
import friendlyDate from "@/date";
|
import friendlyDate from "@/date";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
components: {
|
||||||
|
ProfilePicture
|
||||||
|
},
|
||||||
props: [
|
props: [
|
||||||
"message",
|
"message",
|
||||||
"status",
|
"status",
|
||||||
|
|
@ -72,7 +76,7 @@ export default {
|
||||||
const filetypes = /jpeg|jpg|gif|png/;
|
const filetypes = /jpeg|jpg|gif|png/;
|
||||||
const extname = filetypes.test(path.extname(file.fileName).toLowerCase());
|
const extname = filetypes.test(path.extname(file.fileName).toLowerCase());
|
||||||
if (extname) return undefined;
|
if (extname) return undefined;
|
||||||
file.url = config.domain + '/files/' + file.fileID;
|
file.url = config.domain + "/files/" + file.fileID;
|
||||||
return file;
|
return file;
|
||||||
},
|
},
|
||||||
formatMessage() {
|
formatMessage() {
|
||||||
|
|
@ -170,18 +174,7 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
.profile-picture {
|
.profile-picture {
|
||||||
height: 50px;
|
|
||||||
width: 50px;
|
|
||||||
background-color: rgba(0, 0, 0, 0.281);
|
|
||||||
margin: auto;
|
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
border-radius: 50%;
|
|
||||||
margin-right: 5px;
|
|
||||||
margin-left: 0;
|
|
||||||
flex-shrink: 0;
|
|
||||||
background-position: center;
|
|
||||||
background-size: cover;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.triangle {
|
.triangle {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="my-mini-information">
|
<div class="my-mini-information">
|
||||||
<div class="profile-picture" :style="`background-image: url(${avatar})`"></div>
|
<profile-picture :url="avatar" height="50px" width="50px"/>
|
||||||
<div class="information">
|
<div class="information">
|
||||||
<div class="name">{{user.username}}</div>
|
<div class="name">{{user.username}}</div>
|
||||||
<div class="tag">@{{user.tag}}</div>
|
<div class="tag">@{{user.tag}}</div>
|
||||||
|
|
@ -24,10 +24,12 @@ import {bus} from '../../main';
|
||||||
import config from '@/config.js'
|
import config from '@/config.js'
|
||||||
import statusList from '../../components/app/statusList.vue'
|
import statusList from '../../components/app/statusList.vue'
|
||||||
import settingsService from '@/services/settingsService'
|
import settingsService from '@/services/settingsService'
|
||||||
|
import ProfilePicture from "@/components/ProfilePictureTemplate.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
statusList
|
statusList,
|
||||||
|
ProfilePicture
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
@ -104,15 +106,8 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
.profile-picture{
|
.profile-picture{
|
||||||
height: 50px;
|
|
||||||
width: 50px;
|
|
||||||
border-radius: 50%;
|
|
||||||
background-color: rgba(0, 0, 0, 0.377);
|
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
background-position: center;
|
|
||||||
background-size: cover;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.information{
|
.information{
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,26 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="my-profile-panel">
|
<div class="my-profile-panel">
|
||||||
<div class="profile-picture" :style="`background-image: url(${avatar})`"></div>
|
<profile-picture :url="avatar" height="100px" width="100px" />
|
||||||
<div class="information">
|
<div class="information">
|
||||||
<div class="username"><strong>Username: </strong>{{user.username}}</div>
|
<div class="username">
|
||||||
<div class="tag"><strong>Tag: </strong>@{{user.tag}}</div>
|
<strong>Username:</strong>
|
||||||
|
{{user.username}}
|
||||||
|
</div>
|
||||||
|
<div class="tag">
|
||||||
|
<strong>Tag:</strong>
|
||||||
|
@{{user.tag}}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="options">
|
<div class="options">
|
||||||
<input type="file" accept="image/*" ref="avatarBrowser" @change="avatarBrowse" class="hidden">
|
<input type="file" accept="image/*" ref="avatarBrowser" @change="avatarBrowse" class="hidden">
|
||||||
<div class="option" @click="editAvatarBtn">Edit Avatar</div>
|
<div class="option" @click="editAvatarBtn">Edit Avatar</div>
|
||||||
<div class="option" @click="changePassword">Change Password</div>
|
<div class="option" @click="changePassword">Change Password</div>
|
||||||
<div class="option red" @click="logout">Logout</div>
|
<div class="option red" @click="logout">Logout</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="alert-outer" v-if="alert.show">
|
<div class="alert-outer" v-if="alert.show">
|
||||||
<div class="alert" >
|
<div class="alert">
|
||||||
<div class="alert-title">Error</div>
|
<div class="alert-title">Error</div>
|
||||||
<div class="alert-content">
|
<div class="alert-content">{{alert.content}}</div>
|
||||||
{{alert.content}}
|
|
||||||
</div>
|
|
||||||
<div class="alert-buttons">
|
<div class="alert-buttons">
|
||||||
<div class="alert-button" @click="alert.show = false">Okay</div>
|
<div class="alert-button" @click="alert.show = false">Okay</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -26,93 +30,95 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import AvatarUpload from '@/services/AvatarUpload.js'
|
import ProfilePicture from "@/components/ProfilePictureTemplate.vue";
|
||||||
import config from '@/config.js'
|
import AvatarUpload from "@/services/AvatarUpload.js";
|
||||||
import {bus} from '@/main'
|
import config from "@/config.js";
|
||||||
import path from 'path'
|
import { bus } from "@/main";
|
||||||
|
import path from "path";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
components: {
|
||||||
data(){
|
ProfilePicture
|
||||||
|
},
|
||||||
|
data() {
|
||||||
return {
|
return {
|
||||||
alert: {
|
alert: {
|
||||||
content: '',
|
content: "",
|
||||||
show: false
|
show: false
|
||||||
},
|
}
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
onProgress(percent){
|
onProgress(percent) {
|
||||||
//update vue
|
//update vue
|
||||||
console.log("Avatar upload progress: ", percent)
|
console.log("Avatar upload progress: ", percent);
|
||||||
},
|
},
|
||||||
async avatarBrowse(event) {
|
async avatarBrowse(event) {
|
||||||
const file = event.target.files[0];
|
const file = event.target.files[0];
|
||||||
event.target.value = "";
|
event.target.value = "";
|
||||||
const allowedFormats = ['.png', '.jpeg', '.gif', '.jpg' ];
|
const allowedFormats = [".png", ".jpeg", ".gif", ".jpg"];
|
||||||
|
|
||||||
if (!allowedFormats.includes(path.extname(file.name).toLowerCase())){
|
if (!allowedFormats.includes(path.extname(file.name).toLowerCase())) {
|
||||||
this.alert.content = 'Upload failed - Unsupported image file.';
|
this.alert.content = "Upload failed - Unsupported image file.";
|
||||||
return this.alert.show = true;
|
return (this.alert.show = true);
|
||||||
} else if (file.size >= 10490000){
|
} else if (file.size >= 10490000) {
|
||||||
// 10490000 = 10mb
|
// 10490000 = 10mb
|
||||||
this.alert.content = 'Upload failed - Image size must be less than 10 megabytes.';
|
this.alert.content =
|
||||||
return this.alert.show = true;
|
"Upload failed - Image size must be less than 10 megabytes.";
|
||||||
|
return (this.alert.show = true);
|
||||||
}
|
}
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append('avatar', file);
|
formData.append("avatar", file);
|
||||||
const {ok, error, result} = await AvatarUpload.uploadAvatar(formData, this.onProgress);
|
const { ok, error, result } = await AvatarUpload.uploadAvatar(
|
||||||
if (!ok) {
|
formData,
|
||||||
this.alert.content = 'Upload failed - Something went wrong. Try again later.';
|
this.onProgress
|
||||||
return this.alert.show = true;
|
);
|
||||||
|
if (!ok) {
|
||||||
|
this.alert.content =
|
||||||
|
"Upload failed - Something went wrong. Try again later.";
|
||||||
|
return (this.alert.show = true);
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
logout() {
|
logout() {
|
||||||
this.$store.dispatch('logout')
|
this.$store.dispatch("logout");
|
||||||
window.location.href = "/"
|
window.location.href = "/";
|
||||||
},
|
},
|
||||||
changePassword() {
|
changePassword() {
|
||||||
this.alert.content = 'Not implemented yet.';
|
this.alert.content = "Not implemented yet.";
|
||||||
return this.alert.show = true;
|
return (this.alert.show = true);
|
||||||
},
|
},
|
||||||
editAvatarBtn() {
|
editAvatarBtn() {
|
||||||
if(!this.$store.getters.settings.GDriveLinked) {
|
if (!this.$store.getters.settings.GDriveLinked) {
|
||||||
return this.$store.dispatch('setPopoutVisibility', {name: 'GDLinkMenu', visibility: true})
|
return this.$store.dispatch("setPopoutVisibility", {
|
||||||
|
name: "GDLinkMenu",
|
||||||
|
visibility: true
|
||||||
|
});
|
||||||
}
|
}
|
||||||
this.$refs.avatarBrowser.click()
|
this.$refs.avatarBrowser.click();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
user() {
|
user() {
|
||||||
return this.$store.getters.user
|
return this.$store.getters.user;
|
||||||
},
|
},
|
||||||
avatar() {
|
avatar() {
|
||||||
return config.domain + "/avatars/" +this.$store.getters.user.avatar
|
return config.domain + "/avatars/" + this.$store.getters.user.avatar;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.hidden {
|
.hidden {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
.my-profile-panel{
|
.my-profile-panel {
|
||||||
display: flex;
|
display: flex;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100px;
|
height: 100px;
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
.profile-picture {
|
.profile-picture {
|
||||||
width: 100px;
|
|
||||||
height: 100px;
|
|
||||||
background: rgb(63, 63, 63);
|
|
||||||
border-radius: 50%;
|
|
||||||
margin-left: 20px;
|
margin-left: 20px;
|
||||||
flex-shrink: 0;
|
|
||||||
background-position: center;
|
|
||||||
background-size: cover;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
}
|
}
|
||||||
.information {
|
.information {
|
||||||
margin: auto;
|
margin: auto;
|
||||||
|
|
@ -121,10 +127,10 @@ export default {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
.username{
|
.username {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
.options{
|
.options {
|
||||||
margin: auto;
|
margin: auto;
|
||||||
margin-right: 30px;
|
margin-right: 30px;
|
||||||
border-left: solid 1px rgb(204, 204, 204);
|
border-left: solid 1px rgb(204, 204, 204);
|
||||||
|
|
@ -137,7 +143,7 @@ export default {
|
||||||
transition: 0.3s;
|
transition: 0.3s;
|
||||||
}
|
}
|
||||||
.option:hover {
|
.option:hover {
|
||||||
color: rgb(255, 255, 255);
|
color: rgb(255, 255, 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
.option.red {
|
.option.red {
|
||||||
|
|
@ -146,7 +152,7 @@ export default {
|
||||||
.option.red:hover {
|
.option.red:hover {
|
||||||
color: red;
|
color: red;
|
||||||
}
|
}
|
||||||
.alert-title{
|
.alert-title {
|
||||||
background: rgb(34, 34, 34);
|
background: rgb(34, 34, 34);
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
color: white;
|
color: white;
|
||||||
|
|
@ -159,7 +165,7 @@ export default {
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
background: rgba(0, 0, 0, 0.267)
|
background: rgba(0, 0, 0, 0.267);
|
||||||
}
|
}
|
||||||
.alert {
|
.alert {
|
||||||
margin: auto;
|
margin: auto;
|
||||||
|
|
@ -171,7 +177,7 @@ export default {
|
||||||
user-select: none;
|
user-select: none;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
}
|
||||||
.alert-content{
|
.alert-content {
|
||||||
margin: auto;
|
margin: auto;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
color: white;
|
color: white;
|
||||||
|
|
@ -183,7 +189,6 @@ export default {
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
|
|
||||||
}
|
}
|
||||||
.alert-button {
|
.alert-button {
|
||||||
color: white;
|
color: white;
|
||||||
|
|
@ -193,10 +198,10 @@ export default {
|
||||||
transition: 0.3s;
|
transition: 0.3s;
|
||||||
}
|
}
|
||||||
.alert-button:hover {
|
.alert-button:hover {
|
||||||
background: rgb(83, 53, 53);
|
background: rgb(83, 53, 53);
|
||||||
}
|
}
|
||||||
@media (max-width: 815px) {
|
@media (max-width: 815px) {
|
||||||
.my-profile-panel{
|
.my-profile-panel {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
.profile-picture {
|
.profile-picture {
|
||||||
|
|
@ -213,5 +218,5 @@ export default {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -287,5 +287,35 @@ export default {
|
||||||
outline: none;
|
outline: none;
|
||||||
transition: 0.3s;
|
transition: 0.3s;
|
||||||
}
|
}
|
||||||
|
@media (max-width: 400px) {
|
||||||
|
.inner {
|
||||||
|
align-content: center;
|
||||||
|
align-items: center;
|
||||||
|
align-self: center;
|
||||||
|
}
|
||||||
|
.info {
|
||||||
|
flex-direction:column;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
align-content: center;
|
||||||
|
align-items: center;
|
||||||
|
align-self: center;
|
||||||
|
}
|
||||||
|
.data{
|
||||||
|
display: flex;
|
||||||
|
flex-direction:column;
|
||||||
|
align-content: center;
|
||||||
|
align-items: center;
|
||||||
|
align-self: center;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.bottom-panel {
|
||||||
|
align-content: center;
|
||||||
|
align-items: center;
|
||||||
|
align-self: center;
|
||||||
|
}
|
||||||
|
.message-area {
|
||||||
|
width: calc(100% - 20px);
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
<div class="logged-in">
|
<div class="logged-in">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="avatar-outer">
|
<div class="avatar-outer">
|
||||||
<div class="avatar" :style="`background-image: url(${avatar})`"></div>
|
<profile-picture :url="avatar" height="90px" width="90px" />
|
||||||
</div>
|
</div>
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<div class="username">{{user.username}}<span class="tag">@{{user.tag}}</span></div>
|
<div class="username">{{user.username}}<span class="tag">@{{user.tag}}</span></div>
|
||||||
|
|
@ -16,8 +16,12 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import ProfilePicture from "@/components/ProfilePictureTemplate.vue";
|
||||||
import config from '@/config.js'
|
import config from '@/config.js'
|
||||||
export default {
|
export default {
|
||||||
|
components: {
|
||||||
|
ProfilePicture
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
logout() {
|
logout() {
|
||||||
this.$store.commit('logout')
|
this.$store.commit('logout')
|
||||||
|
|
@ -69,14 +73,8 @@ export default {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatar {
|
.profile-picture {
|
||||||
width: 80px;
|
margin-right: 0;
|
||||||
height: 80px;
|
|
||||||
background-color: rgba(0, 0, 0, 0.459);
|
|
||||||
border-radius: 50%;
|
|
||||||
background-position: center;
|
|
||||||
background-size: 100%;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.info {
|
.info {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue