Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>

This commit is contained in:
Matt Bruce 2026-02-02 22:58:12 -06:00
parent 9247c36721
commit 41578f0941
3 changed files with 107 additions and 70 deletions

View File

@ -24,6 +24,10 @@ struct AlarmView: View {
ZStack {
AppSurface.primary.ignoresSafeArea()
GeometryReader { geometry in
let isLandscape = geometry.size.width > geometry.size.height
let maxWidth = isLandscape ? Design.Size.maxContentWidthLandscape : Design.Size.maxContentWidthPortrait
Group {
if viewModel.alarms.isEmpty {
VStack(spacing: Design.Spacing.large) {
@ -39,8 +43,6 @@ struct AlarmView: View {
showAddAlarm = true
}
}
.frame(maxWidth: Design.Size.maxContentWidthPortrait)
.frame(maxWidth: .infinity, alignment: .center)
} else {
List {
if !isKeepAwakeEnabled {
@ -75,10 +77,11 @@ struct AlarmView: View {
.listStyle(.plain)
.scrollContentBackground(.hidden)
.background(AppSurface.primary.ignoresSafeArea())
.frame(maxWidth: Design.Size.maxContentWidthPortrait)
.frame(maxWidth: .infinity, alignment: .center)
}
}
.frame(maxWidth: maxWidth)
.frame(maxWidth: .infinity, alignment: .center)
}
}
.navigationTitle(isPad ? "" : "Alarms")
.navigationBarTitleDisplayMode(.inline)

View File

@ -37,6 +37,33 @@ struct NoiseView: View {
let isLandscape = geometry.size.width > geometry.size.height
let maxWidth = isLandscape ? Design.Size.maxContentWidthLandscape : Design.Size.maxContentWidthPortrait
VStack(spacing: 0) {
// Custom Search Bar - Constrained to maxWidth
HStack {
HStack(spacing: Design.Spacing.small) {
Image(systemName: "magnifyingglass")
.foregroundColor(AppTextColors.secondary)
TextField("Search sounds", text: $searchText)
.textFieldStyle(.plain)
.foregroundColor(AppTextColors.primary)
if !searchText.isEmpty {
Button(action: { searchText = "" }) {
Image(systemName: "xmark.circle.fill")
.foregroundColor(AppTextColors.tertiary)
}
}
}
.padding(Design.Spacing.small)
.background(AppSurface.overlay)
.cornerRadius(Design.CornerRadius.medium)
}
.padding(.horizontal, Design.Spacing.large)
.padding(.top, Design.Spacing.medium)
.padding(.bottom, Design.Spacing.small)
.frame(maxWidth: maxWidth)
Group {
if isLandscape {
// Landscape layout: Player on left, sounds on right
@ -47,15 +74,13 @@ struct NoiseView: View {
}
}
.frame(maxWidth: maxWidth)
}
.frame(maxWidth: .infinity, alignment: .center)
}
}
.navigationTitle("Noise")
.navigationBarTitleDisplayMode(.inline)
.animation(.easeInOut(duration: 0.3), value: selectedSound)
.searchable(
text: $searchText,
placement: .navigationBarDrawer(displayMode: .automatic),
prompt: "Search sounds"
)
}
// MARK: - Computed Properties
@ -82,6 +107,7 @@ struct NoiseView: View {
if selectedSound != nil {
soundControlView
.centered()
.padding(.bottom, Design.Spacing.medium)
} else {
// Placeholder when no sound selected - Enhanced for CRO
VStack(spacing: Design.Spacing.medium) {
@ -108,27 +134,31 @@ struct NoiseView: View {
}
}
.frame(maxWidth: .infinity)
.padding(.vertical, Design.Spacing.xLarge)
.padding(.vertical, Design.Spacing.large)
.background(AppSurface.overlay, in: RoundedRectangle(cornerRadius: Design.CornerRadius.appLarge))
.overlay(
RoundedRectangle(cornerRadius: Design.CornerRadius.appLarge)
.stroke(AppBorder.subtle, lineWidth: Design.LineWidth.thin)
)
.padding(.bottom, Design.Spacing.medium)
}
}
.contentPadding(horizontal: Design.Spacing.large)
.padding(.top, Design.Spacing.large)
.padding(.horizontal, Design.Spacing.large)
.padding(.top, Design.Spacing.small)
.background(AppSurface.primary)
// Scrollable sound selection
ScrollView {
List {
SoundCategoryView(
sounds: viewModel.availableSounds,
selectedSound: $selectedSound,
searchText: $searchText
)
.contentPadding(horizontal: Design.Spacing.large, vertical: Design.Spacing.large)
.listRowInsets(EdgeInsets(top: 0, leading: Design.Spacing.large, bottom: Design.Spacing.large, trailing: Design.Spacing.large))
.listRowBackground(Color.clear)
.listRowSeparator(.hidden)
}
.listStyle(.plain)
.scrollContentBackground(.hidden)
}
}

View File

@ -58,6 +58,8 @@ struct OnboardingView: View {
.padding(.horizontal, Design.Spacing.xLarge)
.padding(.bottom, Design.Spacing.xxLarge)
}
.frame(maxWidth: Design.Size.maxContentWidthPortrait)
.frame(maxWidth: .infinity, alignment: .center)
}
}
@ -113,9 +115,9 @@ struct OnboardingView: View {
Text(text)
.typography(.body)
.foregroundStyle(AppTextColors.secondary)
Spacer()
}
.frame(maxWidth: 320, alignment: .leading) // Constrain width and align content to leading
.frame(maxWidth: .infinity, alignment: .center) // Center the constrained box in the parent
.padding(.horizontal, Design.Spacing.xxLarge)
}
@ -219,9 +221,9 @@ struct OnboardingView: View {
Text(text)
.typography(.body)
.foregroundStyle(AppTextColors.secondary)
Spacer()
}
.frame(maxWidth: 320, alignment: .leading) // Constrain width and align content to leading
.frame(maxWidth: .infinity, alignment: .center) // Center the constrained box in the parent
.padding(.horizontal, Design.Spacing.xxLarge)
}
@ -311,6 +313,8 @@ struct OnboardingView: View {
.typography(.callout)
.foregroundStyle(AppTextColors.secondary)
}
.frame(maxWidth: 320, alignment: .leading) // Constrain width and align content to leading
.frame(maxWidth: .infinity, alignment: .center) // Center the constrained box in the parent
.padding(.horizontal, Design.Spacing.xxLarge)
}