update user and room icons

update_chat
adb 4 years ago
parent d192046f85
commit 6e18eab9f8

@ -9,7 +9,9 @@
}, },
"dependencies": { "dependencies": {
"@modular-matrix/parse-mxc": "^1.0.1", "@modular-matrix/parse-mxc": "^1.0.1",
"@vue-polkadot/vue-identicon": "^0.0.8",
"core-js": "^3.6.5", "core-js": "^3.6.5",
"jdenticon": "^3.1.0",
"matrix-js-sdk": "^9.1.0", "matrix-js-sdk": "^9.1.0",
"sass": "^1.29.0", "sass": "^1.29.0",
"v-emoji-picker": "^2.3.1", "v-emoji-picker": "^2.3.1",

@ -11,11 +11,11 @@
</div> </div>
<h2 v-if="getMembers().length !== 0">members:</h2> <h2 v-if="getMembers().length !== 0">members:</h2>
<div v-for="member in getMembers().slice(0,20)" :key="member" class="contentBox" :title="member"> <div v-for="member in getMembers().slice(0,20)" :key="member" class="contentBox" :title="member">
<userThumbnail :mxcURL="getUser(member).avatarUrl" :userId="member" :username="getUser(member).displayName" <userThumbnail :mxcURL="getUser(member).avatarUrl" :fallback="getUser(member).displayName"
width="64" height="64" resizeMethod="scale" class="userThumbnail" /> class="userThumbnail" size="3"/>
<div class="information"> <div class="information">
<div class="userName">{{getUser(member).displayName || member}}</div> <div class="userName">{{getUser(member).displayName || member}}</div>
<div class="status"></div> <div class="status">{{getStatus(getUser(member))}}</div>
</div> </div>
</div> </div>
<p v-if="getMembers().length>20">and {{getMembers().length-20}} other members</p> <p v-if="getMembers().length>20">and {{getMembers().length-20}} other members</p>
@ -45,6 +45,8 @@ export default {
}, },
getMembers(){ getMembers(){
return Object.keys(this.room.currentState.members) return Object.keys(this.room.currentState.members)
},
getStatus(){
} }
} }
} }
@ -134,7 +136,8 @@ export default {
position: absolute; position: absolute;
left: 0; left: 0;
top: 0; top: 0;
background-color: #42a7b9; width: 3rem;
height: 3rem;
} }
.information{ .information{
position: absolute; position: absolute;

@ -3,7 +3,7 @@
<label for="newMessageInput"></label> <label for="newMessageInput"></label>
<textarea @keyup.enter.exact="sendMessage()" @input="resizeMessageBanner()" ref="newMessageInput" id="newMessageInput" class="newMessageInput" <textarea @keyup.enter.exact="sendMessage()" @input="resizeMessageBanner()" ref="newMessageInput" id="newMessageInput" class="newMessageInput"
autocomplete="off" rows="1" placeholder="type a message ..." v-model="msg.content.body" /> autocomplete="off" rows="1" placeholder="type a message ..." v-model="msg.content.body" />
<icon type="submit" title="press enter to submit" id="sendMessageBtn" <icon type="submit" title="press enter to submit" class="sendMessageBtn"
ic="./sym/ic_send_white_24px.svg" /> ic="./sym/ic_send_white_24px.svg" />
</form> </form>
</template> </template>
@ -67,16 +67,16 @@ export default {
left: 0; left: 0;
width: 100%; width: 100%;
height: min-content; height: min-content;
min-height: 4rem; min-height: 3.5rem;
background-color: #1d1d1d; background-color: #1d1d1d;
border-radius: 1rem 1rem 0 0; border-radius: 1rem 1rem 0 0;
} }
.newMessageInput{ .newMessageInput{
position: relative; position: relative;
margin-top: 1.5rem; margin-top: 1.25rem;
margin-bottom: 1rem; margin-bottom: 0.75rem;
left: 2rem; left: 2rem;
min-height: 1.25rem; min-height: 1.5rem;
max-height: 10rem; max-height: 10rem;
width: calc(100% - 7rem); width: calc(100% - 7rem);
height: 1.25rem; height: 1.25rem;
@ -90,9 +90,10 @@ export default {
vertical-align: middle; vertical-align: middle;
font-family: Avenir, Helvetica, Arial, sans-serif; font-family: Avenir, Helvetica, Arial, sans-serif;
} }
#sendMessageBtn{ .sendMessageBtn{
position: absolute; position: absolute;
right: 1rem; right: 1rem;
bottom: 0.5rem; bottom: 0.25rem;
background-color: unset;
} }
</style> </style>

@ -2,7 +2,8 @@
<div class="topBanner"> <div class="topBanner">
<div> <div>
<icon @click.native="closeChat()" class="smallIcon" id="icon-arrow" ic="./sym/arrow_back-24px.svg" /> <icon @click.native="closeChat()" class="smallIcon" id="icon-arrow" ic="./sym/arrow_back-24px.svg" />
<div @click="openChatInfo()" class="smallIcon" id="picTop">{{room.name.substr(0,2)}}</div> <userThumbnail @click.native="openChatInfo()" class="userThumbnail"
:mxcURL="getUrl()" :fallback="room.roomId" :size="3"/>
<div id="container"> <div id="container">
<div id="chatName">{{room.name}}</div> <div id="chatName">{{room.name}}</div>
<div id="users">{{Object.keys(room.currentState.members).length}} members</div> <div id="users">{{Object.keys(room.currentState.members).length}} members</div>
@ -12,13 +13,15 @@
</template> </template>
<script> <script>
import icon from '@/components/icon.vue'; import icon from '@/components/icon.vue';
import main from '@/main.js'; import {matrix} from "@/main";
import matrix from '@/matrix.js'; import userThumbnail from "@/components/userThumbnail";
import sdk from 'matrix-js-sdk'
export default { export default {
name: "topBanner", name: "topBanner",
components:{ components:{
icon, icon,
userThumbnail
}, },
props:{ props:{
room: [Object, undefined], room: [Object, undefined],
@ -27,8 +30,16 @@ export default {
}, },
data(){ data(){
return { return {
chatroom: main.data().chatroom, }
session: matrix.data().session },
methods: {
getRoom(roomId) {
return matrix.client.getRoom(roomId);
},
getUrl(){
let avatarState = this.room.getLiveTimeline().getState(sdk.EventTimeline.FORWARDS).getStateEvents("m.room.avatar");
return avatarState.length>0?avatarState[avatarState.length-1].getContent().url:undefined;
//return this.room.getLiveTimeline().getStateEvents("m.room.avatar");
} }
} }
} }
@ -39,7 +50,7 @@ export default {
top: 0; top: 0;
left: 0; left: 0;
width: 100%; width: 100%;
height: 3rem; height: 3.5rem;
background-color: #1d1d1d; background-color: #1d1d1d;
} }
.smallIcon{ .smallIcon{
@ -61,10 +72,12 @@ export default {
background-color: unset; background-color: unset;
box-shadow: none; box-shadow: none;
} }
#picTop{ .userThumbnail{
position: absolute; position: absolute;
top: 0.25rem;
left: 3.5rem; left: 3.5rem;
background-color: #42a7b9; width: 3rem;
height: 3rem;
} }
#container{ #container{
position: absolute; position: absolute;

@ -1,46 +1,50 @@
<template> <template>
<img v-if="mxcURL" :src="thumbnailUrl()" class="userThumbnail" /> <img v-if="mxcURL" :src="thumbnailUrl()" class="image"/>
<div v-else class="userThumbnail"> <Identicon v-else :value="fallback" :theme="'jdenticon'" :size="this.getFontSize()*this.size" class="identicon"/>
{{username?username.substr(0,2):userId.substr(1,2)}}
</div>
</template> </template>
<script> <script>
import parseMXC from '@modular-matrix/parse-mxc'; import parseMXC from '@modular-matrix/parse-mxc';
import {matrix} from "@/main"; import {matrix} from "@/main";
import Identicon from '@vue-polkadot/vue-identicon';
export default { export default {
name: "userThumbnail.vue", name: "userThumbnail.vue",
components: {
Identicon
},
props: { props: {
mxcURL: String, mxcURL: String,
username: String, username: String,
userId: String, fallback: String,
width: String, homeserver: String,
height: String, size: Number
resizeMethod: String,
homeserver: String
}, },
methods: { methods: {
thumbnailUrl(){ thumbnailUrl(){
let mxc = parseMXC.parse(this.mxcURL); let mxc = parseMXC.parse(this.mxcURL);
return `${this.homeserver||matrix.baseUrl}/_matrix/media/v1/thumbnail/${mxc.homeserver}/${mxc.id}?width=${this.width}&height=${this.height}&method=${this.resizeMethod}`; return `${this.homeserver||matrix.baseUrl}/_matrix/media/v1/thumbnail/${
mxc.homeserver}/${mxc.id}?width=${this.imageSize}&height=${this.imageSize}&method=${this.resizeMethod}`;
},
getFontSize(){
return window.getComputedStyle(document.body,null).fontSize.split("px", 1)||16;
} }
}, },
data(){ data(){
return { return {
resizeMethod: 'scale',
imageSize: 128
} }
} }
} }
</script> </script>
<style scoped> <style scoped lang="scss">
.userThumbnail{ .userThumbnail{
background-color: #42a7b9;
width: 3rem;
height: 3rem;
border-radius: 1.5rem; border-radius: 1.5rem;
} .image{
img.userThumbnail{ border-radius: 10rem;
background-color: unset; background-color: unset;
} }
}
</style> </style>

@ -12,9 +12,9 @@
<div :class="isGroup()?'groupEvent':'eventContainer'"> <div :class="isGroup()?'groupEvent':'eventContainer'">
<div class="thumbnailContainer"> <div class="thumbnailContainer">
<div class="filler"></div> <div class="filler"></div>
<userThumbnail v-if="group[0].sender !== user && isGroup()" :userId="group[0].sender" <userThumbnail v-if="group[0].sender !== user && isGroup()" :fallback="group[0].sender"
width="64" height="64" resizeMethod="scale" class="userThumbnail" class="userThumbnail"
:mxcURL="getUser(group[0].sender).avatarUrl" /> :mxcURL="getUser(group[0].sender).avatarUrl" :size="2"/>
</div> </div>
<div class="username" v-if="group[0].sender !== user && isGroup()">{{getUser(group[0].sender).displayName || group[0].sender}}</div> <div class="username" v-if="group[0].sender !== user && isGroup()">{{getUser(group[0].sender).displayName || group[0].sender}}</div>
<div class="event" v-for="event in group" :key="event.origin_server_ts" :title="`${group[0].sender} at ${getTime(event.origin_server_ts)}`"> <div class="event" v-for="event in group" :key="event.origin_server_ts" :title="`${group[0].sender} at ${getTime(event.origin_server_ts)}`">
@ -88,7 +88,7 @@ export default {
return payload; return payload;
}, },
resize(height){ resize(height){
this.$refs.chatContainer.style.height = `calc(100% - ${height}px - 3rem)`; this.$refs.chatContainer.style.height = `calc(100% - ${height}px - 3.5rem)`;
}, },
isGroup(){ isGroup(){
return Object.keys(this.room.currentState.members).length > 2; return Object.keys(this.room.currentState.members).length > 2;
@ -129,7 +129,7 @@ export default {
position: absolute; position: absolute;
margin: 0; margin: 0;
left: 0; left: 0;
top: 3rem; top: 3.5rem;
width: 100%; width: 100%;
height: calc(100% - 7rem); height: calc(100% - 7rem);
.messagesContainer{ .messagesContainer{

Loading…
Cancel
Save