ios_client
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
import SwiftUI
|
||||
|
||||
struct CircularAvatarView: View {
|
||||
let name: String
|
||||
var imageData: Data?
|
||||
var size: CGFloat = 32
|
||||
var isGroup: Bool = false
|
||||
|
||||
var body: some View {
|
||||
if let imageData = imageData, let uiImage = UIImage(data: imageData) {
|
||||
Image(uiImage: uiImage)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fill)
|
||||
.frame(width: size, height: size)
|
||||
.clipShape(Circle())
|
||||
} else {
|
||||
// Default: colored circle with initial letter
|
||||
ZStack {
|
||||
Circle()
|
||||
.fill(avatarColor)
|
||||
.frame(width: size, height: size)
|
||||
|
||||
Text(initial)
|
||||
.font(.system(size: size * 0.4, weight: .semibold))
|
||||
.foregroundStyle(.white)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var initial: String {
|
||||
String(name.prefix(1)).uppercased()
|
||||
}
|
||||
|
||||
/// Deterministic color from name hash (matching Python gui_client behavior)
|
||||
private var avatarColor: Color {
|
||||
let colors: [Color] = [
|
||||
.red, .orange, .yellow, .green, .mint,
|
||||
.teal, .cyan, .blue, .indigo, .purple, .pink
|
||||
]
|
||||
var hash = 0
|
||||
for char in name.unicodeScalars {
|
||||
hash = hash &* 31 &+ Int(char.value)
|
||||
}
|
||||
return colors[abs(hash) % colors.count]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import SwiftUI
|
||||
|
||||
struct ConnectionIndicator: View {
|
||||
let status: ConnectionStatus
|
||||
|
||||
var body: some View {
|
||||
HStack(spacing: 4) {
|
||||
Circle()
|
||||
.fill(statusColor)
|
||||
.frame(width: 8, height: 8)
|
||||
|
||||
if status != .connected {
|
||||
Text(statusText)
|
||||
.font(.caption2)
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var statusColor: Color {
|
||||
switch status {
|
||||
case .connected: return .green
|
||||
case .connecting, .reconnecting: return .orange
|
||||
case .disconnected: return .red
|
||||
}
|
||||
}
|
||||
|
||||
private var statusText: String {
|
||||
switch status {
|
||||
case .connected: return ""
|
||||
case .connecting: return "Connecting..."
|
||||
case .reconnecting: return "Reconnecting..."
|
||||
case .disconnected: return "Disconnected"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import SwiftUI
|
||||
|
||||
struct OnlineDotOverlay: View {
|
||||
var size: CGFloat = 12
|
||||
|
||||
var body: some View {
|
||||
Circle()
|
||||
.fill(.green)
|
||||
.frame(width: size, height: size)
|
||||
.overlay(
|
||||
Circle()
|
||||
.stroke(.white, lineWidth: 2)
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user