Spaces:
Paused
Paused
| import SwiftUI | |
| struct TalkOrbOverlay: View { | |
| (NodeAppModel.self) private var appModel | |
| private var pulse: Bool = false | |
| var body: some View { | |
| let seam = self.appModel.seamColor | |
| let status = self.appModel.talkMode.statusText.trimmingCharacters(in: .whitespacesAndNewlines) | |
| VStack(spacing: 14) { | |
| ZStack { | |
| Circle() | |
| .stroke(seam.opacity(0.26), lineWidth: 2) | |
| .frame(width: 320, height: 320) | |
| .scaleEffect(self.pulse ? 1.15 : 0.96) | |
| .opacity(self.pulse ? 0.0 : 1.0) | |
| .animation(.easeOut(duration: 1.3).repeatForever(autoreverses: false), value: self.pulse) | |
| Circle() | |
| .stroke(seam.opacity(0.18), lineWidth: 2) | |
| .frame(width: 320, height: 320) | |
| .scaleEffect(self.pulse ? 1.45 : 1.02) | |
| .opacity(self.pulse ? 0.0 : 0.9) | |
| .animation(.easeOut(duration: 1.9).repeatForever(autoreverses: false).delay(0.2), value: self.pulse) | |
| Circle() | |
| .fill( | |
| RadialGradient( | |
| colors: [ | |
| seam.opacity(0.95), | |
| seam.opacity(0.40), | |
| Color.black.opacity(0.55), | |
| ], | |
| center: .center, | |
| startRadius: 1, | |
| endRadius: 112)) | |
| .frame(width: 190, height: 190) | |
| .overlay( | |
| Circle() | |
| .stroke(seam.opacity(0.35), lineWidth: 1)) | |
| .shadow(color: seam.opacity(0.32), radius: 26, x: 0, y: 0) | |
| .shadow(color: Color.black.opacity(0.50), radius: 22, x: 0, y: 10) | |
| } | |
| .contentShape(Circle()) | |
| .onTapGesture { | |
| self.appModel.talkMode.userTappedOrb() | |
| } | |
| if !status.isEmpty, status != "Off" { | |
| Text(status) | |
| .font(.system(.footnote, design: .rounded).weight(.semibold)) | |
| .foregroundStyle(Color.white.opacity(0.92)) | |
| .padding(.horizontal, 12) | |
| .padding(.vertical, 8) | |
| .background( | |
| Capsule() | |
| .fill(Color.black.opacity(0.40)) | |
| .overlay( | |
| Capsule().stroke(seam.opacity(0.22), lineWidth: 1))) | |
| } | |
| } | |
| .padding(28) | |
| .onAppear { | |
| self.pulse = true | |
| } | |
| .accessibilityElement(children: .combine) | |
| .accessibilityLabel("Talk Mode \(status)") | |
| } | |
| } | |