Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 8 additions & 10 deletions Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -349,14 +349,13 @@
}
}
},
"Customize row highlight visibility" : {
"comment" : "A description of the guide opacity slider.",
"isCommentAutoGenerated" : true,
"Customize the row highlight in text-imported projects" : {
"comment" : "A description of the text row highlight opacity slider.",
"localizations" : {
"de" : {
"stringUnit" : {
"state" : "machine_translated",
"value" : "Sichtbarkeit der Reihenmarkierung anpassen"
"state" : "translated",
"value" : "Reihenmarkierung in importierten Textprojekten anpassen"
}
}
}
Expand Down Expand Up @@ -513,14 +512,13 @@
}
}
},
"Guide opacity" : {
"comment" : "A heading for the opacity of the guide on the reading mode settings page.",
"isCommentAutoGenerated" : true,
"Text row highlight opacity" : {
"comment" : "A heading for the opacity of the row highlight for text-imported projects on the Reading Mode settings page.",
"localizations" : {
"de" : {
"stringUnit" : {
"state" : "machine_translated",
"value" : "Deckkraft der Reihenmarkierung"
"state" : "translated",
"value" : "Deckkraft der Text-Reihenmarkierung"
}
}
}
Expand Down
152 changes: 99 additions & 53 deletions LoopLine/Views/PDFReadingView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,14 @@ import SwiftUI

struct PDFReadingView: View {
@Environment(\.modelContext) private var modelContext
@Query private var settings: [AppSettings]
@Bindable var project: Project
@State private var viewModel = PDFReadingViewModel()

private var usesLargeControls: Bool {
settings.first?.largeControls ?? true
}

var body: some View {
@Bindable var viewModel = viewModel

Expand Down Expand Up @@ -87,66 +92,35 @@ struct PDFReadingView: View {
}

private var trackingControls: some View {
HStack(spacing: 16) {
Menu {
ForEach(ReadingTrackingMetric.allCases) { metric in
Button(metric.title) {
viewModel.selectedMetric = metric
Group {
if usesLargeControls {
VStack(alignment: .leading, spacing: 12) {
metricPicker

HStack(spacing: 20) {
decreaseButton

metricValue
.frame(minWidth: 90)

increaseButton
}
.frame(maxWidth: .infinity)
}
} label: {
HStack(spacing: 6) {
Text(viewModel.selectedMetric.title)
.font(.subheadline.weight(.semibold))
.lineLimit(1)
} else {
HStack(spacing: 16) {
metricPicker

Image(systemName: "chevron.down")
.font(.caption.weight(.bold))
}
.foregroundStyle(LoopLineTheme.readingPrimaryText)
.frame(minWidth: 92, alignment: .leading)
.padding(.horizontal, 12)
.frame(height: 48)
.background(LoopLineTheme.readingControlFill, in: RoundedRectangle(cornerRadius: LoopLineTheme.compactCornerRadius, style: .continuous))
}
.accessibilityLabel("Tracking metric")
.accessibilityValue(viewModel.selectedMetric.title)
Spacer(minLength: 0)

Spacer(minLength: 0)
decreaseButton

Button {
viewModel.decrementSelectedMetric(for: project, in: modelContext)
} label: {
Image(systemName: "minus")
}
.buttonStyle(LoopLineIconButtonStyle(
size: 48,
foregroundColor: LoopLineTheme.readingPrimaryText,
backgroundColor: LoopLineTheme.readingControlFill
))
.disabled(!viewModel.canDecreaseSelectedMetric(for: project))
.opacity(viewModel.canDecreaseSelectedMetric(for: project) ? 1 : 0.38)
.accessibilityLabel("Decrease \(viewModel.selectedMetric.title)")

Text(String(viewModel.selectedMetricValue(for: project)))
.font(.system(size: 34, weight: .bold).monospacedDigit())
.foregroundStyle(LoopLineTheme.readingPrimaryText)
.lineLimit(1)
.minimumScaleFactor(0.65)
.frame(minWidth: 70)
.accessibilityLabel("\(viewModel.selectedMetric.title) \(viewModel.selectedMetricValue(for: project))")
metricValue
.frame(minWidth: 70)

Button {
viewModel.incrementSelectedMetric(for: project, in: modelContext)
} label: {
Image(systemName: "plus")
increaseButton
}
}
.buttonStyle(LoopLineIconButtonStyle(
size: 48,
foregroundColor: LoopLineTheme.primaryActionForeground,
backgroundColor: LoopLineTheme.primaryActionBackground
))
.accessibilityLabel("Increase \(viewModel.selectedMetric.title)")
}
.padding(.horizontal, 12)
.padding(.vertical, 10)
Expand All @@ -156,6 +130,78 @@ struct PDFReadingView: View {
.stroke(LoopLineTheme.readingStroke, lineWidth: 1)
}
}

private var metricPicker: some View {
Menu {
ForEach(ReadingTrackingMetric.allCases) { metric in
Button(metric.title) {
viewModel.selectedMetric = metric
}
}
} label: {
HStack(spacing: 6) {
Text(viewModel.selectedMetric.title)
.font(.subheadline.weight(.semibold))
.lineLimit(1)

Image(systemName: "chevron.down")
.font(.caption.weight(.bold))
}
.foregroundStyle(LoopLineTheme.readingPrimaryText)
.frame(minWidth: 92, alignment: .leading)
.padding(.horizontal, 12)
.frame(height: usesLargeControls ? 56 : 48)
.background(LoopLineTheme.readingControlFill, in: RoundedRectangle(cornerRadius: LoopLineTheme.compactCornerRadius, style: .continuous))
}
.accessibilityLabel("Tracking metric")
.accessibilityValue(viewModel.selectedMetric.title)
}

private var decreaseButton: some View {
Button {
viewModel.decrementSelectedMetric(for: project, in: modelContext)
} label: {
Image(systemName: "minus")
}
.buttonStyle(LoopLineIconButtonStyle(
size: usesLargeControls ? 70 : 48,
foregroundColor: LoopLineTheme.readingPrimaryText,
backgroundColor: LoopLineTheme.readingControlFill
))
.disabled(!viewModel.canDecreaseSelectedMetric(for: project))
.opacity(viewModel.canDecreaseSelectedMetric(for: project) ? 1 : 0.38)
.accessibilityLabel("Decrease \(viewModel.selectedMetric.title)")
}

private var metricValue: some View {
Text(String(viewModel.selectedMetricValue(for: project)))
.font(metricValueFont)
.foregroundStyle(LoopLineTheme.readingPrimaryText)
.lineLimit(1)
.minimumScaleFactor(0.65)
.accessibilityLabel("\(viewModel.selectedMetric.title) \(viewModel.selectedMetricValue(for: project))")
}

private var increaseButton: some View {
Button {
viewModel.incrementSelectedMetric(for: project, in: modelContext)
} label: {
Image(systemName: "plus")
}
.buttonStyle(LoopLineIconButtonStyle(
size: usesLargeControls ? 70 : 48,
foregroundColor: LoopLineTheme.primaryActionForeground,
backgroundColor: LoopLineTheme.primaryActionBackground
))
.accessibilityLabel("Increase \(viewModel.selectedMetric.title)")
}

private var metricValueFont: Font {
if usesLargeControls {
return Font.title.weight(.bold).monospacedDigit()
}
return Font.system(size: 34, weight: .bold).monospacedDigit()
}
}

private final class PDFMarkupPDFView: PDFView {
Expand Down
121 changes: 79 additions & 42 deletions LoopLine/Views/ReadingModeView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -361,59 +361,96 @@ private struct CounterControlPanel: View {

private var buttonSize: CGFloat {
if isPrimary {
return usesLargeControls ? 76 : 62
return usesLargeControls ? 88 : 62
}
return usesLargeControls ? 58 : 48
return usesLargeControls ? 70 : 48
}

var body: some View {
HStack(spacing: 16) {
Text(label)
.font(.caption.weight(.bold))
.foregroundStyle(secondaryText)
.frame(width: 72, alignment: .leading)

Button(action: decreaseAction) {
Image(systemName: "minus")
}
.buttonStyle(LoopLineIconButtonStyle(
size: buttonSize,
foregroundColor: primaryText,
backgroundColor: secondaryButtonBackground
))
.disabled(!canDecrease)
.opacity(canDecrease ? 1 : 0.38)

VStack(spacing: 1) {
Text(value)
.font((isPrimary ? Font.system(size: 48, weight: .bold) : Font.system(size: 34, weight: .bold)).monospacedDigit())
.foregroundStyle(primaryText)
.lineLimit(1)
.minimumScaleFactor(0.6)

if let detail {
Text(detail)
.font(.caption.monospacedDigit())
.foregroundStyle(secondaryText)
if usesLargeControls {
VStack(alignment: .leading, spacing: 10) {
Text(label)
.font(.caption.weight(.bold))
.foregroundStyle(secondaryText)

HStack(spacing: 20) {
decreaseButton

counterValue
.frame(minWidth: isPrimary ? 96 : 76)

increaseButton
}
.frame(maxWidth: .infinity)
}
.frame(minWidth: isPrimary ? 74 : 58)
} else {
HStack(spacing: 16) {
Text(label)
.font(.caption.weight(.bold))
.foregroundStyle(secondaryText)
.frame(width: 72, alignment: .leading)

decreaseButton

counterValue
.frame(minWidth: isPrimary ? 74 : 58)

increaseButton

Button(action: increaseAction) {
Image(systemName: "plus")
Spacer(minLength: 0)
}
.buttonStyle(LoopLineIconButtonStyle(
size: buttonSize,
foregroundColor: primaryIncreaseForeground,
backgroundColor: primaryIncreaseBackground
))
.disabled(!canIncrease)
.opacity(canIncrease ? 1 : 0.38)

Spacer(minLength: 0)
}
}

private var decreaseButton: some View {
Button(action: decreaseAction) {
Image(systemName: "minus")
}
.buttonStyle(LoopLineIconButtonStyle(
size: buttonSize,
foregroundColor: primaryText,
backgroundColor: secondaryButtonBackground
))
.disabled(!canDecrease)
.opacity(canDecrease ? 1 : 0.38)
}

private var increaseButton: some View {
Button(action: increaseAction) {
Image(systemName: "plus")
}
.buttonStyle(LoopLineIconButtonStyle(
size: buttonSize,
foregroundColor: primaryIncreaseForeground,
backgroundColor: primaryIncreaseBackground
))
.disabled(!canIncrease)
.opacity(canIncrease ? 1 : 0.38)
}

private var counterValue: some View {
VStack(spacing: 1) {
Text(value)
.font(valueFont)
.foregroundStyle(primaryText)
.lineLimit(1)
.minimumScaleFactor(0.6)

if let detail {
Text(detail)
.font(.caption.monospacedDigit())
.foregroundStyle(secondaryText)
}
}
}

private var valueFont: Font {
if usesLargeControls {
return (isPrimary ? Font.largeTitle : Font.title).weight(.bold).monospacedDigit()
}
return (isPrimary ? Font.system(size: 48, weight: .bold) : Font.system(size: 34, weight: .bold)).monospacedDigit()
}

private var primaryText: Color {
LoopLineTheme.readingPrimaryText
}
Expand Down
4 changes: 2 additions & 2 deletions LoopLine/Views/SettingsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ private struct SettingsForm: View {
VStack(alignment: .leading, spacing: 14) {
HStack(alignment: .firstTextBaseline) {
VStack(alignment: .leading, spacing: 4) {
Text("Guide opacity")
Text("Text row highlight opacity")
.font(.headline)
Text("Customize row highlight visibility")
Text("Customize the row highlight in text-imported projects")
.font(.caption)
.foregroundStyle(LoopLineTheme.secondaryText)
}
Expand Down
Loading