Hi,
I’m writing a small chat app in Ionic Vue, which is also my first Ionic Project. I have a big problem regarding the content area:
When the messages are loaded from the rest api, scrollToBottom
does not work, when I add the messages hardcodes as an object, it works perfectly - what am I doing wrong here?
That’s my code:
<template>
<ion-page>
<ion-header color="primary">
<ion-toolbar>
<ion-buttons slot="start">
<ion-back-button text="" color="light" :icon="chevronBackOutline"></ion-back-button>
</ion-buttons>
<div>
<h1 class="text-xl text-white font-bold ml-4 pt-2" style="line-height: 45px;">{{ channel.title }}</h1>
</div>
</ion-toolbar>
</ion-header>
<ion-content fullscreen>
<ion-list>
<ion-item
v-for="(message,index) in messageList"
v-bind:key="index"
lines="none"
>
<div
class="flex w-full mb-2"
>
<div
:class="{ 'w-full inline-flex pr-12': !message.me, 'w-full inline-flex justify-end pl-12': message.me }"
>
<div>
<ion-avatar>
<img :src="message.icon"/>
</ion-avatar>
</div>
<div>
<div class="border rounded-lg bg-white px-3 py-2 text-gray-700 bg-gray-200">
<p class="text-xs username">{{ message.user }}</p>
<p class="text-xs font-semibold">{{ message.message }}</p>
</div>
<p class="timestamp ml-3 text-xs">{{ message.created }}</p>
</div>
</div>
</div>
</ion-item>
</ion-list>
</ion-content>
<ion-footer class="border-t bg-white">
<div class="flex">
<div class="w-full py-2 px-2">
<ion-textarea class="text-sm font-semibold border rounded px-2 text-gray-700"
placeholder="Deine Nachricht" auto-grow rows="1"
v-model="mymessage"
required
></ion-textarea>
</div>
<div class="py-1">
<ion-button
class="bg-ci-color px-2 py-1 rounded-full pt-1 outline-none"
size="small"
@click="sendMessage();"
>
<ion-icon :icon="rocketOutline" size="small"></ion-icon>
</ion-button>
</div>
</div>
</ion-footer>
</ion-page>
</template>
<script>
import {
IonPage,
IonContent,
IonHeader,
IonIcon,
IonFooter,
IonTextarea,
IonButton,
IonAvatar,
IonToolbar,
IonButtons,
IonBackButton,
IonList,
IonItem,
} from '@ionic/vue'
import {chevronBackOutline, rocketOutline} from 'ionicons/icons'
import appDefaults from "../../config"
import Echo from 'laravel-echo'
import axios from 'axios'
window.Pusher = require('pusher-js')
export default {
name: "Chat",
components: {
IonPage,
IonContent,
IonHeader,
IonIcon,
IonFooter,
IonTextarea,
IonButton,
IonAvatar,
IonToolbar,
IonButtons,
IonBackButton,
IonList,
IonItem,
},
data() {
return {
chatId: '',
messageList: {},
channel: [],
mymessage: '',
echo: null,
}
},
setup() {
return {
chevronBackOutline,
rocketOutline,
}
},
created() {
this.chatId = this.$route.params.channel
},
mounted() {
this.loadMessages()
this.connect()
this.joinChannel()
this.listenToVisibility()
},
methods: {
connect: function () {
window.Echo = new Echo({
broadcaster: 'pusher',
key: appDefaults.pusherKey,
....
....
....
....
});
},
joinChannel: function () {
window.Echo
.join('XYZchannel.' + this.chatId)
.listen('MessageSentEvent', (event) => {
if (event.message.user_uuid == undefined) {
this.messageList.push({
user: event.message.user,
message: event.message.message,
created: event.message.created,
icon: event.message.icon,
me: event.message.me,
});
}
})
.listenForWhisper('typing', user => {
this.userActive = user;
if (this.activeTimer) {
clearTimeout(this.activeTimer);
}
this.activeTimer = setTimeout(() => {
this.userActive = false;
}, 3000);
});
},
listenToVisibility: function () {
window.Echo
.join('XYZvisibility.' + this.chatId)
.listen('ChannelVisibilityEvent', (event) => {
....
....
....
});
},
loadMessages: function () {
axios.defaults.headers.common['Authorization'] = 'Bearer ' + this.$store.getters.getToken
axios.get('getMessages?channel=' + this.chatId)
.then(response => {
this.messageList = response.data.data
this.channel = response.data.channel
this.scrollToBottom()
})
.catch(error => {
console.log(error)
})
},
sendMessage: function () {
...
...
...
...
...
},
getContent() {
console.log('get content')
return document.querySelector('ion-content')
},
scrollToBottom() {
console.log('scroll to bottom')
this.getContent().scrollToBottom(500)
},
},
}
</script>
<style scoped>
ion-toolbar {
--ion-toolbar-background: var(--ion-color-primary);
}
ion-icon {
font-size: 25px;
color: white;
}
p.timestamp {
font-size: 10px;
}
p.username {
font-size: 10px;
}
ion-footer {
--ion-background-color: #fff;
}
</style>
It’s about the loadMessages
and the scrollToBottom
methods.
Thank you so much for your help.
Sascha
1 post - 1 participant