Step 2: Creating page Messages: userlist last messages + a page for all the messages received and sent.

This commit is contained in:
Paolo Arena
2019-10-27 00:37:00 +02:00
parent 878ae96813
commit 4f895bdbe2
19 changed files with 407 additions and 159 deletions

View File

@@ -25,9 +25,23 @@
}
.chat_dest{
display: flex;
flex: 1;
justify-content: flex-start;
}
.chat_my{
display: flex;
flex: 1;
justify-content: flex-end;
}
.bottomfixed {
// right: 0;
// position: fixed;
z-index: 9999;
// box-sizing: border-box;
margin-right: 0;
margin-left: auto;
// bottom: 0;
}

View File

@@ -4,10 +4,15 @@ import { toolsext } from '../../store/Modules/toolsext'
import { MessageStore, UserStore } from '../../store/Modules'
import globalroutines from '../../globalroutines/index'
import { tools } from '../../store/Modules/tools'
import MixinUsers from '../../mixins/mixin-users'
import { IChat, IMessage, IUserState } from '../../model'
import { IChat, IMessage, IUserState, MsgDefault, StatusMessage } from '../../model'
import { Getter } from 'vuex-class'
import { IMsgUsers } from '../../model/MessageStore'
import MixinUsers from '../../mixins/mixin-users'
import { scroll } from 'quasar'
const { getScrollTarget, setScrollPosition } = scroll
// import {Loading, QSpinnerFacebook, QSpinnerGears} from 'quasar'
@@ -16,7 +21,7 @@ const namespace = 'MessageModule'
@Component({
name: 'Messages',
mixins: [MixinUsers],
components: { }
components: {}
})
export default class Messages extends Vue {
@@ -24,18 +29,97 @@ export default class Messages extends Vue {
public $q
public mydrawer = true
public miniState = false
public usernameloading: string = ''
public widthdrawer = 300
public chatsel: IChat = {
username: '',
lasttimeActive: new Date()
}
public mytexttosend: string = ''
public loading: boolean = false
// public users_msg_saved: IMsgUsers[] = []
@Getter('getlasts_messages', { namespace })
public lasts_messages: (state: IUserState) => IMessage[]
@Watch('$route.params.un')
public changeusername() {
if (this.$route.params.un === undefined || this.$route.params.un === ':un') {
this.usernameloading = this.getLastUserChatted()
} else {
this.usernameloading = this.$route.params.un
}
if (!this.miniState && tools.isMobile()) {
this.miniState = true
}
if (this.usernameloading) {
// Retrieve last msgs data from the server
this.refreshdata(this.usernameloading)
}
}
get styletextbar() {
let mystr = ''
if (this.mydrawer) {
if (!this.miniState)
mystr = `left: ${this.widthdrawer}px;`
else
mystr = `left: 57px;`
} else {
mystr = 'left: 0;'
}
// console.log('tools.getwidth', tools.getwidth)
mystr += ` width: ${tools.getwidth(this) - this.widthdrawer - 40 - 300}px; `
return mystr
}
public scrollToElement(el) {
const target = getScrollTarget(el)
const offset = el.offsetTop
const duration = 1000
// console.log('target', target, 'offset', offset, 'duration', duration)
setScrollPosition(target, offset, duration)
}
public refreshdata(username: string) {
this.loading = true
this.chatsel.username = ''
return MessageStore.actions.updateMsgDataFromServer({
username,
lastdataread: this.getlastdataread(username)
}).then((ris) => {
this.usernameloading = username
this.chatsel.username = username
this.loading = false
const element = document.getElementById('last')
this.scrollToElement(element)
// this.changemsgs('', '')
}).catch((err) => {
this.loading = false
})
}
public showNotif(msgcode) {
tools.showNotif(this.$q, this.$t(msgcode))
}
public getMyUsername() {
return UserStore.state.my.username
}
public drawerClick(e) {
// if in "mini" state and user
// click on drawer, we switch it to "normal" mode
@@ -58,41 +142,106 @@ export default class Messages extends Vue {
return this.chatsel.username === username
}
@Watch('$route.params.un')
public changeusername() {
this.chatsel.username = this.$route.params.un
if (!this.miniState && tools.isMobile()) {
this.miniState = true
public getLastUserChatted() {
const lastmsg: IMessage = MessageStore.getters.getlasts_messages().slice(-1)[0]
console.log('lastmsg', lastmsg)
if (lastmsg) {
return (lastmsg.origin.username !== this.getMyUsername()) ? lastmsg.origin.username : lastmsg.origin.username
} else {
return ''
}
// Retrieve last msgs data from the server
MessageStore.actions.updateMsgDataFromServer({username: this.chatsel.username, lastdataread: this.getlastdataread() } )
}
public selChat(mymsg: IMessage) {
this.$router.replace('/messages/' + mymsg.dest.username)
if (this.chatsel.username !== mymsg.dest.username)
this.$router.replace('/messages/' + mymsg.dest.username)
else {
// refresh
this.refreshdata(this.chatsel.username)
}
}
public msgchat(): IMsgUsers {
// @Watch('MessageStore.state.users_msg', { immediate: false, deep: true })
// public changemsgs(value: string, oldValue: string) {
// console.log('changemsgs')
//
// const myrec = MessageStore.state.users_msg.find((rec) => rec.username === this.usernameloading)
//
// console.log('myrec', myrec)
//
// if (this.users_msg_saved.length < 0)
// this.users_msg_saved = []
//
// this.users_msg_saved[this.usernameloading] = {...myrec}
// console.log('this.users_msg_saved', this.users_msg_saved[this.usernameloading])
// }
public msgchat(username): IMsgUsers {
// Get msg for this chat
return MessageStore.state.users_msg.find((rec) => rec.username === this.chatsel.username)
return MessageStore.state.users_msg.find((rec) => rec.username === username)
// return this.users_msg_saved[username]
}
public msgchat_records(): IMessage[] {
const myrec = this.msgchat()
console.log('myrec', myrec)
const myrec = this.msgchat(this.chatsel.username)
// console.log('msgchat_records', myrec)
// Get msg for this chat
return (myrec) ? myrec.msgs : []
}
public getlastdataread(): Date {
const myrec = this.msgchat()
public getlastdataread(username): any {
const myrec = this.msgchat(username)
// Get msg for this chat
return (myrec) ? tools.gettimestampByDate(myrec.lastdataread) : tools.getLastDateReadReset()
const lastdata = (myrec) ? myrec.lastdataread : tools.getLastDateReadReset()
console.table(myrec)
let mydate = ''
if (!tools.isIsoDate(lastdata))
mydate = lastdata.toISOString()
else
return lastdata
// console.log('getlastdataread', mydate)
return mydate
}
public getMsgText(msg: IMessage) {
return [msg.message]
public sendMsg() {
const self = this
const data: IMessage = {
dest: {
idapp: process.env.APP_ID,
username: this.chatsel.username
},
message: this.mytexttosend
}
data.dest.username = this.chatsel.username
data.message = this.mytexttosend
this.mytexttosend = ''
MessageStore.actions.SendMsgEvent(data).then((ris) => {
data.status = StatusMessage.Sending
const element = document.getElementById('last')
this.scrollToElement(element)
if (!ris)
tools.showNegativeNotif(self.$q, self.$t('cal.sendmsg_error'))
// tools.showPositiveNotif(self.$q, self.$t('cal.sendmsg_sent'))
// else
})
}
public loadMorePosts() {
console.log('loadMorePosts')
}
public myonScroll({ target: { scrollTop, clientHeight, scrollHeight }}) {
if (scrollTop + clientHeight >= scrollHeight) {
this.loadMorePosts()
}
}
public created() {

View File

@@ -1,5 +1,5 @@
<template>
<div>
<div class="q-pr-md">
<q-layout view="hHh Lpr lff" container :style="`height: ` + getheight + `px`"
class="shadow-2 rounded-borders messages_page">
<q-drawer
@@ -8,7 +8,7 @@
:mini="!mydrawer || miniState"
@click.capture="drawerClick"
:width="300"
:width="widthdrawer"
:breakpoint="300"
bordered
content-class="bg-grey-3">
@@ -36,14 +36,14 @@
<q-item-section avatar>
<q-avatar>
<img :src="getImgByUsername(msg.dest.username)">
<img :src="getImgByMsg(msg)">
</q-avatar>
</q-item-section>
<q-item-section>
<q-item-label lines="1">{{getUserByUsername(msg.dest.username)}}</q-item-label>
<q-item-label lines="1">{{getUsernameChatByMsg(msg)}}</q-item-label>
<q-item-label caption lines="2">
{{msg.message}}
{{getMsgText(msg, false)}}
</q-item-label>
</q-item-section>
@@ -68,62 +68,102 @@
</div>
</q-drawer>
<q-page-container>
<q-page class="q-px-lg q-py-md">
<div>
<q-item clickable v-if="!!chatsel.username">
<div class="row column">
<div>
<q-page-container style="">
<q-page class="q-px-lg q-py-md">
<div>
<q-item clickable v-if="!!chatsel.username" @scroll="myonScroll">
<q-item-section avatar>
<q-avatar>
<img :src="getImgByUsername(chatsel.username)">
</q-avatar>
</q-item-section>
<q-item-section>
<q-item-label lines="1">{{getUserByUsername(chatsel.username)}}</q-item-label>
<q-item-label caption lines="2">
{{func_tools.getDateTimeShortStr(chatsel.lasttimeActive)}}
</q-item-label>
</q-item-section>
</q-item>
</div>
<q-separator/>
<div class="q-pa-md row" style="flex-direction: column;">
<q-item clickable v-for="(msg, index) in msgchat_records()" :key="index" v-if="msg.dest">
<div class="chat_dest" v-if="msg.dest.username === getMyUsername()">
<q-chat-message
:name="getUserByUsername(msg.origin.username)"
:text="getMsgText(msg)"
:stamp="tools.getstrDateTimeShort(msg.datemsg)"
text-color="black"
bg-color="grey-2">
<template v-slot:avatar>
<q-avatar size="sm">
<img :src="getImgByUsername(msg.origin.username)">
<q-item-section avatar>
<q-avatar>
<img :src="getImgByUsername(chatsel.username)">
</q-avatar>
</template>
</q-chat-message>
</div>
<div class="chat_my" v-else>
<q-chat-message
name="me"
:text="getMsgText(msg)"
:stamp="tools.getstrDateTimeShort(msg.datemsg)"
sent
bg-color="blue-2">
<template v-slot:avatar>
<q-avatar size="sm">
<img :src="getMyImg">
</q-avatar>
</template>
</q-item-section>
</q-chat-message>
<q-item-section>
<q-item-label lines="1">{{getUserByUsername(chatsel.username)}}</q-item-label>
<q-item-label caption lines="2">
{{func_tools.getDateTimeShortStr(chatsel.lasttimeActive)}}
</q-item-label>
</q-item-section>
</q-item>
</div>
<q-separator/>
<div class="q-pa-md">
<q-item clickable v-for="(msg, index) in msgchat_records()" :key="index"
v-if="msg.dest">
</q-item>
<div class="chat_dest" v-if="msg.dest.username === getMyUsername()">
<q-chat-message
:name="getUsernameChatByMsg(msg)"
:text="getMsgText(msg, true)"
:stamp="tools.getstrDateTimeShort(msg.datemsg)"
text-color="black"
bg-color="grey-2">
<template v-slot:avatar>
<q-avatar size="sm">
<img :src="getImgByMsg(msg)">
</q-avatar>
</template>
</q-chat-message>
</div>
<div class="chat_my" v-else>
<q-chat-message
name="me"
:text="getMsgText(msg, true)"
:stamp="tools.getstrDateTimeShort(msg.datemsg)"
sent
bg-color="blue-2">
<template v-slot:avatar>
<q-avatar size="sm">
<img :src="getMyImg">
</q-avatar>
</template>
</q-chat-message>
</div>
</q-item>
<div id="last"></div>
<q-inner-loading id="spinner" :showing="loading">
<q-spinner-tail
color="primary"
size="4em">
</q-spinner-tail>
</q-inner-loading>
</div>
</q-page>
</q-page-container>
</div>
<div class="bottomfixed row" :style="styletextbar">
<div class="" style="max-width: 50px; align-self: center; order: 1;">
<q-btn rounded
size="sm"
icon="fas fa-smile">
</q-btn>
</div>
</q-page>
</q-page-container>
<div class="" style="max-height: 100px; flex-grow:1; order: 2;">
<q-input
bordered
rounded
v-model="mytexttosend"
debounce="1000"
filled
autogrow
input-style="max-height: 95px;">
</q-input>
</div>
<div class="" style="max-width: 50px; align-self: center; order: 3;">
<q-btn push
rounded
size="sm"
icon="send"
@click="sendMsg">
</q-btn>
</div>
</div>
</div>
</q-layout>
</div>
</template>