crossmate

A collaborative crossword app for iOS
Log | Files | Refs | LICENSE

commit e2f9a3feac8c660697bb92f2686a10b38d3fdfe4
parent e2da1f48340cc0600425ed99d8f2fabcc929dd72
Author: Michael Camilleri <[email protected]>
Date:   Thu,  9 Jul 2026 13:55:01 +0900

Keep External available before provider setup

The External tab previously disappeared when no provider was configured,
which left Settings as the only way to discover the feature. This commit
keeps the tab visible and shows guidance to set up a provider in
Settings instead of the provider menu and calendar.

Co-Authored-By: Codex GPT 5.5 <[email protected]>

Diffstat:
MCrossmate/Models/PuzzleSource.swift | 2+-
MCrossmate/Views/Browse/ExternalBrowseView.swift | 23+++++++++++++----------
MCrossmate/Views/Browse/NYTBrowseView.swift | 2+-
MCrossmate/Views/Browse/NewGameSheet.swift | 17+----------------
4 files changed, 16 insertions(+), 28 deletions(-)

diff --git a/Crossmate/Models/PuzzleSource.swift b/Crossmate/Models/PuzzleSource.swift @@ -2,8 +2,8 @@ import Foundation enum PuzzleSource: String, CaseIterable, Identifiable { case bundles - case external case imported + case external var id: String { rawValue } diff --git a/Crossmate/Views/Browse/ExternalBrowseView.swift b/Crossmate/Views/Browse/ExternalBrowseView.swift @@ -4,22 +4,25 @@ struct ExternalBrowseView: View { let onSelected: (String) -> Void let excludedDates: Set<Date> + @Environment(NYTAuthService.self) private var nytAuth @State private var provider: ExternalPuzzleProvider = .newYorkTimes var body: some View { VStack(spacing: 0) { - Picker("Provider", selection: $provider) { - ForEach(ExternalPuzzleProvider.allCases) { provider in - Text(provider.title).tag(provider) + if nytAuth.canAttemptNYTFetch { + Picker("Provider", selection: $provider) { + ForEach(ExternalPuzzleProvider.allCases) { provider in + Text(provider.title).tag(provider) + } } + .pickerStyle(.menu) + .buttonStyle(.bordered) + .fixedSize() + .frame(maxWidth: .infinity) + .padding(.horizontal) + .padding(.top) + .padding(.bottom, 8) } - .pickerStyle(.menu) - .buttonStyle(.bordered) - .fixedSize() - .frame(maxWidth: .infinity) - .padding(.horizontal) - .padding(.top) - .padding(.bottom, 8) switch provider { case .newYorkTimes: diff --git a/Crossmate/Views/Browse/NYTBrowseView.swift b/Crossmate/Views/Browse/NYTBrowseView.swift @@ -171,7 +171,7 @@ struct NYTBrowseView: View { Image(systemName: "person.crop.circle.badge.exclamationmark") .font(.largeTitle) .foregroundStyle(.secondary) - Text("Sign in to NYT from Settings to fetch crossword puzzles.") + Text("Set up an external puzzle provider in Settings to fetch crossword puzzles.") .font(.body) .foregroundStyle(.secondary) .multilineTextAlignment(.center) diff --git a/Crossmate/Views/Browse/NewGameSheet.swift b/Crossmate/Views/Browse/NewGameSheet.swift @@ -6,7 +6,6 @@ struct NewGameSheet: View { var onCreated: (UUID) -> Void = { _ in } @Environment(\.dismiss) private var dismiss - @Environment(NYTAuthService.self) private var nytAuth @Environment(EventLog.self) private var eventLog @AppStorage("lastPuzzleSource") private var selection: PuzzleSource = .bundles @State private var duplicateSource: String? @@ -18,20 +17,11 @@ struct NewGameSheet: View { let message: String } - private var availableSources: [PuzzleSource] { - var sources: [PuzzleSource] = [.bundles] - sources.append(.imported) - if nytAuth.canAttemptNYTFetch { - sources.append(.external) - } - return sources - } - var body: some View { NavigationStack { VStack(spacing: 0) { Picker("Source", selection: $selection) { - ForEach(availableSources) { source in + ForEach(PuzzleSource.allCases) { source in Text(source.title).tag(source) } } @@ -65,11 +55,6 @@ struct NewGameSheet: View { } } } - .onAppear { - if !availableSources.contains(selection) { - selection = .bundles - } - } .alert( "Puzzle Already in Library", isPresented: .init(