Skip to content

Commit c31455a

Browse files
Make websocket send details of discussion in JSON whenever an update occurs
1 parent 6edf1b4 commit c31455a

File tree

2 files changed

+37
-52
lines changed

2 files changed

+37
-52
lines changed

Sources/App/Controllers/DiscussionController.swift

Lines changed: 15 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,16 @@ import Vapor
33

44
let store = WebSocketManagerStore()
55

6+
func broadcastUpdate(_ req: Request, discussionId: UUID) async throws {
7+
let discussionDetails = try await Discussion.getDetails(request: req, discussionId: discussionId)
8+
9+
let wsManager = await store.getWebSocket(for: discussionId)
10+
11+
if let wsManager = wsManager {
12+
wsManager.broadcast(discussionDetails.getJSONData())
13+
}
14+
}
15+
616
struct DiscussionController: RouteCollection {
717
func boot(routes: RoutesBuilder) throws {
818
let api = routes.grouped("api")
@@ -94,11 +104,7 @@ struct DiscussionController: RouteCollection {
94104

95105
try await participant.save(on: req.db)
96106

97-
let wsManager = try await store.getWebSocket(for: discussion.requireID())
98-
99-
if let wsManager = wsManager {
100-
wsManager.broadcast("participant-joined".data(using: .utf8)!)
101-
}
107+
try await broadcastUpdate(req, discussionId: discussion.requireID())
102108

103109
return Response(status: .ok, body: .init(string: "Successfully joined discussion"))
104110
}
@@ -107,16 +113,7 @@ struct DiscussionController: RouteCollection {
107113
func getDetails(_ req: Request) async throws -> Discussion {
108114
let discussionId = try req.parameters.require("discussionId")
109115

110-
let discussion = try await Discussion.query(on: req.db)
111-
.filter(\.$id == UUID(uuidString: discussionId) ?? UUID())
112-
.with(\.$author)
113-
.with(\.$participants)
114-
.with(\.$comments)
115-
.first()
116-
117-
guard let discussion = discussion else {
118-
throw Abort(.notFound, reason: "Discussion not found")
119-
}
116+
let discussion = try await Discussion.getDetails(request: req, discussionId: UUID(uuidString: discussionId) ?? UUID())
120117

121118
let isDiscussionIncludesUser = try await Participant.query(on: req.db)
122119
.filter(\.$discussion.$id == discussion.requireID())
@@ -151,11 +148,7 @@ struct DiscussionController: RouteCollection {
151148

152149
try await participant.delete(on: req.db)
153150

154-
let wsManager = try await store.getWebSocket(for: discussion.requireID())
155-
156-
if let wsManager = wsManager {
157-
wsManager.broadcast("participant-left".data(using: .utf8)!)
158-
}
151+
try await broadcastUpdate(req, discussionId: discussion.requireID())
159152

160153
return Response(status: .ok, body: .init(string: "Successfully left discussion"))
161154
}
@@ -203,11 +196,7 @@ struct DiscussionController: RouteCollection {
203196

204197
try await comment.save(on: req.db)
205198

206-
let wsManager = try await store.getWebSocket(for: discussion.requireID())
207-
208-
if let wsManager = wsManager {
209-
wsManager.broadcast("comment-added".data(using: .utf8)!)
210-
}
199+
try await broadcastUpdate(req, discussionId: discussion.requireID())
211200

212201
return comment
213202
}
@@ -229,11 +218,7 @@ struct DiscussionController: RouteCollection {
229218

230219
try await comment.delete(on: req.db)
231220

232-
let wsManager = try await store.getWebSocket(for: discussion.requireID())
233-
234-
if let wsManager = wsManager {
235-
wsManager.broadcast("comment-deleted".data(using: .utf8)!)
236-
}
221+
try await broadcastUpdate(req, discussionId: discussion.requireID())
237222

238223
return req.redirect(to: "/api/discussions/\(discussionId)/comments")
239224
}

Sources/App/Models/Discussion.swift

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import Fluent
22
import Vapor
33

4-
final class Discussion: Model, Content, @unchecked Sendable {
4+
final class Discussion: Model, Content, @unchecked Sendable, Codable {
55
static let schema = "discussions"
66

77
@ID(key: .id)
@@ -36,24 +36,24 @@ final class Discussion: Model, Content, @unchecked Sendable {
3636
}
3737
}
3838

39-
// extension Discussion {
40-
// func toDictionary(request: Request) async throws -> [String: String] {
41-
// let dateFormatter = ISO8601DateFormatter()
42-
// let createdAtString = dateFormatter.string(from: createdAt ?? Date())
43-
// let updatedAtString = dateFormatter.string(from: updatedAt ?? Date())
44-
45-
// let participants = try await Participant.query(on: request.db)
46-
// .filter(\.$discussion.$id == $id.value!)
47-
// .all()
48-
49-
// let participantsString = try JSONSerialization.data(withJSONObject: participants).base64EncodedString()
50-
51-
// return [
52-
// "id": id?.uuidString ?? "",
53-
// "title": title,
54-
// "createdAt": createdAtString,
55-
// "updatedAt": updatedAtString,
56-
// "participants": participantsString,
57-
// ]
58-
// }
59-
// }
39+
extension Discussion {
40+
func getJSONData() -> Data {
41+
let encoder = JSONEncoder()
42+
encoder.dateEncodingStrategy = .iso8601
43+
return try! encoder.encode(self)
44+
}
45+
46+
static func getDetails(request: Request, discussionId: UUID) async throws -> Discussion {
47+
let discussion = try await Discussion.query(on: request.db)
48+
.filter(\.$id == discussionId)
49+
.with(\.$author)
50+
.with(\.$participants)
51+
.with(\.$comments)
52+
.first()
53+
54+
guard let discussion = discussion else {
55+
throw Abort(.notFound, reason: "Discussion not found")
56+
}
57+
return discussion
58+
}
59+
}

0 commit comments

Comments
 (0)