Skip to content

Commit

Permalink
Feature: Add online status to each user (chatwoot#452)
Browse files Browse the repository at this point in the history
* Feature: Add online status to each user
* Add OnlineStatusable, add availability status to thumbnail
  • Loading branch information
pranavrajs authored Feb 2, 2020
1 parent 1f4703d commit 0b31e14
Show file tree
Hide file tree
Showing 14 changed files with 106 additions and 14 deletions.
5 changes: 5 additions & 0 deletions app/channels/room_channel.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
class RoomChannel < ApplicationCable::Channel
def subscribed
stream_from params[:pubsub_token]
::OnlineStatusTracker.add_subscription(params[:pubsub_token])
end

def unsubscribed
::OnlineStatusTracker.remove_subscription(params[:pubsub_token])
end
end
2 changes: 1 addition & 1 deletion app/controllers/api/v1/agents_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ class Api::V1::AgentsController < Api::BaseController
before_action :build_agent, only: [:create]

def index
render json: agents
@agents = agents
end

def destroy
Expand Down
30 changes: 28 additions & 2 deletions app/javascript/dashboard/components/widgets/Thumbnail.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,17 @@
:size="avatarSize"
/>
<img
v-if="badge === 'Channel::FacebookPage'"
v-if="badge === 'Channel::FacebookPage' && status !== ''"
id="badge"
class="source-badge"
:style="badgeStyle"
src="~dashboard/assets/images/fb-badge.png"
/>
<div
v-else-if="status === 'online'"
class="source-badge user--online"
:style="statusStyle"
></div>
</div>
</template>
<script>
Expand All @@ -41,6 +46,7 @@ export default {
props: {
src: {
type: String,
default: '',
},
size: {
type: String,
Expand All @@ -52,6 +58,11 @@ export default {
},
username: {
type: String,
default: '',
},
status: {
type: String,
default: '',
},
},
data() {
Expand All @@ -67,6 +78,10 @@ export default {
const badgeSize = `${this.avatarSize / 3}px`;
return { width: badgeSize, height: badgeSize };
},
statusStyle() {
const statusSize = `${this.avatarSize / 4}px`;
return { width: statusSize, height: statusSize };
},
},
methods: {
onImgError() {
Expand All @@ -78,6 +93,7 @@ export default {

<style lang="scss" scoped>
@import '~dashboard/assets/scss/variables';
@import '~dashboard/assets/scss/foundation-settings';
@import '~dashboard/assets/scss/mixins';
.user-thumbnail-box {
Expand All @@ -91,11 +107,21 @@ export default {
}
.source-badge {
bottom: -$space-micro / 2;
bottom: -$space-micro;
height: $space-slab;
position: absolute;
right: $zero;
width: $space-slab;
}
.user--online {
background: $success-color;
border-radius: 50%;
bottom: $space-micro;
&:after {
content: ' ';
}
}
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
size="56px"
:badge="contact.channel"
:username="contact.name"
:status="contact.availability_status"
/>
<div class="contact--details">
<div class="contact--name">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@
<!-- Gravtar Image -->
<td>
<thumbnail
:src="gravatarUrl(agent.email)"
:src="agent.thumbnail"
class="columns"
:username="agent.name"
size="40px"
:status="agent.availability_status"
/>
</td>
<!-- Agent Name + Email -->
Expand Down
10 changes: 4 additions & 6 deletions app/javascript/widget/store/modules/conversation.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ export const getters = {
Object.values(_state.conversations),
message => new DateHelper(message.created_at).format()
);

return Object.keys(conversationGroupedByDate).map(date => {
const messages = conversationGroupedByDate[date].map((message, index) => {
let showAvatar = false;
Expand All @@ -59,12 +58,11 @@ export const getters = {
const nextMessage = conversationGroupedByDate[date][index + 1];
const currentSender = message.sender ? message.sender.name : '';
const nextSender = nextMessage.sender ? nextMessage.sender.name : '';
showAvatar = currentSender !== nextSender;
showAvatar =
currentSender !== nextSender ||
message.message_type !== nextMessage.message_type;
}
return {
showAvatar,
...message,
};
return { showAvatar, ...message };
});

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,19 +61,27 @@ describe('#getters', () => {
id: 1,
content: 'Thanks for the help',
created_at: 1574075964,
message_type: 0,
},
2: {
id: 2,
content: 'Yes, It makes sense',
created_at: 1574092218,
message_type: 0,
},
3: {
id: 3,
content: 'Hey',
created_at: 1576340623,
created_at: 1574092218,
message_type: 1,
},
4: {
id: 4,
content: 'Hey',
created_at: 1576340623,
},
5: {
id: 5,
content: 'How may I help you',
created_at: 1576340626,
},
Expand All @@ -88,26 +96,35 @@ describe('#getters', () => {
content: 'Thanks for the help',
created_at: 1574075964,
showAvatar: false,
message_type: 0,
},
{
id: 2,
content: 'Yes, It makes sense',
created_at: 1574092218,
showAvatar: true,
message_type: 0,
},
{
id: 3,
content: 'Hey',
created_at: 1574092218,
showAvatar: true,
message_type: 1,
},
],
},
{
date: 'Dec 14, 2019',
messages: [
{
id: 3,
id: 4,
content: 'Hey',
created_at: 1576340623,
showAvatar: false,
},
{
id: 4,
id: 5,
content: 'How may I help you',
created_at: 1576340626,
showAvatar: true,
Expand Down
11 changes: 11 additions & 0 deletions app/models/concerns/availability_statusable.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module AvailabilityStatusable
extend ActiveSupport::Concern

def online?
::OnlineStatusTracker.subscription_count(pubsub_token) != 0
end

def availability_status
online? ? 'online' : 'offline'
end
end
1 change: 1 addition & 0 deletions app/models/contact.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
class Contact < ApplicationRecord
include Pubsubable
include Avatarable
include AvailabilityStatusable
validates :account_id, presence: true

belongs_to :account
Expand Down
1 change: 1 addition & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class User < ApplicationRecord
include Events::Types
include Pubsubable
include Avatarable
include AvailabilityStatusable
include Rails.application.routes.url_helpers

devise :database_authenticatable,
Expand Down
10 changes: 10 additions & 0 deletions app/views/api/v1/agents/index.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
json.array! @agents do |agent|
json.account_id agent.account_id
json.availability_status agent.availability_status
json.confirmed agent.confirmed?
json.email agent.email
json.id agent.id
json.name agent.name
json.role agent.role
json.thumbnail agent.avatar_url
end
3 changes: 2 additions & 1 deletion app/views/api/v1/contacts/show.json.jbuilder
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
json.payload do
json.availability_status @contact.availability_status
json.email @contact.email
json.id @contact.id
json.name @contact.name
json.email @contact.email
json.phone_number @contact.phone_number
json.thumbnail @contact.avatar_url
end
1 change: 1 addition & 0 deletions app/views/api/v1/widget/inbox_members/index.json.jbuilder
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ json.payload do
json.array! @inbox_members do |inbox_member|
json.name inbox_member.user.name
json.avatar_url inbox_member.user.avatar_url
json.availability_status inbox_member.user.availability_status
end
end
19 changes: 19 additions & 0 deletions lib/online_status_tracker.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module OnlineStatusTracker
def self.add_subscription(channel_id)
count = subscription_count(channel_id)
::Redis::Alfred.setex(channel_id, count + 1)
end

def self.remove_subscription(channel_id)
count = subscription_count(channel_id)
if count == 1
::Redis::Alfred.delete(channel_id)
elsif count != 0
::Redis::Alfred.setex(channel_id, count - 1)
end
end

def self.subscription_count(channel_id)
::Redis::Alfred.get(channel_id).to_i
end
end

0 comments on commit 0b31e14

Please sign in to comment.