diff --git a/DynamicIsland/ContentView.swift b/DynamicIsland/ContentView.swift index 9995446..ac5d761 100644 --- a/DynamicIsland/ContentView.swift +++ b/DynamicIsland/ContentView.swift @@ -1043,16 +1043,11 @@ struct ContentView: View { .font(.system(size: badgeSize * 0.5, weight: .semibold)) .foregroundStyle(capsLockTintMode.color) case .extensionPayload(let payload): - ExtensionCompositeIconView( - leading: payload.descriptor.leadingIcon, - badge: payload.descriptor.badgeIcon, + ExtensionBadgeIconView( + descriptor: payload.descriptor.leadingIcon, accent: payload.descriptor.accentColor.swiftUIColor, size: badgeSize ) - .background( - Circle() - .fill(Color.black.opacity(0.85)) - ) } } .frame(width: badgeSize, height: badgeSize) @@ -1066,8 +1061,6 @@ struct ContentView: View { private func badgeDisplaySize(for secondary: MusicSecondaryLiveActivity?, baseSize: CGFloat) -> CGFloat { guard let secondary else { return baseSize } switch secondary { - case .extensionPayload: - return max(11, baseSize * 0.86) default: return baseSize } @@ -1076,8 +1069,6 @@ struct ContentView: View { private func badgeOverlayOffset(for secondary: MusicSecondaryLiveActivity?, badgeSize: CGFloat) -> CGSize { guard let secondary else { return CGSize(width: badgeSize * 0.2, height: badgeSize * 0.25) } switch secondary { - case .extensionPayload: - return CGSize(width: badgeSize * 0.14, height: badgeSize * 0.12) default: return CGSize(width: badgeSize * 0.2, height: badgeSize * 0.25) } @@ -1189,10 +1180,10 @@ struct ContentView: View { return nil } - guard standardMediaControlsActive else { + guard closedMusicContentEnabled else { ExtensionRoutingDiagnostics.shared.logSuppression( .music, - reason: "standard media controls disabled", + reason: "music content disabled", pendingCount: candidates.count ) return nil diff --git a/DynamicIsland/components/Extensions/ExtensionRenderingHelpers.swift b/DynamicIsland/components/Extensions/ExtensionRenderingHelpers.swift index af5dcd8..0e5c5f1 100644 --- a/DynamicIsland/components/Extensions/ExtensionRenderingHelpers.swift +++ b/DynamicIsland/components/Extensions/ExtensionRenderingHelpers.swift @@ -202,6 +202,63 @@ struct ExtensionCompositeIconView: View { } } +struct ExtensionBadgeIconView: View { + let descriptor: AtollIconDescriptor + let accent: Color + let size: CGFloat + + private var symbolSize: CGFloat { size * 0.5 } + private var imageSize: CGFloat { size * 0.62 } + private var imageCornerRadius: CGFloat { size * 0.18 } + + var body: some View { + Group { + switch descriptor { + case let .symbol(name, _, weight): + Image(systemName: name) + .font(.system(size: symbolSize, weight: weight.swiftUI)) + .foregroundStyle(accent) + case let .image(data, _, _): + if let image = NSImage(data: data) { + Image(nsImage: image) + .resizable() + .aspectRatio(contentMode: .fill) + .frame(width: imageSize, height: imageSize) + .clipShape(RoundedRectangle(cornerRadius: imageCornerRadius, style: .continuous)) + } else { + fallbackSymbol + } + case let .appIcon(bundleIdentifier, _, _): + if let icon = AppIconAsNSImage(for: bundleIdentifier) { + Image(nsImage: icon) + .resizable() + .aspectRatio(contentMode: .fill) + .frame(width: imageSize, height: imageSize) + .clipShape(RoundedRectangle(cornerRadius: imageCornerRadius, style: .continuous)) + } else { + fallbackSymbol + } + case let .lottie(animationData, _): + ExtensionLottieView(data: animationData, size: CGSize(width: imageSize, height: imageSize)) + case .none: + fallbackSymbol + } + } + .frame(width: size, height: size) + } + + private var fallbackSymbol: some View { + Image(systemName: "app.dashed") + .font(.system(size: symbolSize, weight: .medium)) + .foregroundStyle(accent) + .frame(width: imageSize, height: imageSize) + .background( + RoundedRectangle(cornerRadius: imageCornerRadius, style: .continuous) + .fill(accent.opacity(0.15)) + ) + } +} + // MARK: - Lottie Rendering struct ExtensionLottieView: View {