diff --git a/addon/components/chat-container.js b/addon/components/chat-container.js index 146800d..4530787 100644 --- a/addon/components/chat-container.js +++ b/addon/components/chat-container.js @@ -1,11 +1,6 @@ import Component from '@glimmer/component'; -import { tracked } from '@glimmer/tracking'; import { inject as service } from '@ember/service'; -import { action } from '@ember/object'; export default class ChatContainerComponent extends Component { @service chat; - constructor(owner) { - super(...arguments); - } } diff --git a/addon/components/chat-tray.hbs b/addon/components/chat-tray.hbs index bd2ada0..3ea068c 100644 --- a/addon/components/chat-tray.hbs +++ b/addon/components/chat-tray.hbs @@ -25,13 +25,15 @@
{{#each this.channels as |channel|}} - - +
+ + +
{{/each}}
diff --git a/addon/components/chat-tray.js b/addon/components/chat-tray.js index ec24c9a..e3ab845 100644 --- a/addon/components/chat-tray.js +++ b/addon/components/chat-tray.js @@ -1,6 +1,6 @@ +import Component from '@glimmer/component'; import { action } from '@ember/object'; import { inject as service } from '@ember/service'; -import Component from '@glimmer/component'; import { tracked } from '@glimmer/tracking'; export default class ChatTrayComponent extends Component { @@ -8,7 +8,7 @@ export default class ChatTrayComponent extends Component { @service socket; @tracked channels = []; - constructor(owner) { + constructor() { super(...arguments); this.chat.loadChannels.perform({ withChannels: (channels) => { @@ -19,19 +19,30 @@ export default class ChatTrayComponent extends Component { @action openChannel(chatChannelRecord) { this.chat.openChannel(chatChannelRecord); + this.reloadChannels(); } @action startChat() { - this.openChannel(chatChannelRecord); + this.chat.createChatChannel('Untitled Chat').then((chatChannelRecord) => { + this.openChannel(chatChannelRecord); + }); } @action removeChannel(chatChannelRecord) { this.chat.deleteChatChannel(chatChannelRecord); - this.chat.loadChannels(); + this.reloadChannels(); } @action updateChatChannel(chatChannelRecord) { this.chat.deleteChatChannel(chatChannelRecord); - this.chat.loadChannels(); + this.reloadChannels(); + } + + reloadChannels() { + this.chat.loadChannels.perform({ + withChannels: (channels) => { + this.channels = channels; + }, + }); } } diff --git a/addon/components/chat-window.hbs b/addon/components/chat-window.hbs index f504fb0..5b5ed22 100644 --- a/addon/components/chat-window.hbs +++ b/addon/components/chat-window.hbs @@ -7,14 +7,13 @@
- - {{#each this.participants as |participant|}} - + {{#each this.availableUsers as |user|}} +
- +
- {{participant.name}} + {{user.name}}
{{/each}} @@ -25,9 +24,6 @@ -
@@ -37,6 +33,9 @@ +
{{/each}} diff --git a/addon/components/chat-window.js b/addon/components/chat-window.js index 3234c87..7fcf0ae 100644 --- a/addon/components/chat-window.js +++ b/addon/components/chat-window.js @@ -2,24 +2,43 @@ import Component from '@glimmer/component'; import { tracked } from '@glimmer/tracking'; import { inject as service } from '@ember/service'; import { action } from '@ember/object'; +import { task } from 'ember-concurrency'; export default class ChatWindowComponent extends Component { @service chat; + @service socket; @service currentUser; + @service modalsManager; @service fetch; @service store; @tracked channel; @tracked sender; @tracked senderIsCreator; - @tracked participants; + @tracked availableUsers = []; @tracked pendingMessageContent = ''; constructor(owner, { channel }) { super(...arguments); this.channel = channel; this.sender = this.getSenderFromParticipants(channel); - this.senderIsCreator = this.sender ? this.sender.id === channel.created_by_uuid : false; - this.participants = this.loadUsers() + this.listenChatChannel(channel); + this.loadAvailableUsers.perform(); + } + + async listenChatChannel(chatChannelRecord) { + this.socket.listen(`chat.${chatChannelRecord.public_id}`, (socketEvent) => { + console.log('[chat event]', socketEvent); + switch (socketEvent.event) { + case 'chat.added_participant': + case 'chat.removed_participant': + this.channel.reloadParticipants(); + break; + case 'chat_message.created': + // this.channel.reloadParticipants(); + this.chat.insertMessageFromSocket(this.channel, socketEvent.data); + break; + } + }); } @action sendMessage() { @@ -31,17 +50,20 @@ export default class ChatWindowComponent extends Component { this.chat.closeChannel(this.channel); } - @action loadUsers() { - return this.store.query('driver', { limit: 25}); - } - - @action addParticipant(participant){ - console.log("Channels : ", this.channel, participant) - this.chat.addParticipant(this.channel, participant) + @action addParticipant(user) { + this.chat.addParticipant(this.channel, user); } @action removeParticipant(participant) { - this.chat.removeParticipant(this.channel, participant); + this.modalsManager.confirm({ + title: `Are you sure you wish to remove this participant (${participant.name}) from the chat?`, + body: 'Proceeding remove this participant from the chat.', + confirm: (modal) => { + modal.startLoading(); + + return this.chat.removeParticipant(this.channel, participant); + }, + }); } @action positionWindow(chatWindowElement) { @@ -63,12 +85,19 @@ export default class ChatWindowComponent extends Component { }, 1000); } + @task *loadAvailableUsers(params = {}) { + const users = yield this.store.query('user', params); + this.availableUsers = users; + return users; + } + getSenderFromParticipants(channel) { const participants = channel.participants ?? []; const sender = participants.find((chatParticipant) => { return chatParticipant.user_uuid === this.currentUser.id; }); + this.senderIsCreator = sender ? sender.id === channel.created_by_uuid : false; return sender; } } diff --git a/addon/styles/components/chat.css b/addon/styles/components/chat.css index 985227e..e883f17 100644 --- a/addon/styles/components/chat.css +++ b/addon/styles/components/chat.css @@ -139,6 +139,7 @@ .chat-window-participants-container { padding: 0rem 0.5rem 0.5rem 0.5rem; background-color: #d1d5db; + display: flex; } .chat-window-participants-container > .chat-window-participant-name { @@ -158,6 +159,39 @@ .chat-window-participants-container .chat-window-participant-bubble-container { width: 30px; display: flex; + position: relative; +} + +.chat-window-participants-container .chat-window-participant-bubble-container > .chat-window-remove-participant { + opacity: 0; + position: absolute; + top: 0; + right: 0; + margin-right: -2px; + margin-top: -2px; + border-radius: 100%; + background-color: #ef4444; + color: #fff; + height: 14px; + width: 14px; + font-size: 12px; + font-weight: bold; + display: flex; + align-items: center; + justify-content: center; + text-align: center; + border: 1px #dc2626 solid; + box-shadow: + 0 10px 15px -3px rgb(0 0 0 / 0.1), + 0 4px 6px -4px rgb(0 0 0 / 0.1); +} + +.chat-window-participants-container .chat-window-participant-bubble-container > .chat-window-remove-participant:hover { + opacity: 0.5; +} + +.chat-window-participants-container .chat-window-participant-bubble-container:hover > .chat-window-remove-participant { + opacity: 1; } .chat-window-participants-container .chat-window-participant-bubble {