// // OfflineReadingDetailView.swift // readeck // // Created by Claude on 17.11.25. // import SwiftUI struct OfflineReadingDetailView: View { @State private var viewModel = OfflineSettingsViewModel() @EnvironmentObject var appSettings: AppSettings var body: some View { List { Section { VStack(alignment: .leading, spacing: 4) { Toggle("Enable Offline Reading", isOn: $viewModel.offlineSettings.enabled) .onChange(of: viewModel.offlineSettings.enabled) { Task { await viewModel.saveSettings() } } Text("Automatically download articles for offline use.") .font(.caption) .foregroundColor(.secondary) .padding(.top, 2) } if viewModel.offlineSettings.enabled { // Max articles slider VStack(alignment: .leading, spacing: 8) { HStack { Text("Maximum Articles") Spacer() Text("\(viewModel.offlineSettings.maxUnreadArticlesInt)") .font(.caption) .foregroundColor(.secondary) } Slider( value: $viewModel.offlineSettings.maxUnreadArticles, in: 0...100, step: 10 ) { Text("Max. Articles Offline") } .onChange(of: viewModel.offlineSettings.maxUnreadArticles) { Task { await viewModel.saveSettings() } } } // Save images toggle VStack(alignment: .leading, spacing: 4) { Toggle("Save Images", isOn: $viewModel.offlineSettings.saveImages) .onChange(of: viewModel.offlineSettings.saveImages) { Task { await viewModel.saveSettings() } } Text("Also download images for offline use.") .font(.caption) .foregroundColor(.secondary) .padding(.top, 2) } } } header: { Text("Settings") .font(.subheadline) .fontWeight(.semibold) .foregroundColor(.primary) .textCase(nil) } footer: { Text("VPN connections are detected as active internet connections.") .font(.caption) .foregroundColor(.secondary) } if viewModel.offlineSettings.enabled { Section { // Sync button Button(action: { Task { await viewModel.syncNow() } }) { HStack { if viewModel.isSyncing { ProgressView() .scaleEffect(0.8) } else { Image(systemName: "arrow.clockwise") .foregroundColor(.blue) } VStack(alignment: .leading, spacing: 2) { Text("Sync Now") .foregroundColor(viewModel.isSyncing ? .secondary : .blue) if let progress = viewModel.syncProgress { Text(progress) .font(.caption) .foregroundColor(.secondary) } else if let lastSync = viewModel.offlineSettings.lastSyncDate { Text("Last synced: \(lastSync.formatted(.relative(presentation: .named)))") .font(.caption) .foregroundColor(.secondary) } } Spacer() } } .disabled(viewModel.isSyncing) // Cache stats with preview link if viewModel.cachedArticlesCount > 0 { SettingsRowNavigationLink( icon: "doc.text.magnifyingglass", iconColor: .green, title: "Preview Cached Articles", subtitle: "\(viewModel.cachedArticlesCount) articles (\(viewModel.cacheSize))" ) { CachedArticlesPreviewView() } } } header: { Text("Synchronization") .font(.subheadline) .fontWeight(.semibold) .foregroundColor(.primary) .textCase(nil) } #if DEBUG Section { // Debug: Toggle offline mode simulation VStack(alignment: .leading, spacing: 4) { Toggle(isOn: Binding( get: { !appSettings.isNetworkConnected }, set: { isOffline in appSettings.isNetworkConnected = !isOffline } )) { HStack { Image(systemName: "airplane") .foregroundColor(.orange) VStack(alignment: .leading, spacing: 2) { Text("Simulate Offline Mode") .foregroundColor(.orange) Text("DEBUG: Toggle network status") .font(.caption) .foregroundColor(.secondary) } } } } } header: { Text("Debug") .font(.subheadline) .fontWeight(.semibold) .foregroundColor(.primary) .textCase(nil) } #endif } } .listStyle(.insetGrouped) .navigationTitle("Offline Reading") .navigationBarTitleDisplayMode(.inline) .task { await viewModel.loadSettings() } } }