diff --git a/MacOSCleaner/Features/Cleanup/CleanupView.swift b/MacOSCleaner/Features/Cleanup/CleanupView.swift index ada7fa1..0266ce2 100644 --- a/MacOSCleaner/Features/Cleanup/CleanupView.swift +++ b/MacOSCleaner/Features/Cleanup/CleanupView.swift @@ -76,53 +76,105 @@ public struct CleanupView: View { private var idleView: some View { @Bindable var vm = viewModel - VStack(spacing: 32) { - ZStack { - Circle() - .fill(LinearGradient(colors: [.accentColor.opacity(0.1), .clear], startPoint: .top, endPoint: .bottom)) - .frame(width: 120, height: 120) + ScrollView { + VStack(spacing: 28) { + // Hero + VStack(spacing: 16) { + Image(systemName: "sparkles") + .font(.system(size: 36, weight: .regular)) + .foregroundStyle(.tint) + + VStack(spacing: 6) { + Text("cleanup_ready".localized) + .font(.title2) + .fontWeight(.semibold) + + Text("cleanup_ready_sub".localized) + .font(.subheadline) + .foregroundColor(.secondary) + .multilineTextAlignment(.center) + .frame(maxWidth: 340) + } + } + .padding(.top, 40) - Image(systemName: "sparkles") - .font(.system(size: 64, weight: .light)) - .foregroundStyle(Color.accentColor) - } - .padding(.bottom, 8) - - VStack(spacing: 12) { - Text("cleanup_ready".localized) - .font(.system(.title, design: .rounded, weight: .bold)) + // Options card + VStack(alignment: .leading, spacing: 16) { + Text("cleanup_additional_options".localized) + .font(.headline) + + optionToggle( + title: "cleanup_option_ds_store".localized, + subtitle: "cleanup_option_ds_store_sub".localized, + value: $vm.options.cleanDSStore + ) + + DisclosureGroup("cleanup_extended_title".localized) { + VStack(alignment: .leading, spacing: 14) { + optionToggle( + title: "cleanup_option_cloud_docs".localized, + subtitle: "cleanup_option_cloud_docs_sub".localized, + value: $vm.options.cleanCloudDocs + ) + optionToggle( + title: "cleanup_option_voice_memos".localized, + subtitle: "cleanup_option_voice_memos_sub".localized, + value: $vm.options.cleanVoiceMemos + ) + optionToggle( + title: "cleanup_option_garageband_logic".localized, + subtitle: "cleanup_option_garageband_logic_sub".localized, + value: $vm.options.cleanGarageBandLogic + ) + optionToggle( + title: "cleanup_option_imovie_final_cut".localized, + subtitle: "cleanup_option_imovie_final_cut_sub".localized, + value: $vm.options.cleanIMovieFinalCut + ) + optionToggle( + title: "cleanup_option_sleep_image".localized, + subtitle: "cleanup_option_sleep_image_sub".localized, + value: $vm.options.cleanSleepImage + ) + } + .padding(.leading, 4) + .padding(.top, 8) + } + } + .padding() + .background(Color(NSColor.controlBackgroundColor)) + .clipShape(RoundedRectangle(cornerRadius: 12)) + .overlay(RoundedRectangle(cornerRadius: 12).stroke(Color.secondary.opacity(0.1), lineWidth: 0.5)) - Text("cleanup_ready_sub".localized) - .font(.body) - .foregroundColor(.secondary) - .multilineTextAlignment(.center) - .frame(maxWidth: 360) - } - - VStack(alignment: .leading, spacing: 12) { - Text("cleanup_additional_options".localized) - .font(.headline) - .padding(.bottom, 4) + // Start button + Button(action: { viewModel.startScan() }) { + Text("cleanup_start_scan".localized) + .font(.headline) + .frame(maxWidth: 280) + .frame(height: 32) + } + .buttonStyle(.borderedProminent) + .controlSize(.large) - Toggle("cleanup_option_ds_store".localized, isOn: $vm.options.cleanDSStore) - Text("cleanup_option_ds_store_sub".localized) + Spacer() + } + .frame(maxWidth: .infinity) + } + } + + private func optionToggle(title: String, subtitle: String, value: Binding) -> some View { + HStack { + VStack(alignment: .leading, spacing: 2) { + Text(title) + .font(.subheadline) + Text(subtitle) .font(.caption) .foregroundColor(.secondary) - .padding(.leading, 20) - } - .padding() - .background(Color(NSColor.controlBackgroundColor)) - .cornerRadius(10) - .padding(.horizontal, 40) - .padding(.top, 10) - - Button(action: { viewModel.startScan() }) { - Text("cleanup_start_scan".localized) - .font(.headline) - .frame(width: 180, height: 40) } - .buttonStyle(.borderedProminent) - .controlSize(.large) + Spacer() + Toggle(isOn: value) { EmptyView() } + .toggleStyle(.switch) + .controlSize(.small) } } diff --git a/MacOSCleaner/Resources/en.lproj/Localizable.strings b/MacOSCleaner/Resources/en.lproj/Localizable.strings index 81430b2..9f1967b 100644 --- a/MacOSCleaner/Resources/en.lproj/Localizable.strings +++ b/MacOSCleaner/Resources/en.lproj/Localizable.strings @@ -168,6 +168,17 @@ "cleanup_option_modcache_sub" = "Removes downloaded Go modules. Re-downloads on next build."; "cleanup_option_projects" = "Clean .dart_tool in projects"; "cleanup_option_projects_sub" = "Removes Flutter/Dart project caches in ~/Documents, ~/Projects, ~/Developer, ~/dev, ~/code, ~/repos."; +"cleanup_option_cloud_docs" = "Clean iCloud Documents"; +"cleanup_option_cloud_docs_sub" = "Removes iCloud document cache. Documents re-download from iCloud on demand."; +"cleanup_option_voice_memos" = "Clean Voice Memos"; +"cleanup_option_voice_memos_sub" = "Removes Voice Memos recordings from the library."; +"cleanup_option_garageband_logic" = "Clean GarageBand / Logic"; +"cleanup_option_garageband_logic_sub" = "Removes GarageBand and Logic Pro project files and caches."; +"cleanup_option_imovie_final_cut" = "Clean iMovie / Final Cut"; +"cleanup_option_imovie_final_cut_sub" = "Removes iMovie and Final Cut Pro render files and libraries."; +"cleanup_option_sleep_image" = "Clean Sleep Image"; +"cleanup_option_sleep_image_sub" = "Removes the hibernation image file. macOS recreates it on next sleep."; +"cleanup_extended_title" = "Extended Cleanup"; "cleanup_start_scan" = "Start Scan"; "cleanup_failed" = "Cleanup Failed"; "cleanup_failed_default" = "An error occurred during the cleanup process."; diff --git a/MacOSCleaner/Resources/es.lproj/Localizable.strings b/MacOSCleaner/Resources/es.lproj/Localizable.strings index e77ffee..3113ce2 100644 --- a/MacOSCleaner/Resources/es.lproj/Localizable.strings +++ b/MacOSCleaner/Resources/es.lproj/Localizable.strings @@ -168,6 +168,17 @@ "cleanup_option_modcache_sub" = "Elimina módulos de Go descargados. Se descargan de nuevo en la próxima compilación."; "cleanup_option_projects" = "Limpiar .dart_tool en proyectos"; "cleanup_option_projects_sub" = "Elimina cachés de proyectos Flutter/Dart en ~/Documents, ~/Projects, ~/Developer, ~/dev, ~/code, ~/repos."; +"cleanup_option_cloud_docs" = "Limpiar Documentos de iCloud"; +"cleanup_option_cloud_docs_sub" = "Elimina el caché de documentos de iCloud. Los documentos se vuelven a descargar de iCloud bajo demanda."; +"cleanup_option_voice_memos" = "Limpiar Notas de Voz"; +"cleanup_option_voice_memos_sub" = "Elimina las grabaciones de Notas de Voz de la biblioteca."; +"cleanup_option_garageband_logic" = "Limpiar GarageBand / Logic"; +"cleanup_option_garageband_logic_sub" = "Elimina archivos de proyecto y cachés de GarageBand y Logic Pro."; +"cleanup_option_imovie_final_cut" = "Limpiar iMovie / Final Cut"; +"cleanup_option_imovie_final_cut_sub" = "Elimina archivos de renderizado y bibliotecas de iMovie y Final Cut Pro."; +"cleanup_option_sleep_image" = "Limpiar Imagen de Suspensión"; +"cleanup_option_sleep_image_sub" = "Elimina el archivo de imagen de hibernación. macOS lo recrea en el próximo sueño."; +"cleanup_extended_title" = "Limpieza extendida"; "cleanup_start_scan" = "Iniciar escaneo"; "cleanup_failed" = "Limpieza fallida"; "cleanup_failed_default" = "Ocurrió un error durante el proceso de limpieza."; diff --git a/MacOSCleaner/Resources/ru.lproj/Localizable.strings b/MacOSCleaner/Resources/ru.lproj/Localizable.strings index b125f96..7f01e4d 100644 --- a/MacOSCleaner/Resources/ru.lproj/Localizable.strings +++ b/MacOSCleaner/Resources/ru.lproj/Localizable.strings @@ -168,6 +168,17 @@ "cleanup_option_modcache_sub" = "Удаляет скачанные модули Go. Повторно скачиваются при следующей сборке."; "cleanup_option_projects" = "Очистить .dart_tool в проектах"; "cleanup_option_projects_sub" = "Удаляет кэши проектов Flutter/Dart в ~/Documents, ~/Projects, ~/Developer, ~/dev, ~/code, ~/repos."; +"cleanup_option_cloud_docs" = "Очистить iCloud Документы"; +"cleanup_option_cloud_docs_sub" = "Удаляет кэш iCloud-документов. Документы заново загружаются из iCloud по запросу."; +"cleanup_option_voice_memos" = "Очистить голосовые заметки"; +"cleanup_option_voice_memos_sub" = "Удаляет записи голосовых заметок из библиотеки."; +"cleanup_option_garageband_logic" = "Очистить GarageBand / Logic"; +"cleanup_option_garageband_logic_sub" = "Удаляет файлы проектов и кэши GarageBand и Logic Pro."; +"cleanup_option_imovie_final_cut" = "Очистить iMovie / Final Cut"; +"cleanup_option_imovie_final_cut_sub" = "Удаляет файлы рендеринга и библиотеки iMovie и Final Cut Pro."; +"cleanup_option_sleep_image" = "Очистить образ сна"; +"cleanup_option_sleep_image_sub" = "Удаляет файл гибернации (/var/vm/sleepimage). macOS воссоздаст его при следующем сне."; +"cleanup_extended_title" = "Расширенная очистка"; "cleanup_start_scan" = "Начать сканирование"; "cleanup_failed" = "Ошибка очистки"; "cleanup_failed_default" = "Произошла ошибка в процессе очистки."; diff --git a/MacOSCleaner/Resources/uk.lproj/Localizable.strings b/MacOSCleaner/Resources/uk.lproj/Localizable.strings index 440abd5..4b9f3c7 100644 --- a/MacOSCleaner/Resources/uk.lproj/Localizable.strings +++ b/MacOSCleaner/Resources/uk.lproj/Localizable.strings @@ -166,6 +166,17 @@ "cleanup_option_modcache_sub" = "Видаляє завантажені модулі Go. Повторно завантажуються під час наступної збірки."; "cleanup_option_projects" = "Очистити .dart_tool у проектах"; "cleanup_option_projects_sub" = "Видаляє кеші проектів Flutter/Dart у ~/Documents, ~/Projects, ~/Developer, ~/dev, ~/code, ~/repos."; +"cleanup_option_cloud_docs" = "Очистити iCloud Документи"; +"cleanup_option_cloud_docs_sub" = "Видаляє кеш iCloud-документів. Документи заново завантажуються з iCloud за запитом."; +"cleanup_option_voice_memos" = "Очистити голосові нотатки"; +"cleanup_option_voice_memos_sub" = "Видаляє записи голосових нотаток з бібліотеки."; +"cleanup_option_garageband_logic" = "Очистити GarageBand / Logic"; +"cleanup_option_garageband_logic_sub" = "Видаляє файли проектів та кеші GarageBand і Logic Pro."; +"cleanup_option_imovie_final_cut" = "Очистити iMovie / Final Cut"; +"cleanup_option_imovie_final_cut_sub" = "Видаляє файли рендерингу та бібліотеки iMovie і Final Cut Pro."; +"cleanup_option_sleep_image" = "Очистити образ сну"; +"cleanup_option_sleep_image_sub" = "Видаляє файл гібернації (/var/vm/sleepimage). macOS відтворить його під час наступного сну."; +"cleanup_extended_title" = "Розширене очищення"; "cleanup_start_scan" = "Почати сканування"; "cleanup_failed" = "Помилка очищення"; "cleanup_failed_default" = "Сталася помилка в процесі очищення."; diff --git a/assets/screenshots/Cleanup.png b/assets/screenshots/Cleanup.png deleted file mode 100644 index 33dd61d..0000000 Binary files a/assets/screenshots/Cleanup.png and /dev/null differ diff --git a/assets/screenshots/Cleanup_page.png b/assets/screenshots/Cleanup_page.png new file mode 100644 index 0000000..baa5530 Binary files /dev/null and b/assets/screenshots/Cleanup_page.png differ