diff --git a/Yattee/Views/Components/SourceListRow.swift b/Yattee/Views/Components/SourceListRow.swift index bbeb67a3..ac68e7fe 100644 --- a/Yattee/Views/Components/SourceListRow.swift +++ b/Yattee/Views/Components/SourceListRow.swift @@ -17,13 +17,25 @@ struct SourceListRow: View { @ViewBuilder let content: () -> Content /// Horizontal padding for row content. + #if os(macOS) + private let horizontalPadding: CGFloat = 12 + #else private let horizontalPadding: CGFloat = 16 + #endif /// Vertical padding for row content. + #if os(macOS) + private let verticalPadding: CGFloat = 8 + #else private let verticalPadding: CGFloat = 12 + #endif /// Width of the icon column. + #if os(macOS) + private let iconWidth: CGFloat = 24 + #else private let iconWidth: CGFloat = 32 + #endif /// Spacing between icon and text. private let iconTextSpacing: CGFloat = 12 diff --git a/Yattee/Views/MediaBrowser/MediaSourcesView.swift b/Yattee/Views/MediaBrowser/MediaSourcesView.swift index 410007d5..e2977874 100644 --- a/Yattee/Views/MediaBrowser/MediaSourcesView.swift +++ b/Yattee/Views/MediaBrowser/MediaSourcesView.swift @@ -170,6 +170,16 @@ struct MediaSourcesView: View { @ViewBuilder private func sectionHeader(_ title: String) -> some View { + #if os(macOS) + Text(title) + .font(.subheadline) + .textCase(.uppercase) + .foregroundStyle(.secondary) + .frame(maxWidth: .infinity, alignment: .leading) + .padding(.horizontal, 16) + .padding(.top, 12) + .padding(.bottom, 4) + #else Text(title) .fontWeight(.semibold) .foregroundStyle(.secondary) @@ -177,6 +187,7 @@ struct MediaSourcesView: View { .padding(.horizontal, listStyle == .inset ? 32 : 16) .padding(.top, 16) .padding(.bottom, 8) + #endif } private var sourcesList: some View { @@ -333,6 +344,16 @@ struct MediaSourcesView: View { @ViewBuilder private func sectionCard(@ViewBuilder content: () -> Content) -> some View { + #if os(macOS) + VStack(spacing: 0) { + Divider() + LazyVStack(spacing: 0) { + content() + } + Divider() + } + .padding(.bottom, 12) + #else if listStyle == .inset { LazyVStack(spacing: 0) { content() @@ -347,6 +368,7 @@ struct MediaSourcesView: View { } .padding(.bottom, 16) } + #endif } @ViewBuilder @@ -364,7 +386,11 @@ struct MediaSourcesView: View { NavigationLink(value: NavigationDestination.instanceBrowse(instance)) { instanceRow(instance) } + #if os(macOS) + .buttonStyle(.plain) + #else .foregroundStyle(.primary) + #endif } #if os(tvOS) .modifier(FirstRowFocusModifier(isFirst: isFirst, focus: $firstSourceFocused)) @@ -416,12 +442,20 @@ struct MediaSourcesView: View { } label: { mediaSourceRow(source, needsPassword: true) } + #if os(macOS) + .buttonStyle(.plain) + #else .foregroundStyle(.primary) + #endif } else { NavigationLink(value: NavigationDestination.mediaBrowser(source, path: "/")) { mediaSourceRow(source, needsPassword: false) } + #if os(macOS) + .buttonStyle(.plain) + #else .foregroundStyle(.primary) + #endif } } #if os(tvOS) @@ -460,15 +494,24 @@ struct MediaSourcesView: View { #else let rowSpacing: CGFloat = 12 #endif + #if os(macOS) + let iconFont: Font = .title3 + let iconFrameWidth: CGFloat = 24 + let titleFont: Font = .body + #else + let iconFont: Font = .title2 + let iconFrameWidth: CGFloat = 32 + let titleFont: Font = .headline + #endif return HStack(spacing: rowSpacing) { Image(systemName: instance.type.systemImage) - .font(.title2) + .font(iconFont) .foregroundStyle(.tint) - .frame(width: 32) + .frame(width: iconFrameWidth) VStack(alignment: .leading, spacing: 2) { Text(instance.displayName) - .font(.headline) + .font(titleFont) .foregroundStyle(.primary) Text("\(instance.type.displayName) - \(instance.url.host ?? instance.url.absoluteString)") @@ -478,10 +521,13 @@ struct MediaSourcesView: View { Spacer() + #if !os(macOS) Image(systemName: "chevron.right") .font(.caption) .foregroundStyle(.secondary) + #endif } + .contentShape(Rectangle()) } private func mediaSourceRow(_ source: MediaSource, needsPassword: Bool) -> some View { @@ -490,15 +536,24 @@ struct MediaSourcesView: View { #else let rowSpacing: CGFloat = 12 #endif + #if os(macOS) + let iconFont: Font = .title3 + let iconFrameWidth: CGFloat = 24 + let titleFont: Font = .body + #else + let iconFont: Font = .title2 + let iconFrameWidth: CGFloat = 32 + let titleFont: Font = .headline + #endif return HStack(spacing: rowSpacing) { Image(systemName: source.type.systemImage) - .font(.title2) + .font(iconFont) .foregroundStyle(.tint) - .frame(width: 32) + .frame(width: iconFrameWidth) VStack(alignment: .leading, spacing: 2) { Text(source.name) - .font(.headline) + .font(titleFont) .foregroundStyle(.primary) Text("\(source.type.displayName) - \(source.urlDisplayString)") @@ -514,10 +569,13 @@ struct MediaSourcesView: View { Spacer() + #if !os(macOS) Image(systemName: "chevron.right") .font(.caption) .foregroundStyle(.secondary) + #endif } + .contentShape(Rectangle()) } } diff --git a/Yattee/Views/Settings/SourcesListView.swift b/Yattee/Views/Settings/SourcesListView.swift index 65d07c93..2e5a3e1b 100644 --- a/Yattee/Views/Settings/SourcesListView.swift +++ b/Yattee/Views/Settings/SourcesListView.swift @@ -174,6 +174,16 @@ struct SourcesListView: View { @ViewBuilder private func sectionHeader(_ title: String) -> some View { + #if os(macOS) + Text(title) + .font(.subheadline) + .textCase(.uppercase) + .foregroundStyle(.secondary) + .frame(maxWidth: .infinity, alignment: .leading) + .padding(.horizontal, 16) + .padding(.top, 12) + .padding(.bottom, 4) + #else Text(title) .fontWeight(.semibold) .foregroundStyle(.secondary) @@ -181,12 +191,23 @@ struct SourcesListView: View { .padding(.horizontal, listStyle == .inset ? 32 : 16) .padding(.top, 16) .padding(.bottom, 8) + #endif } // MARK: - Section Card @ViewBuilder private func sectionCard(@ViewBuilder content: () -> Content) -> some View { + #if os(macOS) + VStack(spacing: 0) { + Divider() + LazyVStack(spacing: 0) { + content() + } + Divider() + } + .padding(.bottom, 12) + #else if listStyle == .inset { LazyVStack(spacing: 0) { content() @@ -205,6 +226,7 @@ struct SourcesListView: View { } .padding(.bottom, 16) } + #endif } // MARK: - Remote Servers Section @@ -244,7 +266,11 @@ struct SourcesListView: View { } label: { instanceRow(instance) } + #if os(macOS) + .buttonStyle(.plain) + #else .foregroundStyle(.primary) + #endif } .swipeActions { SwipeAction(symbolImage: "pencil", tint: .white, background: .orange) { reset in @@ -280,16 +306,25 @@ struct SourcesListView: View { #else let rowSpacing: CGFloat = 12 #endif + #if os(macOS) + let iconFont: Font = .title3 + let iconFrameWidth: CGFloat = 24 + let titleFont: Font = .body + #else + let iconFont: Font = .title2 + let iconFrameWidth: CGFloat = 32 + let titleFont: Font = .headline + #endif return HStack(spacing: rowSpacing) { Image(systemName: instance.type.systemImage) - .font(.title2) + .font(iconFont) .foregroundStyle(.tint) - .frame(width: 32) + .frame(width: iconFrameWidth) VStack(alignment: .leading, spacing: 2) { HStack { Text(instance.displayName) - .font(.headline) + .font(titleFont) .foregroundStyle(.primary) if !instance.isEnabled { @@ -306,10 +341,13 @@ struct SourcesListView: View { Spacer() + #if !os(macOS) Image(systemName: "chevron.right") .font(.caption) .foregroundStyle(.tertiary) + #endif } + .contentShape(Rectangle()) } @ViewBuilder @@ -380,7 +418,11 @@ struct SourcesListView: View { } label: { mediaSourceRow(source, needsPassword: needsPassword) } + #if os(macOS) + .buttonStyle(.plain) + #else .foregroundStyle(.primary) + #endif } .swipeActions { SwipeAction(symbolImage: "pencil", tint: .white, background: .orange) { reset in @@ -416,16 +458,25 @@ struct SourcesListView: View { #else let rowSpacing: CGFloat = 12 #endif + #if os(macOS) + let iconFont: Font = .title3 + let iconFrameWidth: CGFloat = 24 + let titleFont: Font = .body + #else + let iconFont: Font = .title2 + let iconFrameWidth: CGFloat = 32 + let titleFont: Font = .headline + #endif return HStack(spacing: rowSpacing) { Image(systemName: source.type.systemImage) - .font(.title2) + .font(iconFont) .foregroundStyle(.tint) - .frame(width: 32) + .frame(width: iconFrameWidth) VStack(alignment: .leading, spacing: 2) { HStack { Text(source.name) - .font(.headline) + .font(titleFont) .foregroundStyle(.primary) if !source.isEnabled { @@ -446,10 +497,13 @@ struct SourcesListView: View { Spacer() + #if !os(macOS) Image(systemName: "chevron.right") .font(.caption) .foregroundStyle(.tertiary) + #endif } + .contentShape(Rectangle()) } // MARK: - Disabled Badge