Skip to content

Commit 6e38f26

Browse files
committed
add getstream.io 2 keys
1 parent 2e60a57 commit 6e38f26

File tree

15 files changed

+6827
-10717
lines changed

15 files changed

+6827
-10717
lines changed

app/channels/message_channel.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# app/channels/message_channel.rb
2+
class MessageChannel < ApplicationCable::Channel
3+
def subscribed
4+
# Stream from a channel based on the current user's ID or another identifier
5+
stream_from "message_channel_#{current_user.id}"
6+
end
7+
8+
def unsubscribed
9+
# Any cleanup needed when channel is unsubscribed
10+
end
11+
end

app/controllers/messages_controller.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@ def create
1414
end
1515
end
1616

17+
def unread_count
18+
# Assuming you have a method to fetch unread count for the current user
19+
unread_count = Message.where(user_id: current_user.id, read: false).count
20+
21+
render json: { unreadCount: unread_count }
22+
end
23+
1724
private
1825
def set_room
1926
@room = Room.find(params[:room_id])
Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,25 @@
1-
import consumer from "./consumer"
1+
import { createConsumer } from "@rails/actioncable"
22

3-
consumer.subscriptions.create("ChatChannel", {
4-
connected() {
5-
// Called when the subscription is ready for use on the server
6-
},
3+
const consumer = createConsumer()
74

8-
disconnected() {
9-
// Called when the subscription has been terminated by the server
10-
},
5+
document.addEventListener("DOMContentLoaded", () => {
6+
const room = document.getElementById("chat-room-id").value
7+
const chatChannel = consumer.subscriptions.create(
8+
{ channel: "ChatChannel", room: room },
9+
{
10+
received(data) {
11+
console.log("Received message:", data.message)
12+
// Handle the received message (e.g., append to chat log)
13+
},
14+
sendMessage(message) {
15+
this.perform('send_message', { message: message })
16+
}
17+
}
18+
)
1119

12-
received(data) {
13-
// Called when there's incoming data on the websocket for this channel
14-
}
15-
});
20+
// Example usage
21+
document.getElementById("send-button").addEventListener("click", () => {
22+
const message = document.getElementById("message-input").value
23+
chatChannel.sendMessage(message)
24+
})
25+
})

app/models/message.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,15 @@
11
class Message < ApplicationRecord
22
belongs_to :room
33
broadcasts_to :room
4+
5+
after_create_commit :broadcast_unread_count
6+
7+
private
8+
9+
def broadcast_unread_count
10+
# Replace this with your logic to calculate unread messages
11+
unread_count = Message.where(user_id: self.user_id, read: false).count
12+
13+
ActionCable.server.broadcast("message_channel_#{self.user_id}", { unread_count: unread_count })
14+
end
415
end

client/.env-example

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
POSTGRES_PRISMA_URL=postgresql://postgres:@localhost:5432/ruby_rails_boilerplate_development
22
POSTGRES_URL_NON_POOLING=postgresql://postgres:@localhost:5432/ruby_rails_boilerplate_development
3-
NEXT_PUBLIC_STREAM_KEY=
4-
STREAM_SECRET=
3+
NEXT_PUBLIC_STREAM_KEY=6cqupfrs4qh3
4+
STREAM_SECRET=djkppj5rnre3bfqvraufhv8asfkbtngjpx8np7xhnumnege5542sg4vvcx7wx5xq
55
NEXT_PUBLIC_UPLOADTHING_APP_ID=
66
CRON_SECRET=

client/README.md

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,44 @@
22

33
A full-stack social media app with infinite loading, optimistic updates, authentication, DMs, notifications, file uploads, and much more.
44

5-
Watch the free tutorial on YouTube: https://www.youtube.com/watch?v=TyV12oBDsYI
5+
Watch the free tutorial on YouTube PART 1: https://www.youtube.com/watch?v=TyV12oBDsYI
6+
7+
Timestamps:
8+
0:00 - Project overview
9+
16:54 - Project & IDE setup (create-next-app, Shadcn UI, Prettier Tailwind plugin, Prisma, extensions)
10+
40:52 - DB setup (Vercel Postgres + Prisma ORM)
11+
46:02 - Lucia Auth setup (username, email, password login)
12+
2:35:11 - Navbar, SessionProvider, user button
13+
3:17:41 - Dark mode (next-themes)
14+
3:24:00 - Responsive sticky sidebar/bottom bar
15+
3:34:21 - Creating posts (TipTap editor)
16+
3:52:06 - Loading posts server-side (server component)
17+
4:08:42 - Trending topics sidebar (unstable_cache, Suspense)
18+
4:35:25 - React Query introduction (useQuery, QueryClient, QueryClientProvider, ReactQueryDevTools)
19+
4:52:59 - Ky setup
20+
4:57:46 - useInfiniteQuery (infinite loading, cursor-based pagination, react-intersection-observer)
21+
5:22:29 - React Query cache mutation (useMutation, setQueriesData vs invalidateQueries)
22+
5:41:21 - Deleting posts
23+
6:08:50 - Follow feature (React Query optimistic updates)
24+
6:53:47 - Following feed (Shadcn UI customization)
25+
7:01:21 - User profile page (generateMetadata, loading.tsx, not-found.tsx)
26+
27+
Watch the free tutorial on YouTube PART 2: https://www.youtube.com/watch?v=1nKETjqJluI&t
28+
29+
Timestamps:
30+
0:00 - User tooltip & react-linkify-it
31+
30:26 - Update user profile & upload avatar (UploadThing, react-cropper, react-image-file-resizer)
32+
1:42:48 - Post media uploads (image & video)
33+
2:38:48 - Drag & drop and copy-paste uploads
34+
2:46:07 - Cron job to delete orphaned uploads (Vercel cron)
35+
2:57:52 - Post details page
36+
3:14:58 - Likes feature (optimistic updates)
37+
3:35:14 - Bookmarks feature
38+
3:50:27 - Comments feature (with infinite loading)
39+
4:49:02 - Notifications feature (Prisma transactions)
40+
5:39:06 - Direct messages feature (Stream Chat)
41+
7:20:36 - Google signin (OAuth2, Lucia)
42+
7:48:20 - Search feature (+ rewrites)
43+
8:01:51 - Deployment (Vercel, custom install command)
644

745
![thumbnail 7](https://github.com/user-attachments/assets/686b37e4-3d16-4bc4-a7f2-9d152c3addf5)

0 commit comments

Comments
 (0)