|
@@ -1,14 +1,52 @@
|
|
<template>
|
|
<template>
|
|
<div class="content profile-tab">
|
|
<div class="content profile-tab">
|
|
- <p class="control is-expanded">
|
|
|
|
|
|
+ <h4 class="section-title">
|
|
|
|
+ Change Profile
|
|
|
|
+ </h4>
|
|
|
|
+ <p class="section-description">
|
|
|
|
+ Edit your public profile so other users can find out more about you.
|
|
|
|
+ </p>
|
|
|
|
+
|
|
|
|
+ <hr class="section-horizontal-rule" />
|
|
|
|
+
|
|
|
|
+ <div
|
|
|
|
+ class="control is-expanded avatar-selection-outer-container"
|
|
|
|
+ v-if="modifiedUser.avatar"
|
|
|
|
+ >
|
|
|
|
+ <label>Avatar</label>
|
|
|
|
+ <div id="avatar-selection-inner-container">
|
|
|
|
+ <div class="profile-picture">
|
|
|
|
+ <img
|
|
|
|
+ :src="
|
|
|
|
+ modifiedUser.avatar.url &&
|
|
|
|
+ modifiedUser.avatar.type === 'gravatar'
|
|
|
|
+ ? `${modifiedUser.avatar.url}?d=${notesUri}&s=250`
|
|
|
|
+ : '/assets/notes.png'
|
|
|
|
+ "
|
|
|
|
+ onerror="this.src='/assets/notes.png'; this.onerror=''"
|
|
|
|
+ />
|
|
|
|
+ </div>
|
|
|
|
+ <div class="select">
|
|
|
|
+ <select v-model="modifiedUser.avatar.type">
|
|
|
|
+ <option value="gravatar">Using Gravatar</option>
|
|
|
|
+ <option value="initials">Based on initials</option>
|
|
|
|
+ </select>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <p class="control is-expanded margin-top-zero">
|
|
<label for="name">Name</label>
|
|
<label for="name">Name</label>
|
|
<input
|
|
<input
|
|
class="input"
|
|
class="input"
|
|
id="name"
|
|
id="name"
|
|
type="text"
|
|
type="text"
|
|
- placeholder="Name"
|
|
|
|
|
|
+ placeholder="Enter name here..."
|
|
|
|
+ maxlength="64"
|
|
v-model="modifiedUser.name"
|
|
v-model="modifiedUser.name"
|
|
/>
|
|
/>
|
|
|
|
+ <span v-if="modifiedUser.name" class="character-counter"
|
|
|
|
+ >{{ modifiedUser.name.length }}/64</span
|
|
|
|
+ >
|
|
</p>
|
|
</p>
|
|
<p class="control is-expanded">
|
|
<p class="control is-expanded">
|
|
<label for="location">Location</label>
|
|
<label for="location">Location</label>
|
|
@@ -16,34 +54,44 @@
|
|
class="input"
|
|
class="input"
|
|
id="location"
|
|
id="location"
|
|
type="text"
|
|
type="text"
|
|
- placeholder="Location"
|
|
|
|
|
|
+ placeholder="Enter location here..."
|
|
|
|
+ maxlength="50"
|
|
v-model="modifiedUser.location"
|
|
v-model="modifiedUser.location"
|
|
/>
|
|
/>
|
|
|
|
+ <span v-if="modifiedUser.location" class="character-counter"
|
|
|
|
+ >{{ modifiedUser.location.length }}/50</span
|
|
|
|
+ >
|
|
</p>
|
|
</p>
|
|
<p class="control is-expanded">
|
|
<p class="control is-expanded">
|
|
<label for="bio">Bio</label>
|
|
<label for="bio">Bio</label>
|
|
<textarea
|
|
<textarea
|
|
class="textarea"
|
|
class="textarea"
|
|
id="bio"
|
|
id="bio"
|
|
- placeholder="Bio"
|
|
|
|
|
|
+ placeholder="Enter bio here..."
|
|
|
|
+ maxlength="200"
|
|
|
|
+ autocomplete="off"
|
|
v-model="modifiedUser.bio"
|
|
v-model="modifiedUser.bio"
|
|
/>
|
|
/>
|
|
|
|
+ <span
|
|
|
|
+ v-if="modifiedUser.bio"
|
|
|
|
+ class="character-counter"
|
|
|
|
+ style="height: initial"
|
|
|
|
+ >{{ modifiedUser.bio.length }}/200</span
|
|
|
|
+ >
|
|
</p>
|
|
</p>
|
|
- <div class="control is-expanded avatar-select">
|
|
|
|
- <label>Avatar</label>
|
|
|
|
- <div class="select">
|
|
|
|
- <select
|
|
|
|
- v-if="modifiedUser.avatar"
|
|
|
|
- v-model="modifiedUser.avatar.type"
|
|
|
|
- >
|
|
|
|
- <option value="gravatar">Using Gravatar</option>
|
|
|
|
- <option value="initials">Based on initials</option>
|
|
|
|
- </select>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- <button class="button is-primary" @click="saveChangesToProfile()">
|
|
|
|
- Save changes
|
|
|
|
- </button>
|
|
|
|
|
|
+ <transition name="saved-changes-transition" mode="out-in">
|
|
|
|
+ <button
|
|
|
|
+ class="button is-primary save-changes"
|
|
|
|
+ v-if="!savedChanges"
|
|
|
|
+ @click="saveChanges()"
|
|
|
|
+ key="save"
|
|
|
|
+ >
|
|
|
|
+ Save changes
|
|
|
|
+ </button>
|
|
|
|
+ <button class="button is-success save-changes" key="saved" v-else>
|
|
|
|
+ <i class="material-icons icon-with-button">done</i>Saved Changes
|
|
|
|
+ </button>
|
|
|
|
+ </transition>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
|
|
|
|
@@ -55,18 +103,31 @@ import validation from "../../../validation";
|
|
import io from "../../../io";
|
|
import io from "../../../io";
|
|
|
|
|
|
export default {
|
|
export default {
|
|
|
|
+ data() {
|
|
|
|
+ return {
|
|
|
|
+ notesUri: "",
|
|
|
|
+ savedChanges: false
|
|
|
|
+ };
|
|
|
|
+ },
|
|
computed: mapState({
|
|
computed: mapState({
|
|
userId: state => state.user.auth.userId,
|
|
userId: state => state.user.auth.userId,
|
|
originalUser: state => state.settings.originalUser,
|
|
originalUser: state => state.settings.originalUser,
|
|
modifiedUser: state => state.settings.modifiedUser
|
|
modifiedUser: state => state.settings.modifiedUser
|
|
}),
|
|
}),
|
|
mounted() {
|
|
mounted() {
|
|
|
|
+ lofig.get("frontendDomain").then(frontendDomain => {
|
|
|
|
+ this.frontendDomain = frontendDomain;
|
|
|
|
+ this.notesUri = encodeURI(
|
|
|
|
+ `${this.frontendDomain}/assets/notes.png`
|
|
|
|
+ );
|
|
|
|
+ });
|
|
|
|
+
|
|
io.getSocket(socket => {
|
|
io.getSocket(socket => {
|
|
this.socket = socket;
|
|
this.socket = socket;
|
|
});
|
|
});
|
|
},
|
|
},
|
|
methods: {
|
|
methods: {
|
|
- saveChangesToProfile() {
|
|
|
|
|
|
+ saveChanges() {
|
|
if (this.modifiedUser.name !== this.originalUser.name)
|
|
if (this.modifiedUser.name !== this.originalUser.name)
|
|
this.changeName();
|
|
this.changeName();
|
|
if (this.modifiedUser.location !== this.originalUser.location)
|
|
if (this.modifiedUser.location !== this.originalUser.location)
|
|
@@ -76,6 +137,12 @@ export default {
|
|
if (this.modifiedUser.avatar.type !== this.originalUser.avatar.type)
|
|
if (this.modifiedUser.avatar.type !== this.originalUser.avatar.type)
|
|
this.changeAvatarType();
|
|
this.changeAvatarType();
|
|
},
|
|
},
|
|
|
|
+ showSavedAnimation() {
|
|
|
|
+ this.savedChanges = true;
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ this.savedChanges = false;
|
|
|
|
+ }, 2000);
|
|
|
|
+ },
|
|
changeName() {
|
|
changeName() {
|
|
const { name } = this.modifiedUser;
|
|
const { name } = this.modifiedUser;
|
|
|
|
|
|
@@ -98,7 +165,12 @@ export default {
|
|
timeout: 4000
|
|
timeout: 4000
|
|
});
|
|
});
|
|
|
|
|
|
- this.updateOriginalUser("name", name);
|
|
|
|
|
|
+ this.updateOriginalUser({
|
|
|
|
+ property: "name",
|
|
|
|
+ value: name
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ if (!this.savedChanges) this.showSavedAnimation();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
);
|
|
);
|
|
@@ -125,7 +197,12 @@ export default {
|
|
timeout: 4000
|
|
timeout: 4000
|
|
});
|
|
});
|
|
|
|
|
|
- this.updateOriginalUser("location", location);
|
|
|
|
|
|
+ this.updateOriginalUser({
|
|
|
|
+ property: "location",
|
|
|
|
+ value: location
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ if (!this.savedChanges) this.showSavedAnimation();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
);
|
|
);
|
|
@@ -152,18 +229,23 @@ export default {
|
|
timeout: 4000
|
|
timeout: 4000
|
|
});
|
|
});
|
|
|
|
|
|
- this.updateOriginalUser("bio", bio);
|
|
|
|
|
|
+ this.updateOriginalUser({
|
|
|
|
+ property: "bio",
|
|
|
|
+ value: bio
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ if (!this.savedChanges) this.showSavedAnimation();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
);
|
|
);
|
|
},
|
|
},
|
|
changeAvatarType() {
|
|
changeAvatarType() {
|
|
- const { type } = this.modifiedUser.avatar;
|
|
|
|
|
|
+ const { avatar } = this.modifiedUser;
|
|
|
|
|
|
return this.socket.emit(
|
|
return this.socket.emit(
|
|
"users.updateAvatarType",
|
|
"users.updateAvatarType",
|
|
this.userId,
|
|
this.userId,
|
|
- type,
|
|
|
|
|
|
+ avatar.type,
|
|
res => {
|
|
res => {
|
|
if (res.status !== "success")
|
|
if (res.status !== "success")
|
|
new Toast({ content: res.message, timeout: 8000 });
|
|
new Toast({ content: res.message, timeout: 8000 });
|
|
@@ -173,7 +255,12 @@ export default {
|
|
timeout: 4000
|
|
timeout: 4000
|
|
});
|
|
});
|
|
|
|
|
|
- this.updateOriginalUser("avatar.type", type);
|
|
|
|
|
|
+ this.updateOriginalUser({
|
|
|
|
+ property: "avatar",
|
|
|
|
+ value: avatar
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ if (!this.savedChanges) this.showSavedAnimation();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
);
|
|
);
|
|
@@ -190,7 +277,7 @@ export default {
|
|
margin-bottom: 15px;
|
|
margin-bottom: 15px;
|
|
}
|
|
}
|
|
|
|
|
|
-.avatar-select {
|
|
|
|
|
|
+.avatar-selection-outer-container {
|
|
display: flex;
|
|
display: flex;
|
|
flex-direction: column;
|
|
flex-direction: column;
|
|
align-items: flex-start;
|
|
align-items: flex-start;
|
|
@@ -198,5 +285,25 @@ export default {
|
|
.select:after {
|
|
.select:after {
|
|
border-color: $musare-blue;
|
|
border-color: $musare-blue;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ #avatar-selection-inner-container {
|
|
|
|
+ display: flex;
|
|
|
|
+ align-items: center;
|
|
|
|
+ margin-top: 5px;
|
|
|
|
+
|
|
|
|
+ .profile-picture {
|
|
|
|
+ line-height: 1;
|
|
|
|
+ cursor: pointer;
|
|
|
|
+
|
|
|
|
+ img {
|
|
|
|
+ background-color: #fff;
|
|
|
|
+ width: 50px;
|
|
|
|
+ height: 50px;
|
|
|
|
+ border-radius: 100%;
|
|
|
|
+ border: 2px solid $light-grey;
|
|
|
|
+ margin-right: 10px;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
</style>
|
|
</style>
|