Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
<template>
<div>
<div class="card mb-3 col-xs-3 col-sm-3 col-md-12">
<div class="accordion" id="accordionExample">
<div class="">
<div class="d-flex flex-column chat-titles">
<a class="btn btn-link col-xs-9 col-sm-9"
data-toggle="collapse"
:href="`#collapse-` + group.id"
>
<strong>Subject:</strong> {{ group.subject }}&nbsp;&bull;
<span v-show="group.urgency">
<strong>Urgency</strong> <span class="badge badge-info">{{ group.urgency | capitalize }}</span>
&nbsp;&bull;&nbsp;
</span>
<strong>Message ID:</strong> {{ group.unique_id }}
<a data-toggle="collapse" :href="`#collapse-` + group.id">
<i class="fas fa-chevron-down"></i>
</a>
<br />
<span v-for="(user_group, index) in groups" :key="index">
<small>
<strong>Conversation party:</strong>
<span v-for="(ug, index) in user_group.users" :key="index">
{{ ug.name }} ({{ ug.account_type }}),
</span>
</small>
<br />
<small><strong>Property:</strong> {{ user_group.property.name_number }}, {{ user_group.property.town }}, {{ user_group.property.postcode }} </small>
</span>
</a>
</div>
<div :id="`collapse-${group.id}`" class="collapse" aria-labelledby="headingOne" data-parent="#accordionExample">
<div class="card-body">
<div class="panel-body chat-panel">
<ul class="list-unstyled">
<li class="media" v-for="(conversation, index) in conversations" :key="index">
<i class="far fa-user mr-3 img-thumbnail"></i>
<div class="media-body">
<h5 class="mt-0 mb-1">{{ conversation.user.name }} ({{ conversation.user.account_type | capitalize }})</h5>
<p>
{{ conversation.message }}<br />
<small class="text-muted pt-1">{{ conversation.created_at | formatDate }}</small>
</p>
</div>
</li>
</ul>
<span v-show="typing" class="help-block" style="font-style: italic;">
{{ user.name }} is typing...
</span>
</div>
<div class="panel-footer">
<div class="input-group">
<input
type="text"
class="form-control input-sm"
placeholder="Type your message here..."
v-model="message"
@keyup.enter="store(group_id)"
@keydown="isTyping"
>
<span class="input-group-btn">
<button class="btn btn-success" @click.prevent="store()">
Send
</button>
</span>
</div>
<br />
<small>If the conversation is finished, you can can archive by clicking <a href="#" @click.prevent="archive(group_id)">here</a></small>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: ['group'],
data() {
return {
conversations: [],
group_id: this.group.id,
typing: false,
user: '',
message: '',
groups: []
}
},
created() {
let _this = this;
Echo.private('groups.' + this.group.id)
.listenForWhisper('typing', (e) => {
this.user = e.user;
this.typing = e.typing;
// remove is typing indicator after 0.9s
setTimeout(function() {
_this.typing = false
}, 5000);
});
},
mounted() {
this.listenForNewMessage();
this.getMessages();
this.getUsersInChat();
},
methods: {
isTyping() {
let channel = Echo.private('groups.' + this.group.id);
setTimeout(function() {
channel.whisper('typing', {
user: Laravel.userName,
typing: true
});
}, 3500);
},
getMessages() {
axios.get('/conversations/all/' + this.group_id)
.then((response) => {
let conversations = response.data;
conversations.map((conversations) => {
this.conversations.push(conversations);
});
let message = '';
this.group.push({
message: message
});
});
},
store() {
axios.post('/conversations', {message: this.message, group_id: this.group.id})
.then((response) => {
this.conversations.push(response.data);
});
},
listenForNewMessage() {
Echo.private('groups.' + this.group.id)
.listen('NewMessage', (e) => {
this.conversations.push(e);
});
},
getUsersInChat() {
axios.get('/conversations/users/' + this.group_id)
.then((response) => {
let user_groups = response.data;
user_groups.map((user_groups) => {
this.groups.push(user_groups);
});
});
},
archive(group_id) {
axios.post('/conversations/archive/' + group_id)
.then((response) => {
location.reload();
});
}
}
}
</script>
<style>
.chat-panel {
min-height: 15px;
max-height: 200px;
overflow: scroll;
}
.arrow_box {
width:10px;
height:10px;
transition: all .3s;
padding-bottom:0px;
position:absolute;
margin:20px 0px 0px -15px;
}
.arrow_box:after, .arrow_box:before {
border: solid transparent;
content: " ";
position: absolute;
}
.arrow_box:after {
border-width: 5px;
}
.arrow_box:before {
border-left-color: #000;
border-width: 5px;
}
.arrow_box--open{
transform: rotateZ(90deg);
transform-origin: 50% 50%;
}
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.