Skip to content

Instantly share code, notes, and snippets.

@mahfuz10
Created February 11, 2024 16:09
Show Gist options
  • Save mahfuz10/810aab8b407a35325b786a24450d1d2c to your computer and use it in GitHub Desktop.
Save mahfuz10/810aab8b407a35325b786a24450d1d2c to your computer and use it in GitHub Desktop.
Some code from a chat example with React JS, in a Rails 7 application
<template>
<div class="chat-container"
:class="activeChat ? 'selected' : ''"
@click="$emit('chat:select', chat.id)" style="cursor: pointer">
<div class="chat-card-header">
<div class="chat-name">
{{ otherUser }}
</div>
<div class="chat-updated">
{{ chat.updated_at }}
</div>
</div>
<div class="chat-object">
{{ `${chat.chatable_name} #${chat.chatable_id}` }}
</div>
<template v-if="chat.last_message">
<div class="last-message">
<span class="text-muted">{{ chat.last_message.user_id != userId ? otherUser : 'Me' }}:</span>
{{ chat.last_message.message}}
</div>
</template>
</div>
</template>
<script>
export default {
name: 'ChatElement',
props: {
chat: Object,
userId: Number,
otherUser: String,
activeChat: Boolean
},
}
</script>
<template>
<div class="chat-block-container">
<div class="chats-list">
<template v-for="(chat, index) in chats" :key="chat.id">
<ChatElement
:chat.sync="chats[index]"
:user-id="userId"
:otherUser="otherUserName(chats[index].id)"
:activeChat="chat.id == activeChat.id"
@chat:select="setActiveChat"
/>
</template>
</div>
<div class="messages-container">
<h3 class="p-2">{{ otherUserName(activeChat.id) }}</h3>
<div class="messages-list">
<template v-for="(message, index) in messages" :key="message.id">
<Message :message.sync="messages[index]" :user-id="userId"/>
</template>
</div>
<div class="add-message-container">
<textarea id="messageInput"
class="form-control"
@keyup.enter.exact="addMessage"
v-model="newMessage"></textarea>
<div class="message-buttons">
<button @click="addMessage" class="btn btn-primary send-button" disabled>
<i class="bi bi-send m-0 me-1"></i>
Send
</button>
</div>
</div>
</div>
</div>
</template>
<script>
import Message from './message.vue';
import ChatElement from './chat_element.vue';
export default {
name: 'ChatContainer',
components: { Message, ChatElement, Attachment, Document },
data() {
return {
chatId: $('#chatContainer').data('chat-id'),
userId: $('#chatContainer').data('user-id'),
},
created() {
$.get(this.chatsUrl, (result) => {
this.chats = result
this.setActiveChat(this.chatId)
});
let container = this;
consumer.subscriptions.create(
{ channel: "UserChatsChannel", user: $('#chatContainer').data('user-id') },
{ received(data) {
let chatPosition = container.chats.findIndex(e => e.id == data.id)
if ( chatPosition >= 0 ) {
container.chats[chatPosition].last_message = data.last_message
container.chats[chatPosition].updated_at = data.updated_at
} else {
container.chats.push(data)
}
container.reorderChats()
}}
)
},
}
... more code ...
</script>
/* global I18n */
import { createApp } from 'vue/dist/vue.esm-bundler.js';
import ChatContainer from './chat/container.vue';
window.initChatComponent = () => {
app = createApp({})
app.component('ChatContainer', ChatContainer);
app.mount('#chatContainer')
};
document.addEventListener('turbo:load', function(){
if ($('#chatContainer').length) {
initChatComponent()
}
})
<div id='chatContainer'
data-user-id="<%= current_user.id %>"
data-chat-id="<%= @chat.id if @chat.present? %>"
data-messages-url="<%= chat_path(@chat) if @chat.present? %>"
data-add-message-url="<%= chat_chat_messages_path(@chat) if @chat.present? %>"
data-chats-url="<%= user_chats_chats_path %>"
>
<chat-container/>
</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment