diff --git a/PlayNextWidget/PlayNextQueueWidget.swift b/PlayNextWidget/PlayNextQueueWidget.swift index 8f6359c4..9957fd76 100644 --- a/PlayNextWidget/PlayNextQueueWidget.swift +++ b/PlayNextWidget/PlayNextQueueWidget.swift @@ -321,6 +321,7 @@ struct PlayNextQueueWidget: Widget { } private struct PlayNextQueueWidgetView: View { + @Environment(\.dynamicTypeSize) private var dynamicTypeSize @Environment(\.widgetFamily) private var family let entry: QueueTimelineEntry @@ -328,15 +329,15 @@ private struct PlayNextQueueWidgetView: View { var body: some View { switch family { case .systemSmall: - listView(rowCount: 3) + listView(rowCount: dynamicTypeSize.isAccessibilitySize ? 2 : 3) case .systemMedium: - listView(rowCount: 3) + listView(rowCount: dynamicTypeSize.isAccessibilitySize ? 2 : 3) case .systemLarge: - listView(rowCount: 8) + listView(rowCount: dynamicTypeSize.isAccessibilitySize ? 4 : 8) case .accessoryRectangular: accessoryView default: - listView(rowCount: 3) + listView(rowCount: dynamicTypeSize.isAccessibilitySize ? 2 : 3) } } @@ -359,7 +360,7 @@ private struct PlayNextQueueWidgetView: View { ) return GeometryReader { proxy in - let headerHeight: CGFloat = 32 + let headerHeight: CGFloat = dynamicTypeSize.isAccessibilitySize ? 44 : 32 let rowHeight = items.isEmpty ? 0 : max((proxy.size.height - headerHeight) / CGFloat(items.count), 0) @@ -391,7 +392,8 @@ private struct PlayNextQueueWidgetView: View { Text(entry.playlistTitle) .font(.caption2) .foregroundStyle(Color.upNextAccent) - .lineLimit(1) + .lineLimit(dynamicTypeSize.isAccessibilitySize ? 2 : 1) + .fixedSize(horizontal: false, vertical: dynamicTypeSize.isAccessibilitySize) if let first = entry.snapshot.upcomingItems.first ?? entry.snapshot.currentItem { HStack(spacing: 6) { @@ -401,20 +403,23 @@ private struct PlayNextQueueWidgetView: View { Text(first.title) .font(.caption) .fontWeight(.semibold) - .lineLimit(1) + .lineLimit(dynamicTypeSize.isAccessibilitySize ? 2 : 1) + .fixedSize(horizontal: false, vertical: dynamicTypeSize.isAccessibilitySize) if let podcast = first.podcast, podcast.isEmpty == false { Text(podcast) .font(.caption2) .foregroundStyle(.secondary) - .lineLimit(1) + .lineLimit(dynamicTypeSize.isAccessibilitySize ? 2 : 1) + .fixedSize(horizontal: false, vertical: dynamicTypeSize.isAccessibilitySize) } } } } else { Text(entry.statusMessage ?? "Queue is empty") .font(.caption) - .lineLimit(1) + .lineLimit(dynamicTypeSize.isAccessibilitySize ? 2 : 1) + .fixedSize(horizontal: false, vertical: dynamicTypeSize.isAccessibilitySize) } } .widgetURL(widgetURL) @@ -429,7 +434,8 @@ private struct PlayNextQueueWidgetView: View { Text(entry.playlistTitle) .font(.caption) .fontWeight(.semibold) - .lineLimit(1) + .lineLimit(dynamicTypeSize.isAccessibilitySize ? 2 : 1) + .fixedSize(horizontal: false, vertical: dynamicTypeSize.isAccessibilitySize) .foregroundStyle(Color.upNextAccent) .widgetAccentable() Spacer(minLength: 0) @@ -437,7 +443,8 @@ private struct PlayNextQueueWidgetView: View { Text(progressText) .font(.caption2) .fontWeight(.medium) - .lineLimit(1) + .lineLimit(dynamicTypeSize.isAccessibilitySize ? 2 : 1) + .fixedSize(horizontal: false, vertical: dynamicTypeSize.isAccessibilitySize) } } .padding(.horizontal, 14) @@ -471,6 +478,7 @@ private struct PlayNextQueueWidgetView: View { } private struct QueueLine: View { + @Environment(\.dynamicTypeSize) private var dynamicTypeSize enum Style { case current case upNext @@ -498,7 +506,11 @@ private struct QueueLine: View { if let playURL { Button(intent: OpenURLIntent(playURL)) { Image(systemName: "play.circle.fill") - .font(.system(size: 18, weight: .semibold)) + .font( + dynamicTypeSize.isAccessibilitySize + ? .title3.weight(.semibold) + : .system(size: 18, weight: .semibold) + ) .foregroundStyle(Color.upNextAccent) .widgetAccentable() } @@ -557,14 +569,16 @@ private struct QueueLine: View { .font(.subheadline) .fontWeight(style == .current ? .semibold : .regular) .foregroundStyle(style == .current ? Color.upNextAccent : Color.primary) - .lineLimit(1) + .lineLimit(dynamicTypeSize.isAccessibilitySize ? 2 : 1) + .fixedSize(horizontal: false, vertical: dynamicTypeSize.isAccessibilitySize) .widgetAccentable(style == .current) if let supportingText = supportingText, supportingText.isEmpty == false { Text(supportingText) .font(.caption) .foregroundStyle(.secondary) - .lineLimit(1) + .lineLimit(dynamicTypeSize.isAccessibilitySize ? 2 : 1) + .fixedSize(horizontal: false, vertical: dynamicTypeSize.isAccessibilitySize) } } } diff --git a/Raul/Features/Library/Views/Bookmarks/BookmarkRowView.swift b/Raul/Features/Library/Views/Bookmarks/BookmarkRowView.swift index c8732d24..ef7709d2 100644 --- a/Raul/Features/Library/Views/Bookmarks/BookmarkRowView.swift +++ b/Raul/Features/Library/Views/Bookmarks/BookmarkRowView.swift @@ -11,6 +11,8 @@ import SwiftUI import ESADesignKit struct BookmarkRowView: View { + @Environment(\.dynamicTypeSize) private var dynamicTypeSize + let marker: Bookmark var isPlaying: Bool var clipDisabled: Bool @@ -34,11 +36,13 @@ struct BookmarkRowView: View { Text(episode?.displayPodcastTitle ?? episode?.title ?? "") .font(.caption) .foregroundStyle(.secondary) - .lineLimit(1) + .lineLimit(dynamicTypeSize.isAccessibilitySize ? 2 : 1) + .fixedSize(horizontal: false, vertical: dynamicTypeSize.isAccessibilitySize) Text(marker.title) .font(.headline) - .lineLimit(2) + .lineLimit(dynamicTypeSize.isAccessibilitySize ? 4 : 2) + .fixedSize(horizontal: false, vertical: dynamicTypeSize.isAccessibilitySize) if let start = marker.start { Text("at \(Duration.seconds(start).formatted(.units(width: .abbreviated)))") @@ -49,7 +53,7 @@ struct BookmarkRowView: View { Spacer(minLength: 0) if episode != nil { - HStack(spacing: 10) { + HStack(spacing: dynamicTypeSize.isAccessibilitySize ? 14 : 10) { Button(action: onPlayToggle) { Label(isPlaying ? "Pause" : "Play", systemImage: isPlaying ? "pause.fill" : "play.fill") } diff --git a/Raul/Features/Library/Views/Episodes/EpisodeRowView.swift b/Raul/Features/Library/Views/Episodes/EpisodeRowView.swift index 7cdd04d8..46e415c8 100644 --- a/Raul/Features/Library/Views/Episodes/EpisodeRowView.swift +++ b/Raul/Features/Library/Views/Episodes/EpisodeRowView.swift @@ -15,6 +15,7 @@ struct EpisodeRowView: View { @Environment(\.modelContext) private var modelContext @Environment(\.accessibilityReduceMotion) private var reduceMotion @Environment(\.accessibilityDifferentiateWithoutColor) private var differentiateWithoutColor + @Environment(\.dynamicTypeSize) private var dynamicTypeSize @Bindable var episode: Episode @State private var referenceAvailability = EpisodeReferenceAvailability() @@ -61,7 +62,8 @@ struct EpisodeRowView: View { Text(episodeTypeBadgeText) .font(.caption2.weight(.semibold)) .foregroundStyle(.primary) - .lineLimit(1) + .lineLimit(dynamicTypeSize.isAccessibilitySize ? 2 : 1) + .fixedSize(horizontal: false, vertical: dynamicTypeSize.isAccessibilitySize) .padding(.horizontal, 7) .padding(.vertical, 4) .background(.ultraThinMaterial, in: Capsule()) @@ -86,7 +88,8 @@ struct EpisodeRowView: View { Text(podcastTitle) .font(.caption) .foregroundStyle(.secondary) - .lineLimit(2) + .lineLimit(dynamicTypeSize.isAccessibilitySize ? 3 : 2) + .fixedSize(horizontal: false, vertical: dynamicTypeSize.isAccessibilitySize) Spacer(minLength: 8) Text(publishText) .font(.caption) @@ -95,7 +98,8 @@ struct EpisodeRowView: View { Text(episode.title) .font(.headline) - .lineLimit(4) + .lineLimit(dynamicTypeSize.isAccessibilitySize ? 6 : 4) + .fixedSize(horizontal: false, vertical: dynamicTypeSize.isAccessibilitySize) .foregroundStyle(.primary) Spacer(minLength: 0) diff --git a/Raul/Features/Library/Views/Podcasts/PodcastDetailView.swift b/Raul/Features/Library/Views/Podcasts/PodcastDetailView.swift index 15596715..d2b023bb 100644 --- a/Raul/Features/Library/Views/Podcasts/PodcastDetailView.swift +++ b/Raul/Features/Library/Views/Podcasts/PodcastDetailView.swift @@ -54,6 +54,7 @@ struct PodcastDetailView: View { @Environment(\.modelContext) private var modelContext @Environment(\.deviceUIStyle) var style @Environment(\.openPodcastSettings) private var openSettings + @Environment(\.dynamicTypeSize) private var dynamicTypeSize @Query(filter: PodcastSettingsView.defaultSettingsFilter) private var defaultSettings: [PodcastSettings] @State private var showPodroll: Bool = false @@ -160,7 +161,8 @@ struct PodcastDetailView: View { ProgressView() Text(refreshProgressMessage ?? "Refreshing podcast") .font(.caption.weight(.semibold)) - .lineLimit(2) + .lineLimit(dynamicTypeSize.isAccessibilitySize ? 3 : 2) + .fixedSize(horizontal: false, vertical: dynamicTypeSize.isAccessibilitySize) Spacer() Text(refreshProgress, format: .percent.precision(.fractionLength(0))) .font(.caption.monospacedDigit().weight(.semibold)) @@ -246,7 +248,8 @@ struct PodcastDetailView: View { } Text(podcast.title) .font(.headline) - .lineLimit(2) + .lineLimit(dynamicTypeSize.isAccessibilitySize ? 4 : 2) + .fixedSize(horizontal: false, vertical: dynamicTypeSize.isAccessibilitySize) } Spacer(minLength: 8) diff --git a/Raul/Features/Library/Views/Podcasts/PodcastRowView.swift b/Raul/Features/Library/Views/Podcasts/PodcastRowView.swift index b1159b00..48fc33b4 100644 --- a/Raul/Features/Library/Views/Podcasts/PodcastRowView.swift +++ b/Raul/Features/Library/Views/Podcasts/PodcastRowView.swift @@ -9,6 +9,8 @@ import SwiftData import ESADesignKit struct PodcastRowView: View { + @Environment(\.dynamicTypeSize) private var dynamicTypeSize + let podcast: Podcast @ScaledMetric(relativeTo: .body) private var rowHeight: CGFloat = 140 @ScaledMetric(relativeTo: .body) private var artworkSize: CGFloat = 112 @@ -34,20 +36,23 @@ struct PodcastRowView: View { VStack(alignment: .leading, spacing: 8) { Text(podcast.title) .font(.headline) - .lineLimit(2) + .lineLimit(dynamicTypeSize.isAccessibilitySize ? 4 : 2) + .fixedSize(horizontal: false, vertical: dynamicTypeSize.isAccessibilitySize) if let author = podcast.author, author.isEmpty == false { Text(author) .font(.subheadline) .foregroundStyle(.secondary) - .lineLimit(1) + .lineLimit(dynamicTypeSize.isAccessibilitySize ? 2 : 1) + .fixedSize(horizontal: false, vertical: dynamicTypeSize.isAccessibilitySize) } if let desc = podcast.desc, desc.isEmpty == false { Text(desc) .font(.caption) .foregroundStyle(.secondary) - .lineLimit(3) + .lineLimit(dynamicTypeSize.isAccessibilitySize ? 5 : 3) + .fixedSize(horizontal: false, vertical: dynamicTypeSize.isAccessibilitySize) } if podcast.isSubscribed == false { diff --git a/Raul/Features/Search/Views/PodcastBrowseView.swift b/Raul/Features/Search/Views/PodcastBrowseView.swift index 29974fde..321ea589 100644 --- a/Raul/Features/Search/Views/PodcastBrowseView.swift +++ b/Raul/Features/Search/Views/PodcastBrowseView.swift @@ -433,6 +433,8 @@ private struct PodcastBrowseHeaderView: View { } private struct PodcastBrowseEpisodeRowView: View { + @Environment(\.dynamicTypeSize) private var dynamicTypeSize + let episode: PodcastEpisodeDraft let podcastFeed: PodcastFeed let queueAction: (Playlist.Position) async -> Void @@ -485,7 +487,8 @@ private struct PodcastBrowseEpisodeRowView: View { Text(episodeTypeBadgeText) .font(.caption2.weight(.semibold)) .foregroundStyle(.primary) - .lineLimit(1) + .lineLimit(dynamicTypeSize.isAccessibilitySize ? 2 : 1) + .fixedSize(horizontal: false, vertical: dynamicTypeSize.isAccessibilitySize) .padding(.horizontal, 7) .padding(.vertical, 4) .background(.ultraThinMaterial, in: Capsule()) @@ -501,7 +504,8 @@ private struct PodcastBrowseEpisodeRowView: View { Text(podcastFeed.title ?? "Untitled Podcast") .font(.caption) .foregroundStyle(.secondary) - .lineLimit(2) + .lineLimit(dynamicTypeSize.isAccessibilitySize ? 3 : 2) + .fixedSize(horizontal: false, vertical: dynamicTypeSize.isAccessibilitySize) Spacer(minLength: 8) Text(publishText) .font(.caption) @@ -510,7 +514,8 @@ private struct PodcastBrowseEpisodeRowView: View { Text(episode.title) .font(.headline) - .lineLimit(4) + .lineLimit(dynamicTypeSize.isAccessibilitySize ? 6 : 4) + .fixedSize(horizontal: false, vertical: dynamicTypeSize.isAccessibilitySize) .foregroundStyle(.primary) Spacer(minLength: 0) diff --git a/UpNextWatch/WatchPlayerView.swift b/UpNextWatch/WatchPlayerView.swift index 17bc3408..11a3ce8d 100644 --- a/UpNextWatch/WatchPlayerView.swift +++ b/UpNextWatch/WatchPlayerView.swift @@ -413,6 +413,8 @@ struct WatchProgressBar: View { } private struct WatchPrimaryControlButton: View { + @Environment(\.dynamicTypeSize) private var dynamicTypeSize + let systemName: String let accessibilityLabelText: String let accessibilityHintText: String? @@ -434,7 +436,10 @@ private struct WatchPrimaryControlButton: View { Button(action: action) { Image(systemName: systemName) .font(.headline.weight(.bold)) - .frame(width: 48, height: 48) + .frame( + width: dynamicTypeSize.isAccessibilitySize ? 54 : 48, + height: dynamicTypeSize.isAccessibilitySize ? 54 : 48 + ) .background( Circle() .fill( @@ -454,6 +459,7 @@ private struct WatchPrimaryControlButton: View { } private struct WatchSmallControlButton: View { + @Environment(\.dynamicTypeSize) private var dynamicTypeSize let systemName: String let accessibilityLabelText: String let accessibilityHintText: String? @@ -476,7 +482,7 @@ private struct WatchSmallControlButton: View { Image(systemName: systemName) .font(.caption.weight(.semibold)) .frame(maxWidth: .infinity) - .frame(height: 34) + .frame(height: dynamicTypeSize.isAccessibilitySize ? 44 : 34) .background( RoundedRectangle(cornerRadius: 14, style: .continuous) .fill(Color.upNextAccent.opacity(0.18)) @@ -490,6 +496,8 @@ private struct WatchSmallControlButton: View { } struct WatchCapsuleButtonStyle: ButtonStyle { + @Environment(\.dynamicTypeSize) private var dynamicTypeSize + let accent: Color func makeBody(configuration: Configuration) -> some View { @@ -497,7 +505,7 @@ struct WatchCapsuleButtonStyle: ButtonStyle { .font(.caption.weight(.semibold)) .foregroundStyle(.white) .frame(maxWidth: .infinity) - .frame(height: 34) + .frame(height: dynamicTypeSize.isAccessibilitySize ? 44 : 34) .background( Capsule() .fill(accent.opacity(configuration.isPressed ? 0.4 : 0.28)) diff --git a/UpNextWatch/WatchRootView.swift b/UpNextWatch/WatchRootView.swift index 743eb029..75862e3c 100644 --- a/UpNextWatch/WatchRootView.swift +++ b/UpNextWatch/WatchRootView.swift @@ -321,6 +321,7 @@ private struct WatchRemotePlaylistControls: View { } private struct WatchNowPlayingHero: View { + @Environment(\.dynamicTypeSize) private var dynamicTypeSize @EnvironmentObject private var playback: WatchPlaybackController let episode: WatchSyncEpisode @@ -343,14 +344,16 @@ private struct WatchNowPlayingHero: View { Text(episode.title) .font(.caption.weight(.semibold)) .foregroundStyle(.white) - .lineLimit(2) + .lineLimit(dynamicTypeSize.isAccessibilitySize ? 4 : 2) + .fixedSize(horizontal: false, vertical: dynamicTypeSize.isAccessibilitySize) .frame(maxWidth: .infinity, alignment: .leading) if let chapterTitle = playback.currentChapter?.title { Text(chapterTitle) .font(.caption2) .foregroundStyle(.white.opacity(0.78)) - .lineLimit(1) + .lineLimit(dynamicTypeSize.isAccessibilitySize ? 2 : 1) + .fixedSize(horizontal: false, vertical: dynamicTypeSize.isAccessibilitySize) } } }