Permalink
Browse files

feat: typing indicator

  • Loading branch information...
akazorg committed Nov 16, 2018
1 parent df96ecf commit 3e85d903865925c7665fb845406cf72238b1452f
@@ -1,3 +1,4 @@
import _ from 'lodash';
import Vue from 'vue';
import axios from 'axios';
import BootstrapVue from 'bootstrap-vue';
@@ -7,7 +8,6 @@ import vuescroll from 'vuescroll/dist/vuescroll-native';

import 'vuescroll/dist/vuescroll.css';

window._ = require('lodash');
window.Vue = Vue;
window.swal = swal;
window.Bus = new Vue();
@@ -1,5 +1,5 @@
<template>
<div id="dialogs" class="conversations">
<div class="conversations" :class="{conversations__wait: is_loading_conv}">
<div v-show="is_loading" class="mercurius__loading">
<svg class="ic"><use xlink:href="#icon-ani-puff"></use></svg>
<h5 class="mt-3">{{ 'loading_conversations' | __ }}</h5>
@@ -36,7 +36,7 @@
>
<a
href="#"
@click.prevent="open(conversation)"
@click.prevent="onOpen(conversation)"
>
<mercurius-avatar
class="mr-3 pull-left"
@@ -66,12 +66,14 @@
</template>

<script>
import ConversationsHttp from './conversations-http';
export default {
props: ['conversations'],
mixins: [
require('./conversations-http'),
ConversationsHttp,
],
@@ -80,6 +82,7 @@ export default {
active: false,
filterStr: '',
is_appending: false,
is_loading_conv: false,
onLoadOpenFirst: false,
placeholder: '/vendor/mercurius/img/avatar/avatar_placeholder.png',
}
@@ -89,6 +92,7 @@ export default {
created() {
Bus.$on('mercuriusComposeNewMessage', () => this.onComposeNewMessage())
Bus.$on('mercuriusConversationsLoaded', res => this.onConversationsLoaded(res));
Bus.$on('mercuriusConversationLoaded', conv => this.onConversationLoaded(conv));
Bus.$on('mercuriusFilterConversations', str => this.onFilter(str))
Bus.$on('mercuriusMessageDeleted', (msg, msgLatest) => this.onMessageDeleted(msg, msgLatest))
Bus.$on('mercuriusMessageReceived', (usr, sender, msg) => this.onMessageReceived(sender, msg))
@@ -98,7 +102,7 @@ export default {
mounted() {
this.loadConversations()
this.loadConversations();
},
@@ -136,16 +140,12 @@ export default {
getMsg(conv) {
return (this._received(conv) ? '':'You: ') + conv.message
},
isTyping(conv) {
return !_.isEmpty(conv.typing) && conv.typing
},
getAvatar(img) {
return (img.avatar = img.avatar || this.placeholder)
},
open(conversation) {
this.is_appending = false
this.active = conversation
this.active.seen_at = moment.utc().format('YYYY-MM-DD HH:mm:ss');
Bus.$emit('mercuriusOpenConversation', this.active);
},
refreshMessage(msg) {
this.active.sender = msg.sender
this.active.message = msg.message
@@ -185,12 +185,23 @@ export default {
// Event handlers
//
onOpen(conv) {
if (this.is_loading_conv) return
this.is_appending = false
this.is_loading_conv = true
this.active = conv
Bus.$emit('mercuriusConversationOpen', conv);
},
onConversationLoaded(conv) {
this.is_loading_conv = false
this.active.seen_at = moment.utc().format('YYYY-MM-DD HH:mm:ss');
},
onConversationsLoaded(res) {
if (this.onLoadOpenFirst && res.length > 0) this.open(res[0])
if (this.onLoadOpenFirst && res.length > 0) this.onOpen(res[0])
},
onRecipientSelected(recipient) {
let item = this._findOrCreate(recipient);
this.open(item)
this.onOpen(item)
},
onMessageReceived(sender, msg) {
let item = this._findOrCreate(sender);
@@ -209,5 +220,5 @@ export default {
this.filterStr = str;
},
}
}
};
</script>
@@ -1,4 +1,4 @@
module.exports = {
export default {
data() {
return {
is_loading: false,
@@ -13,13 +13,14 @@ module.exports = {
* @param {string} recipient
* @param {string} message
*/
loadConversations() {
async loadConversations() {
this.is_loading = true

setTimeout(() => {
return new Promise((resolve, reject) => {
axios.get('/conversations')
.then(res => {
Bus.$emit('mercuriusConversationsLoaded', res.data);
resolve(res);
})
.catch(err => {
swal(
@@ -28,12 +29,12 @@ module.exports = {
+'\n'+error.response.data.message,
'error'
)

reject(errors);
})
.finally(() => {
this.is_loading = false
})
}, 500);
});
},


@@ -15,5 +15,5 @@ export default {
Bus.$emit('mercuriusComposeNewMessage');
},
}
}
};
</script>
@@ -7,7 +7,7 @@
* @param {array} args attributes used with translations
* @return {string}
*/
const __ = function(key, args) {
function __(key, args) {
let trans = _.get(Mercurius.i18n, key);

_.eachRight(args, (value, key) => {
@@ -25,7 +25,8 @@ module.exports = {

Bus.$on('mercuriusConversationsLoaded', res => this.onConversationsLoaded(res));
Bus.$on('mercuriusConversationDeleted', usrId => this.onConversationDeleted(usrId));
Bus.$on('mercuriusOpenConversation', conv => this.onOpenConversation(conv));
Bus.$on('mercuriusConversationOpen', conv => this.onConversationOpen(conv));
Bus.$on('mercuriusConversationLoaded', conv => {this.conversation = conv});
Bus.$on('mercuriusComposeNewMessage', () => this.onComposeNewMessage());
},

@@ -46,23 +47,40 @@ module.exports = {

methods: {
/**
* Setup event listener using Laravel Echo and Pusher.
* Setup event listener using Laravel Echo.
*/
listen() {
Echo.private('mercurius.'+this.user.slug)
.listen('.mercurius.message.sent', this.onMessageReceived)
.listen('.mercurius.user.status.changed', this.onUserStatusChanged)
.listenForWhisper('typing', (e) => {
// console.log(e);
// Bus.$emit('mercuriusUserTyping', true);

// setTimeout( () => {
// Bus.$emit('mercuriusUserTyping', false);
// }, 1000)
.listen('.mercurius.user.status.changed', this.onUserStatusChanged);

Echo.private('mercurius.conversation.'+this.user.slug)
.listenForWhisper('typing', (usr) => {
Bus.$emit('mercuriusUserTyping', usr)
});
},


/**
* When opening a conversation.
*/
onConversationOpen(conv) {
this.conversation = false
this.finding_recipient = false
},


/**
* Closes a conversation.
*
* @param {object} conv
*/
onConversationClose(conv) {
this.conversation = false
Bus.$emit('mercuriusConversationClose');
},


/**
* Message was received.
*
@@ -81,26 +99,17 @@ module.exports = {
},


/**
* When opening a conversation.
*/
onOpenConversation(conv) {
this.conversation = conv
this.finding_recipient = false
},


/**
* When composing a new message.
*/
onComposeNewMessage() {
this.conversation = false
this.onConversationClose(this.conversation);
this.finding_recipient = true
},


/**
* Conversation was loaded.
* Conversations list was loaded.
*/
onConversationsLoaded(data) {
this.conversations = data;
@@ -7,7 +7,7 @@
:class="{disabled: is_sending}"
ref="inpmessage"
v-model.trim="message"
@keydown="onTyping"
@input="onTyping"
@keyup.enter="onSend"
:placeholder="'type_message' | __"
:disabled="is_sending"
@@ -39,13 +39,13 @@ export default {
data() {
return {
message: '',
is_typing: false,
typing: false
}
},
created() {
Bus.$on('mercuriusComposeNewMessage', () => this.reset())
Bus.$on('mercuriusConversationLoaded', conv => this.onConversationLoaded(conv))
Bus.$on('mercuriusConversationDeleted', user => this.onConversationDeleted(user));
Bus.$on('mercuriusMessageSent', () => this.reset())
},
@@ -55,24 +55,23 @@ export default {
reset() {
this.message = ''
},
onConversationLoaded(conv) {
this.reset();
setTimeout(() => { this.$refs.inpmessage.focus() }, 125);
},
onConversationDeleted(user) {
if (this.conversation.slug === user) this.reset()
},
onTyping() {
if (this.is_typing) return;
// let channel = Echo.private('mercurius.'+this.conversation.slug);
// setTimeout(function() {
// channel.whisper('typing', {
// user: Mercurius.user.slug,
// typing: true
// });
// }, 250);
},
onSend() {
if (_.isEmpty(this.message)) return
this.sendMessage(this.conversation.slug, this.message);
},
onTyping() {
let channel = Echo.private('mercurius.conversation.'+this.conversation.slug);
setTimeout(function() {
channel.whisper('typing', Mercurius.user.slug);
}, 500);
},
},
@@ -81,5 +80,5 @@ export default {
return !_.isEmpty(this.conversation);
},
},
}
};
</script>
Oops, something went wrong.

0 comments on commit 3e85d90

Please sign in to comment.