0👍
✅
To do this you have to create an Event in your Laravel application that you will broadcast on a precise channel (you can for example give the name ‘chat. {Conversation}. {User_id}’) and with Laravel Echo you will listen this event!
I allowed myself to make some changes in your code -:)
I presume you have this class HasSeenEvent
<?php
namespace App\Events;
use App\Order;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class HasSeenEvent implements ShouldBroadcast
{
use SerializesModels;
public $message;
/**
* Create a new event instance.
*
* @param Message $message
* @return void
*/
public function __construct(Message $message)
{
$this->message = $message;
}
public function broadcastOn()
{
// I presume we can get conversation id like this : $this->message->conversation->id
return new PrivateChannel('chat.'.$this->message->conversation->id.'.'.$this->message->sender->id);
}
}
Then, in your routes/broadcast.php declare this route chat.{conversation}.{user_id}
In the function where you put the ‘seen’ to 1 you broadcast the event at the same time
broadcast(new HasSeenMessage($message))
Then you listen to this event in your vuejs code
components/Message.js
<template>
<li :class="className">
{{ message }}
</li>
</template>
<script>
export default {
props: [
'message',
'user',
'time',
'readed',
],
computed: {
className() {
return this.readed == 1 ? 'seen' : 'unread';
}
},
mounted() {
console.log('Component mounted.')
}
}
</script>
chat.blade.php
<message v-for="message,index in chat.messages"
:key="index"
:user="message.user"
:message="message.content"
:time="message.time"
:readed="message.readed"
>
</message>
<div class="form-group">
<button type="button" class="btn btn-lg btn-primary" v-on:click="send">Send message</button>
</div>
App.js
data: {
message: '',
convId: 1,
chat: {
messages: [],
/* message: [],
user: [],
time: [],
seen: [], */
},
typing: '',
},
....
watch: {
message() {
Echo.private('chat')
.whisper('typing', {
name: this.message
});
}
},
methods: {
send() {
if (this.message.length != 0 && this.message.length <= 4000) {
let data = {
content: this.message,
user: 'you',
time:this.getTime(),
readed: 0
}
this.chat.messages.push(data)
data = {}
axios.post('/sendMessage', {
message: this.message,
//lastName: 'Flintstone'
})
.then(response => {
console.log(response);
this.message = '';
})
.catch(error => {
console.log(error);
});
}
},
seenMessage() {
axios.post('/setMessagesSeen/' + this.convId) //this request mark messages in chat all readed for auhenticated user
.then(response => {
//This is not the best way to do that
this.chat.messages[this.messages.length -1 ].readed = 0
}).catch(response => {
console.log(response)
})
},
getTime() {
let time = new Date();
return time.getHours() + ':' + time.getMinutes();
}
},
mounted() {
Echo.private('chat')
.listen('ChatEvent', (e) => {
this.chat.messages.push({
content: e.message,
user: e.user,
time: this.getTime(),
readed: 0
})
console.log(e);
})
.listenForWhisper('typing', (e) => {
if (e.name != '')
this.typing = 'typing..';
else
this.typing = null;
});
// I presume to can access to user info
let that = this
Echo.private('chat.'+convId+'.'+user.id)
.listen('HasSeenMessage', (e) => {
let message = e.message
let lookingForMessage = that.chat.messages.find((m) => {
// I presume in your db messages table has field content and time
return m.content == message.content && m.time => message.time
})
try {
lookingForMessage.readed = 1
}catch (err){
// message not found
console.log(err)
}
})
}
Hope it helped you!
Source:stackexchange.com