import SwiftUI
import Supabase
struct PresenceUser: Identifiable, Codable {
let id: String
let name: String
}
struct GameLiveViewerCount: View {
let game: Core_V1beta_Game
@State var liveUsers: [String: PresenceUser] = [:]
@State var channel: RealtimeChannelV2?
var body: some View {
HStack {
Image(systemName: "eye").resizable().scaledToFit().frame(width: 10, height: 10)
Text("\(liveUsers.count)").font(.caption2)
}
.foregroundStyle(.secondary)
.onAppear {
Task { await subscribe() }
}
.onDisappear {
Task { await unsubscribe() }
}
}
func subscribe() async {
do {
await unsubscribe()
await ensureSession()
let channelId = "game:\(game.id):viewers"
print("channelID: \(channelId)")
channel = supabase.channel(channelId)
if let channel {
let presenceStream = channel.presenceChange()
try await channel.subscribeWithError()
self.channel = channel
// Track current user
let uuid = UUID().uuidString
try await channel.track(
PresenceUser(id: uuid, name: "Seb")
)
// Listen to presence changes
for await presence in presenceStream {
let joinedUsers = try presence.decodeJoins(as: PresenceUser.self)
for user in joinedUsers {
liveUsers[user.id] = user
}
let leftUsers = try presence.decodeLeaves(as: PresenceUser.self)
for user in leftUsers {
liveUsers.removeValue(forKey: user.id)
}
}
}
} catch {
print("Error: \(error)")
}
}
func unsubscribe() async {
if let channel {
await channel.untrack()
await channel.unsubscribe()
}
}
}
import SwiftUI
import Supabase
struct PresenceUser: Identifiable, Codable {
let id: String
let name: String
}
struct GameLiveViewerCount: View {
let game: Core_V1beta_Game
@State var liveUsers: [String: PresenceUser] = [:]
@State var channel: RealtimeChannelV2?
var body: some View {
HStack {
Image(systemName: "eye").resizable().scaledToFit().frame(width: 10, height: 10)
Text("\(liveUsers.count)").font(.caption2)
}
.foregroundStyle(.secondary)
.onAppear {
Task { await subscribe() }
}
.onDisappear {
Task { await unsubscribe() }
}
}
func subscribe() async {
do {
await unsubscribe()
await ensureSession()
let channelId = "game:\(game.id):viewers"
print("channelID: \(channelId)")
channel = supabase.channel(channelId)
if let channel {
let presenceStream = channel.presenceChange()
try await channel.subscribeWithError()
self.channel = channel
// Track current user
let uuid = UUID().uuidString
try await channel.track(
PresenceUser(id: uuid, name: "Seb")
)
// Listen to presence changes
for await presence in presenceStream {
let joinedUsers = try presence.decodeJoins(as: PresenceUser.self)
for user in joinedUsers {
liveUsers[user.id] = user
}
let leftUsers = try presence.decodeLeaves(as: PresenceUser.self)
for user in leftUsers {
liveUsers.removeValue(forKey: user.id)
}
}
}
} catch {
print("Error: \(error)")
}
}
func unsubscribe() async {
if let channel {
await channel.untrack()
await channel.unsubscribe()
}
}
}