Sessions in a lab are now collaborative artifacts. Any owner can host (own the local Frida attachment) and any owner can drive (issue REPL evals and instrument commands); a driver's actions are relayed to the current host. Members watch read-only and see an "Only lab owners can host sessions" CTA when they try the new session button. Re-host (Run on My Device…) lets an owner take over a running session by attaching to their own equivalent process; the prior host's Frida attachment detaches and the new host auto-loads the session's instruments. Driver auto-reverts to host when the current driver fully disconnects from the lab.
35 lines
1005 B
Swift
35 lines
1005 B
Swift
import LumaCore
|
|
import SwiftUI
|
|
|
|
struct UserAvatarView: View {
|
|
let user: LumaCore.CollaborationSession.UserInfo
|
|
let size: CGFloat
|
|
|
|
var body: some View {
|
|
Group {
|
|
if let url = sizedAvatarURL {
|
|
AsyncImage(url: url) { image in
|
|
image.resizable().scaledToFill()
|
|
} placeholder: {
|
|
Color.secondary.opacity(0.15)
|
|
}
|
|
} else {
|
|
Image(systemName: "person.crop.circle.fill")
|
|
.resizable()
|
|
.scaledToFit()
|
|
.foregroundStyle(.secondary)
|
|
}
|
|
}
|
|
.frame(width: size, height: size)
|
|
.clipShape(Circle())
|
|
.overlay(
|
|
Circle().strokeBorder(Color.secondary.opacity(0.3), lineWidth: 0.5)
|
|
)
|
|
}
|
|
|
|
private var sizedAvatarURL: URL? {
|
|
let pixels = Int(size * 2)
|
|
return user.avatarURL.flatMap { URL(string: "\($0.absoluteString)&s=\(pixels)") }
|
|
}
|
|
}
|