parent
2b3f99c421
commit
6d97fd030d
9 changed files with 240 additions and 42 deletions
70
package-lock.json
generated
70
package-lock.json
generated
|
|
@ -1,11 +1,11 @@
|
||||||
{
|
{
|
||||||
"name": "keanuapp-weblite",
|
"name": "keanuapp-weblite",
|
||||||
"version": "0.1.2",
|
"version": "0.1.3",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"version": "0.1.2",
|
"version": "0.1.3",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"aes-js": "^3.1.2",
|
"aes-js": "^3.1.2",
|
||||||
"axios": "^0.21.0",
|
"axios": "^0.21.0",
|
||||||
|
|
@ -28,6 +28,7 @@
|
||||||
"vue-resize": "^0.5.0",
|
"vue-resize": "^0.5.0",
|
||||||
"vue-router": "^3.2.0",
|
"vue-router": "^3.2.0",
|
||||||
"vue-sanitize": "^0.2.1",
|
"vue-sanitize": "^0.2.1",
|
||||||
|
"vue-swipeable-bottom-sheet": "^0.0.5",
|
||||||
"vuetify": "^2.2.11",
|
"vuetify": "^2.2.11",
|
||||||
"vuex": "^3.5.1",
|
"vuex": "^3.5.1",
|
||||||
"vuex-persist": "^3.1.3"
|
"vuex-persist": "^3.1.3"
|
||||||
|
|
@ -5286,17 +5287,17 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/elliptic": {
|
"node_modules/elliptic": {
|
||||||
"version": "6.5.3",
|
"version": "6.5.4",
|
||||||
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz",
|
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz",
|
||||||
"integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==",
|
"integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bn.js": "^4.4.0",
|
"bn.js": "^4.11.9",
|
||||||
"brorand": "^1.0.1",
|
"brorand": "^1.1.0",
|
||||||
"hash.js": "^1.0.0",
|
"hash.js": "^1.0.0",
|
||||||
"hmac-drbg": "^1.0.0",
|
"hmac-drbg": "^1.0.1",
|
||||||
"inherits": "^2.0.1",
|
"inherits": "^2.0.4",
|
||||||
"minimalistic-assert": "^1.0.0",
|
"minimalistic-assert": "^1.0.1",
|
||||||
"minimalistic-crypto-utils": "^1.0.0"
|
"minimalistic-crypto-utils": "^1.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/emoji-regex": {
|
"node_modules/emoji-regex": {
|
||||||
|
|
@ -6642,6 +6643,14 @@
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/hammerjs": {
|
||||||
|
"version": "2.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/hammerjs/-/hammerjs-2.0.8.tgz",
|
||||||
|
"integrity": "sha1-BO93hiz/K7edMPdpIJWTAiK/YPE=",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/handle-thing": {
|
"node_modules/handle-thing": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz",
|
||||||
|
|
@ -13938,6 +13947,14 @@
|
||||||
"integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=",
|
"integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/vue-swipeable-bottom-sheet": {
|
||||||
|
"version": "0.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/vue-swipeable-bottom-sheet/-/vue-swipeable-bottom-sheet-0.0.5.tgz",
|
||||||
|
"integrity": "sha512-PcARUGu6tZ22WRwNum6mTlnMQk/DwqdcD3cQavshIICntD9OzPelkY4mlfJezx3BspfiTO0UI33pQ3x9tmzfcg==",
|
||||||
|
"dependencies": {
|
||||||
|
"hammerjs": "^2.0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/vue-template-compiler": {
|
"node_modules/vue-template-compiler": {
|
||||||
"version": "2.6.12",
|
"version": "2.6.12",
|
||||||
"resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.12.tgz",
|
"resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.12.tgz",
|
||||||
|
|
@ -19613,17 +19630,17 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"elliptic": {
|
"elliptic": {
|
||||||
"version": "6.5.3",
|
"version": "6.5.4",
|
||||||
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz",
|
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz",
|
||||||
"integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==",
|
"integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"bn.js": "^4.4.0",
|
"bn.js": "^4.11.9",
|
||||||
"brorand": "^1.0.1",
|
"brorand": "^1.1.0",
|
||||||
"hash.js": "^1.0.0",
|
"hash.js": "^1.0.0",
|
||||||
"hmac-drbg": "^1.0.0",
|
"hmac-drbg": "^1.0.1",
|
||||||
"inherits": "^2.0.1",
|
"inherits": "^2.0.4",
|
||||||
"minimalistic-assert": "^1.0.0",
|
"minimalistic-assert": "^1.0.1",
|
||||||
"minimalistic-crypto-utils": "^1.0.0"
|
"minimalistic-crypto-utils": "^1.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"emoji-regex": {
|
"emoji-regex": {
|
||||||
|
|
@ -20677,6 +20694,11 @@
|
||||||
"pify": "^4.0.1"
|
"pify": "^4.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"hammerjs": {
|
||||||
|
"version": "2.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/hammerjs/-/hammerjs-2.0.8.tgz",
|
||||||
|
"integrity": "sha1-BO93hiz/K7edMPdpIJWTAiK/YPE="
|
||||||
|
},
|
||||||
"handle-thing": {
|
"handle-thing": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz",
|
||||||
|
|
@ -26528,6 +26550,14 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"vue-swipeable-bottom-sheet": {
|
||||||
|
"version": "0.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/vue-swipeable-bottom-sheet/-/vue-swipeable-bottom-sheet-0.0.5.tgz",
|
||||||
|
"integrity": "sha512-PcARUGu6tZ22WRwNum6mTlnMQk/DwqdcD3cQavshIICntD9OzPelkY4mlfJezx3BspfiTO0UI33pQ3x9tmzfcg==",
|
||||||
|
"requires": {
|
||||||
|
"hammerjs": "^2.0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"vue-template-compiler": {
|
"vue-template-compiler": {
|
||||||
"version": "2.6.12",
|
"version": "2.6.12",
|
||||||
"resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.12.tgz",
|
"resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.12.tgz",
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
"vue-resize": "^0.5.0",
|
"vue-resize": "^0.5.0",
|
||||||
"vue-router": "^3.2.0",
|
"vue-router": "^3.2.0",
|
||||||
"vue-sanitize": "^0.2.1",
|
"vue-sanitize": "^0.2.1",
|
||||||
|
"vue-swipeable-bottom-sheet": "^0.0.5",
|
||||||
"vuetify": "^2.2.11",
|
"vuetify": "^2.2.11",
|
||||||
"vuex": "^3.5.1",
|
"vuex": "^3.5.1",
|
||||||
"vuex-persist": "^3.1.3"
|
"vuex-persist": "^3.1.3"
|
||||||
|
|
|
||||||
|
|
@ -678,3 +678,30 @@ $admin-fg: white;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bottom-sheet .card {
|
||||||
|
z-index: 10; /* Above mic button etc. */
|
||||||
|
background-color: white;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.room-info-sheet {
|
||||||
|
background-color: white;
|
||||||
|
|
||||||
|
.current-room {
|
||||||
|
padding: 25px;
|
||||||
|
background: linear-gradient(180deg, #FFFFFF 0%, rgba(255, 255, 255, 0) 100%), #F5F5F7;
|
||||||
|
box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.15);
|
||||||
|
border-radius: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.room-avatar {
|
||||||
|
background-color: #ededed;
|
||||||
|
width: 44px !important;
|
||||||
|
height: 44px !important;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
.headline {
|
||||||
|
font-size: 70 * $chat-text-size !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -37,6 +37,14 @@ $chat-button-height: 50px;
|
||||||
color: #505050;
|
color: #505050;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.h4 {
|
||||||
|
font-family: 'Poppins', sans-serif;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 11 * $chat-text-size;
|
||||||
|
color: black;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
.v-btn.outlined-button {
|
.v-btn.outlined-button {
|
||||||
font-family: 'Inter', sans-serif;
|
font-family: 'Inter', sans-serif;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="chat-root fill-height d-flex flex-column" ma-0 pa-0>
|
<div class="chat-root fill-height d-flex flex-column" ma-0 pa-0>
|
||||||
<ChatHeader class="chat-header flex-grow-1 flex-shrink-1" />
|
<ChatHeader
|
||||||
|
class="chat-header flex-grow-1 flex-shrink-1"
|
||||||
|
v-on:header-click="$refs.roomInfoSheet.open()"
|
||||||
|
/>
|
||||||
<div
|
<div
|
||||||
class="chat-content flex-grow-1 flex-shrink-1"
|
class="chat-content flex-grow-1 flex-shrink-1"
|
||||||
ref="chatContainer"
|
ref="chatContainer"
|
||||||
|
|
@ -160,7 +163,7 @@
|
||||||
elevation="0"
|
elevation="0"
|
||||||
v-blur
|
v-blur
|
||||||
style="z-index: 10"
|
style="z-index: 10"
|
||||||
v-longTap:250="[showRecordingUI,startRecording]"
|
v-longTap:250="[showRecordingUI, startRecording]"
|
||||||
>
|
>
|
||||||
<v-icon :color="showRecorder ? 'white' : 'black'">mic</v-icon>
|
<v-icon :color="showRecorder ? 'white' : 'black'">mic</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
|
|
@ -288,6 +291,9 @@
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
</v-container>
|
</v-container>
|
||||||
|
|
||||||
|
<RoomInfoBottomSheet ref="roomInfoSheet" />
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -312,6 +318,7 @@ import util from "../plugins/utils";
|
||||||
import MessageOperations from "./messages/MessageOperations.vue";
|
import MessageOperations from "./messages/MessageOperations.vue";
|
||||||
import ChatHeader from "./ChatHeader";
|
import ChatHeader from "./ChatHeader";
|
||||||
import VoiceRecorder from "./VoiceRecorder";
|
import VoiceRecorder from "./VoiceRecorder";
|
||||||
|
import RoomInfoBottomSheet from "./RoomInfoBottomSheet";
|
||||||
|
|
||||||
const READ_RECEIPT_TIMEOUT = 5000; /* How long a message must have been visible before the read marker is updated */
|
const READ_RECEIPT_TIMEOUT = 5000; /* How long a message must have been visible before the read marker is updated */
|
||||||
|
|
||||||
|
|
@ -364,6 +371,7 @@ export default {
|
||||||
DebugEvent,
|
DebugEvent,
|
||||||
MessageOperations,
|
MessageOperations,
|
||||||
VoiceRecorder,
|
VoiceRecorder,
|
||||||
|
RoomInfoBottomSheet
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
|
|
@ -698,7 +706,10 @@ export default {
|
||||||
switch (event.getType()) {
|
switch (event.getType()) {
|
||||||
case "m.room.member":
|
case "m.room.member":
|
||||||
if (event.getContent().membership == "join") {
|
if (event.getContent().membership == "join") {
|
||||||
if (event.getPrevContent() && event.getPrevContent().membership == "join") {
|
if (
|
||||||
|
event.getPrevContent() &&
|
||||||
|
event.getPrevContent().membership == "join"
|
||||||
|
) {
|
||||||
// We we already joined, so this must be a display name and/or avatar update!
|
// We we already joined, so this must be a display name and/or avatar update!
|
||||||
return ContactChanged;
|
return ContactChanged;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -4,20 +4,17 @@
|
||||||
<v-col
|
<v-col
|
||||||
cols="auto"
|
cols="auto"
|
||||||
class="chat-header-members text-start ma-0 pa-0"
|
class="chat-header-members text-start ma-0 pa-0"
|
||||||
|
style="overflow:hidden;cursor:pointer" @click.stop="onHeaderClicked"
|
||||||
>
|
>
|
||||||
<v-avatar size="40" class="mr-2">
|
<v-avatar size="40" class="mr-2">
|
||||||
<v-img :src="room.avatar" />
|
<v-img :src="room.avatar" />
|
||||||
</v-avatar>
|
</v-avatar>
|
||||||
</v-col>
|
</v-col>
|
||||||
|
|
||||||
<v-col class="ma-0 pa-0 flex-shrink-1 flex-nowrap" style="overflow:hidden">
|
<v-col class="ma-0 pa-0 flex-shrink-1 flex-nowrap" style="overflow:hidden;cursor:pointer" @click.stop="onHeaderClicked">
|
||||||
<div class="d-flex flex-nowrap room-name" @click.stop="showRoomList = true">{{ room.summary.info.title }} <v-icon>expand_more</v-icon></div>
|
<div class="d-flex flex-nowrap room-name">{{ room.summary.info.title }} <!--<v-icon>expand_more</v-icon>--></div>
|
||||||
<RoomList v-if="showRoomList" v-click-outside="hideRoomList" @close="hideRoomList" />
|
|
||||||
<div class="num-members">{{ memberCount }}{{ memberCount > 1 ? " members" : " member" }}</div>
|
<div class="num-members">{{ memberCount }}{{ memberCount > 1 ? " members" : " member" }}</div>
|
||||||
</v-col>
|
</v-col>
|
||||||
<v-col cols="auto" class="text-end ma-0 pa-0">
|
|
||||||
<v-btn text class="info-button" @click.stop="showRoomInfo"><v-icon color="black">info</v-icon></v-btn>
|
|
||||||
</v-col>
|
|
||||||
<v-col cols="auto" class="text-end ma-0 pa-0">
|
<v-col cols="auto" class="text-end ma-0 pa-0">
|
||||||
<v-btn text class="leave-button" @click.stop="leaveRoom">Leave</v-btn>
|
<v-btn text class="leave-button" @click.stop="leaveRoom">Leave</v-btn>
|
||||||
</v-col>
|
</v-col>
|
||||||
|
|
@ -31,18 +28,15 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import LeaveRoomDialog from '../components/LeaveRoomDialog';
|
import LeaveRoomDialog from '../components/LeaveRoomDialog';
|
||||||
import RoomList from "../components/RoomList";
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "ChatHeader",
|
name: "ChatHeader",
|
||||||
components: {
|
components: {
|
||||||
LeaveRoomDialog,
|
LeaveRoomDialog
|
||||||
RoomList
|
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
memberCount: null,
|
memberCount: null,
|
||||||
showRoomList: false,
|
|
||||||
showLeaveConfirmation: false
|
showLeaveConfirmation: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
@ -83,6 +77,10 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onHeaderClicked() {
|
||||||
|
this.$emit("header-click", {event: this.event});
|
||||||
|
},
|
||||||
|
|
||||||
updateMemberCount() {
|
updateMemberCount() {
|
||||||
if (!this.room) {
|
if (!this.room) {
|
||||||
this.memberCount = 0;
|
this.memberCount = 0;
|
||||||
|
|
@ -91,17 +89,9 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
showRoomInfo() {
|
|
||||||
this.$navigation.push({ name: "RoomInfo" });
|
|
||||||
},
|
|
||||||
|
|
||||||
leaveRoom() {
|
leaveRoom() {
|
||||||
this.showLeaveConfirmation = true;
|
this.showLeaveConfirmation = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
hideRoomList() {
|
|
||||||
this.showRoomList = false;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
96
src/components/RoomInfoBottomSheet.vue
Normal file
96
src/components/RoomInfoBottomSheet.vue
Normal file
|
|
@ -0,0 +1,96 @@
|
||||||
|
<template>
|
||||||
|
<SwipeableBottomSheet
|
||||||
|
class="bottom-sheet"
|
||||||
|
ref="roomInfoSheet"
|
||||||
|
:halfY="0.5"
|
||||||
|
:openY="0.1"
|
||||||
|
:data-closed="closed ? 1 : 0"
|
||||||
|
>
|
||||||
|
<div class="room-info-sheet" ref="roomInfoSheetContent">
|
||||||
|
<div class="text-center current-room">
|
||||||
|
<v-avatar class="room-avatar">
|
||||||
|
<v-img v-if="roomAvatar" :src="roomAvatar" />
|
||||||
|
<span v-else class="white--text headline">{{
|
||||||
|
roomName.substring(0, 1).toUpperCase()
|
||||||
|
}}</span>
|
||||||
|
</v-avatar>
|
||||||
|
<div class="h4">This group</div>
|
||||||
|
<div class="h2">{{ roomName }}</div>
|
||||||
|
<v-btn
|
||||||
|
height="20px"
|
||||||
|
color="black"
|
||||||
|
class="filled-button"
|
||||||
|
@click.stop="showDetails"
|
||||||
|
>View details</v-btn
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<room-list :title="'Other groups'" v-on:close="close" />
|
||||||
|
</div>
|
||||||
|
</SwipeableBottomSheet>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import SwipeableBottomSheet from "vue-swipeable-bottom-sheet/src/components/SwipeableBottomSheet";
|
||||||
|
import RoomList from "./RoomList.vue";
|
||||||
|
import roomInfoMixin from "./roomInfoMixin";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "RoomInfoBottomSheet",
|
||||||
|
mixins: [roomInfoMixin],
|
||||||
|
components: {
|
||||||
|
SwipeableBottomSheet,
|
||||||
|
RoomList,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
closed: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.$watch(
|
||||||
|
"$refs.roomInfoSheet.state",
|
||||||
|
(new_value, ignored_old_value) => {
|
||||||
|
this.closed = new_value == 'close';
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
open() {
|
||||||
|
if (this.$refs.roomInfoSheet.state == "half") {
|
||||||
|
this.$refs.roomInfoSheet.setState("close");
|
||||||
|
} else {
|
||||||
|
// Reset scroll before opening!
|
||||||
|
this.$refs.roomInfoSheetContent.parentElement.scrollTop = 0;
|
||||||
|
this.$refs.roomInfoSheet.setState("half");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
close() {
|
||||||
|
this.$refs.roomInfoSheet.setState("close");
|
||||||
|
},
|
||||||
|
|
||||||
|
showDetails() {
|
||||||
|
this.close();
|
||||||
|
this.$navigation.push({ name: "RoomInfo" });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@import "@/assets/css/chat.scss";
|
||||||
|
|
||||||
|
/* Default implementation only dims background when fully open,
|
||||||
|
so we use our own flag (data-closed) here to that we can
|
||||||
|
dim also when it is just half open */
|
||||||
|
.bottom-sheet[data-closed="0"] .bg {
|
||||||
|
display: block;
|
||||||
|
transition: all 0.3s;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: rgba(0, 0, 0, 0.3) !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<v-list dense class="room-list">
|
<v-list dense class="room-list">
|
||||||
<v-subheader>ROOMS</v-subheader>
|
<div class="h4">{{title}}</div>
|
||||||
<v-list-item-group v-model="currentRoomId" color="primary">
|
<v-list-item-group v-model="currentRoomId" color="primary">
|
||||||
<v-list-item v-for="room in $matrix.rooms" :key="room.roomId" :value="room.roomId">
|
<v-list-item v-for="room in $matrix.rooms" :key="room.roomId" :value="room.roomId">
|
||||||
<v-list-item-avatar size="40" color="#e0e0e0">
|
<v-list-item-avatar size="40" color="#e0e0e0">
|
||||||
|
|
@ -22,6 +22,13 @@ import util from "../plugins/utils";
|
||||||
export default {
|
export default {
|
||||||
name: "RoomList",
|
name: "RoomList",
|
||||||
|
|
||||||
|
props: {
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: "Rooms"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
currentRoomId: null,
|
currentRoomId: null,
|
||||||
}),
|
}),
|
||||||
|
|
|
||||||
28
src/components/roomInfoMixin.js
Normal file
28
src/components/roomInfoMixin.js
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
export default {
|
||||||
|
computed: {
|
||||||
|
room() {
|
||||||
|
return this.$matrix.currentRoom;
|
||||||
|
},
|
||||||
|
|
||||||
|
roomName() {
|
||||||
|
if (this.room) {
|
||||||
|
return this.room.name;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
},
|
||||||
|
|
||||||
|
roomTopic() {
|
||||||
|
if (this.room) {
|
||||||
|
return this.room.topic;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
},
|
||||||
|
|
||||||
|
roomAvatar() {
|
||||||
|
if (this.room) {
|
||||||
|
return this.room.avatar;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue