"Knowing who you are"

Work on issue #128.
This commit is contained in:
N-Pex 2021-06-17 20:56:25 +02:00
parent 36ca5b50ff
commit 18f1945c19
10 changed files with 323 additions and 61 deletions

View file

@ -0,0 +1,32 @@
<template>
<v-row class="action-row ma-0 pa-0" no-gutters align-content="center" v-on="$listeners">
<v-col cols="auto" class="mr-2">
<v-icon size="22">{{ icon }}</v-icon>
</v-col>
<v-col>{{ text }}</v-col>
</v-row>
</template>
<script>
export default {
name: "ActionRow",
props: {
icon: {
type: String,
default: function () {
return null;
},
},
text: {
type: String,
default: function () {
return "";
},
},
},
};
</script>
<style lang="scss">
@import "@/assets/css/chat.scss";
</style>

View file

@ -18,26 +18,42 @@
<v-col cols="auto" class="text-end ma-0 pa-0">
<v-btn text class="leave-button" @click.stop="leaveRoom">{{$t('room.leave')}}</v-btn>
</v-col>
<v-col cols="auto" class="text-end ma-0 pa-0 ml-2">
<v-avatar class="avatar-32 clickable" size="32" color="#e0e0e0" @click.stop="showProfileInfo = true">
<img v-if="userAvatar" :src="userAvatar" />
<span v-else class="white--text">{{
userAvatarLetter
}}</span>
</v-avatar>
</v-col>
</v-row>
<!-- "REALLY LEAVE?" dialog -->
<LeaveRoomDialog :show="showLeaveConfirmation" :room="room" @close="showLeaveConfirmation = false" />
<!-- PROFILE INFO POPUP -->
<ProfileInfoPopup :show="showProfileInfo" @close="showProfileInfo = false" />
</v-container>
</template>
<script>
import LeaveRoomDialog from '../components/LeaveRoomDialog';
import ProfileInfoPopup from '../components/ProfileInfoPopup';
import profileInfoMixin from '../components/profileInfoMixin';
export default {
name: "ChatHeader",
mixins: [profileInfoMixin],
components: {
LeaveRoomDialog
LeaveRoomDialog,
ProfileInfoPopup
},
data() {
return {
memberCount: null,
showLeaveConfirmation: false
showLeaveConfirmation: false,
showProfileInfo: false
};
},
mounted() {

View file

@ -35,8 +35,10 @@
</v-row>
</v-container>
<div class="action" @click="showEditPasswordDialog = true"><v-icon>lock</v-icon><span>{{$t('profile.set_password')}}</span></div>
<div class="action" @click="editValue = displayName;showEditDisplaynameDialog = true"><v-icon>edit</v-icon><span>{{$t('profile.change_name')}}</span></div>
<v-container class="mt-2 pa-5">
<ActionRow @click="showEditPasswordDialog = true" :icon="'lock'" :text="$t('profile.set_password')" />
<ActionRow @click="editValue = displayName;showEditDisplaynameDialog = true" :icon="'edit'" :text="$t('profile.change_name')" />
</v-container>
<!-- edit password dialog -->
<v-dialog v-model="showEditPasswordDialog" class="ma-0 pa-0" width="50%">
@ -92,8 +94,13 @@
</template>
<script>
import ActionRow from "./ActionRow.vue";
export default {
name: "Profile",
components: {
ActionRow
},
data() {
return {
showEditPasswordDialog: false,
@ -142,14 +149,6 @@ export default {
},
methods: {
logout() {
//TODO - For guest accounts, show warning about not being able to rejoin.
this.$store.dispatch("logout");
this.$nextTick(() => {
this.$navigation.push({path: "/login"}, -1);
})
},
setDisplayName(name) {
this.$matrix.matrixClient.setDisplayName(name);
},

View file

@ -0,0 +1,162 @@
<template>
<v-dialog
v-model="showDialog"
content-class="profile-info-popup"
class="ma-0 pa-0"
:width="$vuetify.breakpoint.smAndUp ? '60%' : '95%'"
>
<v-card flat>
<v-card-text>
<div class="you-are">{{ $t("profile_info_popup.you_are") }}</div>
<v-container fluid>
<v-row>
<v-col class="username" cols="pa-2">
<div v-if="$matrix.currentUser.is_guest">
<i18n path="profile_info_popup.identity_temporary" tag="span">
<template v-slot:displayName>
<b>{{ displayName }}</b>
</template>
</i18n>
</div>
<div v-else>
<i18n path="profile_info_popup.identity" tag="span">
<template v-slot:displayName>
<b>{{ displayName }}</b>
</template>
</i18n>
</div>
</v-col>
<v-col cols="auto" class="pa-2">
<v-avatar
class="avatar-32"
size="32"
color="#e0e0e0"
@click.stop="showProfileInfo = true"
>
<img v-if="userAvatar" :src="userAvatar" />
<span v-else class="white--text">{{ userAvatarLetter }}</span>
</v-avatar>
</v-col>
</v-row>
</v-container>
<v-container class="mt-4 pa-0">
<ActionRow @click="viewProfile" :icon="'account_circle'" :text="$t('profile_info_popup.edit_profile')" />
<ActionRow @click="logout" :icon="'logout'" :text="$t('profile_info_popup.logout')" />
</v-container>
<div class="more-container">
<div class="want_more">🙌 {{$t('profile_info_popup.want_more')}}</div>
<i18n path="profile_info_popup.powered_by" tag="div">
<template v-slot:product>{{ product }}</template>
<template v-slot:productLink>
<a :href="productLink">{{ productLink }}</a>
</template>
</i18n>
<div style="position:relative;width:100%;height: 40px">
<v-btn class="new_room" right absolute text @click="createRoom">{{ $t('profile_info_popup.new_room') }}</v-btn></div>
</div>
</v-card-text>
</v-card>
</v-dialog>
</template>
<script>
import profileInfoMixin from "./profileInfoMixin";
import ActionRow from "./ActionRow.vue";
import config from "../assets/config";
export default {
name: "ProfileInfoPopup",
mixins: [profileInfoMixin],
components: {
ActionRow
},
props: {
show: {
type: Boolean,
default: function () {
return false;
},
},
},
data() {
return {
showDialog: false,
};
},
computed: {
product() {
return config.product;
},
productLink() {
return config.productLink;
}
},
watch: {
show: {
handler(newVal, ignoredOldVal) {
this.showDialog = newVal;
},
},
showDialog() {
if (!this.showDialog) {
this.$emit("close");
}
},
},
methods: {
viewProfile() {
this.showDialog = false;
this.$navigation.push({ name: "Profile" }, 1);
},
createRoom() {
this.showDialog = false;
this.$navigation.push({ name: "CreateRoom" });
}
},
};
</script>
<style lang="scss">
@import "@/assets/css/chat.scss";
.profile-info-popup {
font-family: "Inter", sans-serif !important;
font-size: 16px;
position: fixed;
margin: 0px;
top: 70px;
right: 10px;
border-radius: 40px;
&::before {
content: '▲';
position: fixed;
top: 57px;
right: 22px;
color: white;
}
.you-are {
padding-top: 20px;
font-size: 12px;
}
.username {
border-radius: 4px;
background-color: #f5f5f5;
}
.more-container {
border-radius: 10px;
background-color: #f5f5f5;
padding: 20px;
.want_more {
font-family: "Poppins", sans-serif;
font-weight: 700;
font-size: 13 * $chat-text-size;
}
.new_room .v-btn__content {
font-family: "Poppins", sans-serif !important;
font-weight: 700 !important;
font-size: 13 * $chat-text-size !important;
}
}
}
</style>

View file

@ -170,35 +170,6 @@
>
</div>
<v-card class="account ma-3" flat>
<v-card-title class="h2">{{ $t("room_info.my_profile") }}</v-card-title>
<v-card-text>
<div>
<div v-if="$matrix.currentUser.is_guest">
<i18n path="room_info.identity_temporary" tag="span">
<template v-slot:displayName>
<b>{{ displayName }}</b>
</template>
</i18n>
</div>
<div v-else>
<i18n path="room_info.identity" tag="span">
<template v-slot:displayName>
<b>{{ displayName }}</b>
</template>
</i18n>
</div>
<v-btn
depressed
block
class="outlined-button"
@click.stop="viewProfile"
>{{ $t("room_info.view_profile") }}</v-btn
>
</div>
</v-card-text>
</v-card>
<div class="build-version">
{{ $t("room_info.version_info", { version: buildVersion }) }}
</div>

View file

@ -0,0 +1,44 @@
export default {
computed: {
user() {
if (!this.$matrix.matrixClient) {
return null;
}
return this.$matrix.matrixClient.getUser(this.$matrix.currentUserId);
},
displayName() {
if (!this.user) {
return null;
}
return (this.user.displayName || this.user.userId);
},
userAvatar() {
if (!this.user || !this.user.avatarUrl) {
return null;
}
return this.$matrix.matrixClient.mxcUrlToHttp(this.user.avatarUrl, 80, 80, 'scale', true);
},
userAvatarLetter() {
if (!this.user) {
return null;
}
return (this.user.displayName || this.user.userId.substring(1)).substring(0, 1).toUpperCase();
},
passwordsMatch() {
return this.newPassword1 && this.newPassword2 && this.newPassword1 == this.newPassword2;
}
},
methods: {
logout() {
//TODO - For guest accounts, show warning about not being able to rejoin.
this.$store.dispatch("logout");
this.$nextTick(() => {
this.$navigation.push({path: "/login"}, -1);
})
},
}
}