From d0ac7d6f35e921021a15c53d63ce8d0165051c08 Mon Sep 17 00:00:00 2001 From: Maksim Zoteev <39910552+F0x1d@users.noreply.github.com> Date: Sun, 3 Nov 2024 16:52:52 +0300 Subject: [PATCH] [feat]: update v2.0.3 * [feat]: finally some logging in debug mode * [build]: updated libraries and SDK versions * [build]: fixed fdroid issues * [build]: renamed data to shared module * [build]: updated tests screenshots * [fix]: removed debug logging by default * [build]: moved code and modules a little * [build]: refactored app a little once again * [build]: bumped app version --- app/build.gradle.kts | 31 ++- app/src/main/AndroidManifest.xml | 7 +- .../main/kotlin/com/f0x1d/logfox/LogFoxApp.kt | 15 ++ .../com/f0x1d/logfox/coil/AppIconFetcher.kt | 6 +- ...MainActivityPendingIntentProviderModule.kt | 4 +- .../settings/LoggingServiceDelegateModule.kt | 30 --- .../f0x1d/logfox/presentation/MainAction.kt | 5 + .../f0x1d/logfox/presentation/MainState.kt | 3 + .../MainViewModel.kt | 16 +- .../ui/activity/MainActivity.kt | 27 ++- .../ui/activity/OpenFileActivity.kt | 4 +- .../com/f0x1d/logfox/receiver/BootReceiver.kt | 4 +- app/src/main/res/xml/file_paths.xml | 3 +- .../main/kotlin/extensions/Dependencies.kt | 7 +- .../main/AndroidCoreConventionPlugin.kt | 4 +- .../feature/AndroidFeatureConventionPlugin.kt | 1 + .../f0x1d/logfox/arch/logs/TimberFileTree.kt | 45 ++++ .../adapter/BaseListAdapter.kt | 4 +- .../arch/{ => presentation}/ui/SnackbarExt.kt | 2 +- .../arch/{ => presentation}/ui/WindowExt.kt | 2 +- .../ui/activity/BaseActivity.kt | 8 +- .../ui/base/SimpleLifecycleOwner.kt | 2 +- .../ui/dialog/BaseBottomSheetFragment.kt} | 9 +- .../ui/fragment/BaseFragment.kt | 6 +- .../fragment/compose/BaseComposeFragment.kt | 14 +- .../ui/viewholder/BaseViewHolder.kt | 4 +- .../logfox/arch/repository/BaseRepository.kt | 3 - .../arch/ui/activity/BaseViewModelActivity.kt | 24 --- .../ui/dialog/BaseViewModelBottomSheet.kt | 19 -- .../arch/ui/fragment/BaseViewModelFragment.kt | 24 --- .../compose/BaseComposeViewModelFragment.kt | 37 ---- .../arch/viewmodel/BaseStateViewModel.kt | 18 -- .../logfox/arch/viewmodel/BaseViewModel.kt | 36 ++-- .../com/f0x1d/logfox/arch/viewmodel/Event.kt | 7 - .../src/main/res/navigation/crashes.xml | 8 +- .../src/main/res/navigation/logs.xml | 12 +- .../src/main/res/navigation/nav_graph.xml | 2 +- .../src/main/res/navigation/recordings.xml | 4 +- .../src/main/res/navigation/settings.xml | 12 +- .../aidl/com/f0x1d/logfox/IUserService.aidl | 4 +- .../logfox/model/terminal/TerminalResult.aidl | 3 - .../f0x1d/logfox/models/TerminalResult.aidl | 3 + .../f0x1d/logfox/models}/TerminalProcess.kt | 2 +- .../f0x1d/logfox/models}/TerminalResult.kt | 4 +- .../com/f0x1d/logfox/service/UserService.kt | 6 +- .../f0x1d/logfox/terminals/DefaultTerminal.kt | 4 +- .../f0x1d/logfox/terminals/RootTerminal.kt | 4 +- .../f0x1d/logfox/terminals/ShizukuTerminal.kt | 4 +- .../f0x1d/logfox/terminals/base/Terminal.kt | 4 +- feature/apps-picker/api/.gitignore | 1 + feature/apps-picker/api/build.gradle.kts | 9 + .../apps/picker/AppsPickerResultHandler.kt | 18 ++ .../feature/apps/picker}/InstalledApp.kt | 4 +- {data => feature/apps-picker/impl}/.gitignore | 0 .../apps-picker/{ => impl}/build.gradle.kts | 2 + .../picker/presentation/AppsPickerAction.kt | 3 + .../picker/presentation/AppsPickerState.kt | 18 ++ .../presentation}/AppsPickerViewModel.kt | 37 ++-- .../presentation/ui}/AppsPickerFragment.kt | 37 ++-- .../ui/AppsPickerScreenListener.kt | 19 ++ .../ui}/compose/AppsPickerScreenContent.kt | 17 +- .../picker/compose/AppsPickerScreenState.kt | 34 --- .../viewmodel/AppsPickerResultHandler.kt | 34 --- .../{crashes-core => crashes/api}/.gitignore | 0 .../api}/build.gradle.kts | 2 +- .../crashes/api/data/CrashesController.kt | 7 + .../data/CrashesNotificationsController.kt | 12 ++ .../crashes/api/data/CrashesRepository.kt | 15 ++ .../api/data/DisabledAppsRepository.kt | 13 ++ feature/crashes/apps-list/.gitignore | 1 + feature/crashes/apps-list/build.gradle.kts | 10 + .../list}/di/AppCrashesViewModelModule.kt | 2 +- .../list/presentation/AppCrashesAction.kt | 3 + .../apps/list/presentation/AppCrashesState.kt | 7 + .../list/presentation/AppCrashesViewModel.kt | 56 +++++ .../presentation/ui}/AppCrashesFragment.kt | 18 +- .../main/res/layout/fragment_app_crashes.xml | 0 feature/crashes/build.gradle.kts | 12 -- .../common}/.gitignore | 0 feature/crashes/common/build.gradle.kts | 9 + .../presentation}/adapter/CrashesAdapter.kt | 8 +- .../ui/viewholder/CrashViewHolder.kt | 6 +- .../src/main/res/layout/item_crash.xml | 0 .../main/res/layout/placeholder_crashes.xml | 0 feature/crashes/details/.gitignore | 1 + feature/crashes/details/build.gradle.kts | 10 + .../di/CrashDetailsViewModelModule.kt | 2 +- .../presentation/CrashDetailsAction.kt | 3 + .../details/presentation/CrashDetailsState.kt | 9 + .../presentation}/CrashDetailsViewModel.kt | 86 ++++---- .../presentation/ui}/CrashDetailsFragment.kt | 164 ++++++++------- .../res/layout/fragment_crash_details.xml | 0 .../src/main/res/menu/crash_details_menu.xml | 0 feature/crashes/impl/.gitignore | 1 + feature/crashes/impl/build.gradle.kts | 9 + .../impl/data/CrashesControllerImpl.kt} | 18 +- .../CrashesNotificationsControllerImpl.kt} | 12 +- .../impl/data/CrashesRepositoryImpl.kt} | 16 +- .../impl/data/DisabledAppsRepositoryImpl.kt} | 12 +- .../crashes/impl/data}/reader/ANRDetector.kt | 4 +- .../impl/data}/reader/JNICrashDetector.kt | 4 +- .../impl/data}/reader/JavaCrashDetector.kt | 4 +- .../data}/reader/base/BaseCrashDetector.kt | 4 +- .../impl/data}/reader/base/DefaultChecker.kt | 2 +- .../crashes/impl}/di/ControllersModule.kt | 10 +- .../crashes/impl}/di/RepositoriesModule.kt | 10 +- feature/crashes/list/.gitignore | 1 + feature/crashes/list/build.gradle.kts | 12 ++ .../list/presentation/CrashesAction.kt | 3 + .../crashes/list/presentation/CrashesState.kt | 12 ++ .../list/presentation/CrashesViewModel.kt | 154 ++++++++++++++ .../list/presentation/ui}/CrashesFragment.kt | 36 ++-- .../src/main/res/layout/dialog_sorting.xml | 0 .../src/main/res/layout/fragment_crashes.xml | 0 .../src/main/res/layout/item_sort.xml | 0 .../src/main/res/menu/crashes_menu.xml | 0 .../viewmodel/list/AppCrashesViewModel.kt | 47 ----- .../viewmodel/list/CrashesViewModel.kt | 150 -------------- .../{filters-core => filters/api}/.gitignore | 0 .../api}/build.gradle.kts | 2 +- .../filters/api/data/FiltersRepository.kt | 38 ++++ feature/filters/build.gradle.kts | 12 -- feature/filters/edit/.gitignore | 1 + feature/filters/edit/build.gradle.kts | 12 ++ .../edit}/di/EditFilterViewModelModule.kt | 2 +- .../edit/presentation/EditFilterAction.kt | 5 + .../edit/presentation/EditFilterState.kt | 9 + .../edit/presentation/EditFilterViewModel.kt | 133 ++++++++++++ .../presentation/ui}/EditFilterFragment.kt | 91 ++++---- .../main/res/layout/fragment_edit_filter.xml | 0 .../src/main/res/menu/edit_filter_menu.xml | 3 +- feature/filters/{ => impl}/.gitignore | 0 feature/filters/impl/build.gradle.kts | 12 ++ .../impl/data/FiltersRepositoryImpl.kt} | 36 +--- .../filters/impl}/di/RepositoriesModule.kt | 6 +- feature/filters/list/.gitignore | 1 + feature/filters/list/build.gradle.kts | 11 + .../list/presentation/FiltersAction.kt | 3 + .../filters/list/presentation/FiltersState.kt | 7 + .../list/presentation}/FiltersViewModel.kt | 33 +-- .../presentation/adapter/FiltersAdapter.kt | 24 +++ .../ui/fragment/FiltersFragment.kt | 22 +- .../ui/viewholder/FilterViewHolder.kt | 6 +- .../src/main/res/layout/fragment_filters.xml | 0 .../src/main/res/layout/item_filter.xml | 0 .../main/res/layout/placeholder_filters.xml | 0 .../src/main/res/menu/filters_menu.xml | 0 .../feature/filters/adapter/FiltersAdapter.kt | 32 --- .../filters/viewmodel/EditFilterViewModel.kt | 117 ----------- .../feature/logging/core/di/StoresModule.kt | 18 -- .../core/repository/LoggingRepository.kt | 102 --------- .../{logging-core => logging/api}/.gitignore | 0 .../api}/build.gradle.kts | 2 +- .../logging/api/data/LoggingRepository.kt | 22 ++ .../logging/api/data/LogsDataSource.kt | 10 + .../logging/api/data/QueryDataSource.kt | 9 + .../api/data/SelectedLogLinesDataSource.kt | 10 + .../feature/logging/api}/model/LogLinesExt.kt | 2 +- .../presentation/LoggingServiceDelegate.kt | 7 + feature/logging/build.gradle.kts | 12 -- .../extended-copy}/.gitignore | 0 .../logging/extended-copy/build.gradle.kts | 9 + .../presentation/LogsExtendedCopyAction.kt | 3 + .../presentation/LogsExtendedCopyState.kt | 5 + .../presentation/LogsExtendedCopyViewModel.kt | 50 +++++ .../ui}/LogsExtendedCopyFragment.kt | 21 +- .../layout/fragment_logs_extended_copy.xml | 0 feature/{crashes => logging/impl}/.gitignore | 0 feature/logging/impl/build.gradle.kts | 9 + .../impl/data/LoggingRepositoryImpl.kt | 118 +++++++++++ .../logging/impl/data/LogsDataSourceImpl.kt} | 18 +- .../logging/impl/data/QueryDataSourceImpl.kt | 25 +++ .../data/SelectedLogLinesDataSourceImpl.kt | 26 +++ .../logging/impl/di/DataSourcesModule.kt | 32 +++ .../logging/impl}/di/RepositoriesModule.kt | 6 +- .../{recordings => logging/list}/.gitignore | 0 feature/logging/list/build.gradle.kts | 12 ++ .../logging/list}/di/LogsViewModelModule.kt | 2 +- .../logging/list/presentation/LogsAction.kt | 3 + .../logging/list/presentation/LogsState.kt | 12 ++ .../list/presentation/LogsViewModel.kt | 195 ++++++++++++++++++ .../logging/list/presentation}/UriExt.kt | 10 +- .../list/presentation}/adapter/LogsAdapter.kt | 8 +- .../presentation}/ui/fragment/LogsFragment.kt | 174 ++++++++-------- .../ui/viewholder/LogViewHolder.kt | 23 +-- .../src/main/res/layout/fragment_logs.xml | 0 .../src/main/res/layout/item_log.xml | 0 .../src/main/res/layout/placeholder_logs.xml | 0 .../{ => list}/src/main/res/menu/log_menu.xml | 0 .../src/main/res/menu/logs_menu.xml | 0 feature/logging/search/.gitignore | 1 + feature/logging/search/build.gradle.kts | 9 + .../search/presentation/SearchLogsAction.kt | 5 + .../search/presentation/SearchLogsState.kt | 5 + .../presentation/SearchLogsViewModel.kt | 37 ++++ .../ui/SearchLogsBottomSheetFragment.kt} | 38 ++-- .../src/main/res/layout/sheet_search.xml | 0 feature/logging/service/.gitignore | 1 + feature/logging/service/build.gradle.kts | 12 ++ .../src/main/AndroidManifest.xml | 2 +- .../di/LoggingServiceDelegateModule.kt | 18 ++ .../service/presentation}/LoggingService.kt | 42 +++- .../LoggingServiceDelegateImpl.kt | 23 +++ .../MainActivityPendingIntentProvider.kt | 2 +- .../logging/viewmodel/LogsViewModel.kt | 178 ---------------- feature/recordings-core/build.gradle.kts | 9 - feature/recordings/api/.gitignore | 1 + feature/recordings/api/build.gradle.kts | 9 + .../api/data/RecordingController.kt | 21 ++ .../data/RecordingNotificationController.kt | 13 ++ .../api/data/RecordingsRepository.kt | 12 ++ .../api/data}/reader/RecordingReader.kt | 2 +- feature/recordings/build.gradle.kts | 9 - feature/recordings/details/.gitignore | 1 + feature/recordings/details/build.gradle.kts | 10 + .../di/RecordingDetailsViewModelModule.kt} | 2 +- .../presentation/RecordingDetailsAction.kt | 3 + .../presentation/RecordingDetailsState.kt | 7 + .../RecordingDetailsViewModel.kt} | 54 ++--- .../RecordingDetailsBottomSheetFragment.kt} | 51 ++--- .../res/layout/sheet_recording_details.xml} | 0 feature/recordings/impl/.gitignore | 1 + feature/recordings/impl/build.gradle.kts | 10 + .../impl}/src/main/AndroidManifest.xml | 2 +- .../impl/data/RecordingControllerImpl.kt} | 25 +-- .../RecordingNotificationControllerImpl.kt} | 17 +- .../impl/data/RecordingsRepositoryImpl.kt} | 13 +- .../recordings/impl}/di/ControllersModule.kt | 10 +- .../recordings/impl}/di/RepositoriesModule.kt | 6 +- .../receiver/RecordingReceiver.kt | 4 +- feature/recordings/list/.gitignore | 1 + feature/recordings/list/build.gradle.kts | 10 + .../list/presentation/RecordingsAction.kt | 8 + .../list/presentation/RecordingsState.kt | 9 + .../list/presentation/RecordingsViewModel.kt | 78 +++++++ .../presentation/adapter/RecordingsAdapter.kt | 22 ++ .../ui/fragment/RecordingsFragment.kt | 46 ++--- .../ui/viewholder/RecordingViewHolder.kt | 6 +- .../main/res/layout/fragment_recordings.xml | 0 .../src/main/res/layout/item_recording.xml | 0 .../res/layout/placeholder_recordings.xml | 0 .../src/main/res/menu/recordings_menu.xml | 0 .../recordings/adapter/RecordingsAdapter.kt | 21 -- .../viewmodel/RecordingsViewModel.kt | 61 ------ feature/settings/build.gradle.kts | 2 +- .../settings/LoggingServiceDelegate.kt | 5 - .../{ => presentation}/IntArrayExt.kt | 2 +- .../ui/fragment/SettingsCrashesFragment.kt | 4 +- .../ui/fragment/SettingsLinksFragment.kt | 4 +- .../ui/fragment/SettingsMenuFragment.kt | 21 +- .../fragment/SettingsNotificationsFragment.kt | 4 +- .../ui/fragment/SettingsServiceFragment.kt | 12 +- .../ui/fragment/SettingsUIFragment.kt | 6 +- .../fragment/base/BasePreferenceFragment.kt | 4 +- .../src/main/res/xml/settings_menu.xml | 3 + .../feature/setup/presentation/SetupAction.kt | 7 + .../feature/setup/presentation/SetupState.kt | 6 + .../SetupViewModel.kt | 22 +- .../setup/presentation/ui/SetupFragment.kt | 58 ++++++ .../ui/SetupScreenListener.kt} | 7 +- .../ui}/compose/SetupScreenContent.kt | 9 +- .../setup/ui/fragment/setup/SetupFragment.kt | 41 ---- .../ui}/compose/SetupScreenContentTest.kt | 13 +- ...houldOpenAdbDialogOnSetupScreenContent.png | Bin 0 -> 48367 bytes ...houldShowAdbDialogOnSetupScreenContent.png | Bin 0 -> 206094 bytes ...Test.shouldShowDarkSetupScreenContent.png} | Bin 40052 -> 40076 bytes ...ntentTest.shouldShowSetupScreenContent.png | Bin 0 -> 39627 bytes ...houldOpenAdbDialogOnSetupScreenContent.png | Bin 48482 -> 0 bytes ...houldShowAdbDialogOnSetupScreenContent.png | Bin 206610 -> 0 bytes ...ntentTest.shouldShowSetupScreenContent.png | Bin 81418 -> 0 bytes gradle/libs.versions.toml | 30 +-- gradle/wrapper/gradle-wrapper.properties | 4 +- settings.gradle.kts | 37 +++- {feature/logging => shared}/.gitignore | 0 {data => shared}/build.gradle.kts | 2 + .../kotlin/com/f0x1d/logfox/model/Device.kt | 0 .../com/f0x1d/logfox/model/Identifiable.kt | 1 - .../kotlin/com/f0x1d/logfox/model/UIDS.kt | 0 .../TerminalNotSupportedException.kt | 0 .../com/f0x1d/logfox/model/logline/LogLine.kt | 14 +- .../f0x1d/logfox/model/logline/LogLineExt.kt | 9 +- .../logfox/model/preferences/ShowLogValues.kt | 0 strings/src/main/res/values-ru/strings.xml | 1 + strings/src/main/res/values/strings.xml | 1 + 284 files changed, 2600 insertions(+), 1946 deletions(-) delete mode 100644 app/src/main/kotlin/com/f0x1d/logfox/di/settings/LoggingServiceDelegateModule.kt create mode 100644 app/src/main/kotlin/com/f0x1d/logfox/presentation/MainAction.kt create mode 100644 app/src/main/kotlin/com/f0x1d/logfox/presentation/MainState.kt rename app/src/main/kotlin/com/f0x1d/logfox/{viewmodel => presentation}/MainViewModel.kt (77%) rename app/src/main/kotlin/com/f0x1d/logfox/{ => presentation}/ui/activity/MainActivity.kt (92%) rename app/src/main/kotlin/com/f0x1d/logfox/{ => presentation}/ui/activity/OpenFileActivity.kt (91%) create mode 100644 core/arch/src/main/kotlin/com/f0x1d/logfox/arch/logs/TimberFileTree.kt rename core/arch/src/main/kotlin/com/f0x1d/logfox/arch/{ => presentation}/adapter/BaseListAdapter.kt (91%) rename core/arch/src/main/kotlin/com/f0x1d/logfox/arch/{ => presentation}/ui/SnackbarExt.kt (79%) rename core/arch/src/main/kotlin/com/f0x1d/logfox/arch/{ => presentation}/ui/WindowExt.kt (97%) rename core/arch/src/main/kotlin/com/f0x1d/logfox/arch/{ => presentation}/ui/activity/BaseActivity.kt (89%) rename core/arch/src/main/kotlin/com/f0x1d/logfox/arch/{ => presentation}/ui/base/SimpleLifecycleOwner.kt (95%) rename core/arch/src/main/kotlin/com/f0x1d/logfox/arch/{ui/dialog/BaseBottomSheet.kt => presentation/ui/dialog/BaseBottomSheetFragment.kt} (85%) rename core/arch/src/main/kotlin/com/f0x1d/logfox/arch/{ => presentation}/ui/fragment/BaseFragment.kt (89%) rename core/arch/src/main/kotlin/com/f0x1d/logfox/arch/{ => presentation}/ui/fragment/compose/BaseComposeFragment.kt (70%) rename core/arch/src/main/kotlin/com/f0x1d/logfox/arch/{ => presentation}/ui/viewholder/BaseViewHolder.kt (87%) delete mode 100644 core/arch/src/main/kotlin/com/f0x1d/logfox/arch/repository/BaseRepository.kt delete mode 100644 core/arch/src/main/kotlin/com/f0x1d/logfox/arch/ui/activity/BaseViewModelActivity.kt delete mode 100644 core/arch/src/main/kotlin/com/f0x1d/logfox/arch/ui/dialog/BaseViewModelBottomSheet.kt delete mode 100644 core/arch/src/main/kotlin/com/f0x1d/logfox/arch/ui/fragment/BaseViewModelFragment.kt delete mode 100644 core/arch/src/main/kotlin/com/f0x1d/logfox/arch/ui/fragment/compose/BaseComposeViewModelFragment.kt delete mode 100644 core/arch/src/main/kotlin/com/f0x1d/logfox/arch/viewmodel/BaseStateViewModel.kt delete mode 100644 core/arch/src/main/kotlin/com/f0x1d/logfox/arch/viewmodel/Event.kt delete mode 100644 core/terminals/src/main/aidl/com/f0x1d/logfox/model/terminal/TerminalResult.aidl create mode 100644 core/terminals/src/main/aidl/com/f0x1d/logfox/models/TerminalResult.aidl rename {data/src/main/kotlin/com/f0x1d/logfox/model/terminal => core/terminals/src/main/kotlin/com/f0x1d/logfox/models}/TerminalProcess.kt (83%) rename {data/src/main/kotlin/com/f0x1d/logfox/model/terminal => core/terminals/src/main/kotlin/com/f0x1d/logfox/models}/TerminalResult.kt (86%) create mode 100644 feature/apps-picker/api/.gitignore create mode 100644 feature/apps-picker/api/build.gradle.kts create mode 100644 feature/apps-picker/api/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/AppsPickerResultHandler.kt rename {data/src/main/kotlin/com/f0x1d/logfox/model => feature/apps-picker/api/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker}/InstalledApp.kt (61%) rename {data => feature/apps-picker/impl}/.gitignore (100%) rename feature/apps-picker/{ => impl}/build.gradle.kts (76%) create mode 100644 feature/apps-picker/impl/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/presentation/AppsPickerAction.kt create mode 100644 feature/apps-picker/impl/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/presentation/AppsPickerState.kt rename feature/apps-picker/{src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/viewmodel => impl/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/presentation}/AppsPickerViewModel.kt (63%) rename feature/apps-picker/{src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/ui/fragment/picker => impl/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/presentation/ui}/AppsPickerFragment.kt (60%) create mode 100644 feature/apps-picker/impl/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/presentation/ui/AppsPickerScreenListener.kt rename feature/apps-picker/{src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/ui/fragment/picker => impl/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/presentation/ui}/compose/AppsPickerScreenContent.kt (92%) delete mode 100644 feature/apps-picker/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/ui/fragment/picker/compose/AppsPickerScreenState.kt delete mode 100644 feature/apps-picker/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/viewmodel/AppsPickerResultHandler.kt rename feature/{crashes-core => crashes/api}/.gitignore (100%) rename feature/{crashes-core => crashes/api}/build.gradle.kts (52%) create mode 100644 feature/crashes/api/src/main/kotlin/com/f0x1d/logfox/feature/crashes/api/data/CrashesController.kt create mode 100644 feature/crashes/api/src/main/kotlin/com/f0x1d/logfox/feature/crashes/api/data/CrashesNotificationsController.kt create mode 100644 feature/crashes/api/src/main/kotlin/com/f0x1d/logfox/feature/crashes/api/data/CrashesRepository.kt create mode 100644 feature/crashes/api/src/main/kotlin/com/f0x1d/logfox/feature/crashes/api/data/DisabledAppsRepository.kt create mode 100644 feature/crashes/apps-list/.gitignore create mode 100644 feature/crashes/apps-list/build.gradle.kts rename feature/crashes/{src/main/kotlin/com/f0x1d/logfox/feature/crashes => apps-list/src/main/kotlin/com/f0x1d/logfox/feature/crashes/apps/list}/di/AppCrashesViewModelModule.kt (93%) create mode 100644 feature/crashes/apps-list/src/main/kotlin/com/f0x1d/logfox/feature/crashes/apps/list/presentation/AppCrashesAction.kt create mode 100644 feature/crashes/apps-list/src/main/kotlin/com/f0x1d/logfox/feature/crashes/apps/list/presentation/AppCrashesState.kt create mode 100644 feature/crashes/apps-list/src/main/kotlin/com/f0x1d/logfox/feature/crashes/apps/list/presentation/AppCrashesViewModel.kt rename feature/crashes/{src/main/kotlin/com/f0x1d/logfox/feature/crashes/ui/fragment/list => apps-list/src/main/kotlin/com/f0x1d/logfox/feature/crashes/apps/list/presentation/ui}/AppCrashesFragment.kt (78%) rename feature/crashes/{ => apps-list}/src/main/res/layout/fragment_app_crashes.xml (100%) delete mode 100644 feature/crashes/build.gradle.kts rename feature/{apps-picker => crashes/common}/.gitignore (100%) create mode 100644 feature/crashes/common/build.gradle.kts rename feature/crashes/{src/main/kotlin/com/f0x1d/logfox/feature/crashes => common/src/main/kotlin/com/f0x1d/logfox/feature/crashes/common/presentation}/adapter/CrashesAdapter.kt (76%) rename feature/crashes/{src/main/kotlin/com/f0x1d/logfox/feature/crashes => common/src/main/kotlin/com/f0x1d/logfox/feature/crashes/common/presentation}/ui/viewholder/CrashViewHolder.kt (85%) rename feature/crashes/{ => common}/src/main/res/layout/item_crash.xml (100%) rename feature/crashes/{ => common}/src/main/res/layout/placeholder_crashes.xml (100%) create mode 100644 feature/crashes/details/.gitignore create mode 100644 feature/crashes/details/build.gradle.kts rename feature/crashes/{src/main/kotlin/com/f0x1d/logfox/feature/crashes => details/src/main/kotlin/com/f0x1d/logfox/feature/crashes/details}/di/CrashDetailsViewModelModule.kt (91%) create mode 100644 feature/crashes/details/src/main/kotlin/com/f0x1d/logfox/feature/crashes/details/presentation/CrashDetailsAction.kt create mode 100644 feature/crashes/details/src/main/kotlin/com/f0x1d/logfox/feature/crashes/details/presentation/CrashDetailsState.kt rename feature/crashes/{src/main/kotlin/com/f0x1d/logfox/feature/crashes/viewmodel => details/src/main/kotlin/com/f0x1d/logfox/feature/crashes/details/presentation}/CrashDetailsViewModel.kt (57%) rename feature/crashes/{src/main/kotlin/com/f0x1d/logfox/feature/crashes/ui/fragment => details/src/main/kotlin/com/f0x1d/logfox/feature/crashes/details/presentation/ui}/CrashDetailsFragment.kt (69%) rename feature/crashes/{ => details}/src/main/res/layout/fragment_crash_details.xml (100%) rename feature/crashes/{ => details}/src/main/res/menu/crash_details_menu.xml (100%) create mode 100644 feature/crashes/impl/.gitignore create mode 100644 feature/crashes/impl/build.gradle.kts rename feature/{crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/controller/CrashesController.kt => crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/data/CrashesControllerImpl.kt} (83%) rename feature/{crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/controller/CrashesNotificationsController.kt => crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/data/CrashesNotificationsControllerImpl.kt} (93%) rename feature/{crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/repository/CrashesRepository.kt => crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/data/CrashesRepositoryImpl.kt} (83%) rename feature/{crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/repository/DisabledAppsRepository.kt => crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/data/DisabledAppsRepositoryImpl.kt} (85%) rename feature/{crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/repository => crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/data}/reader/ANRDetector.kt (84%) rename feature/{crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/repository => crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/data}/reader/JNICrashDetector.kt (92%) rename feature/{crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/repository => crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/data}/reader/JavaCrashDetector.kt (82%) rename feature/{crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/repository => crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/data}/reader/base/BaseCrashDetector.kt (96%) rename feature/{crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/repository => crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/data}/reader/base/DefaultChecker.kt (85%) rename feature/{crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core => crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl}/di/ControllersModule.kt (57%) rename feature/{crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core => crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl}/di/RepositoriesModule.kt (56%) create mode 100644 feature/crashes/list/.gitignore create mode 100644 feature/crashes/list/build.gradle.kts create mode 100644 feature/crashes/list/src/main/kotlin/com/f0x1d/logfox/feature/crashes/list/presentation/CrashesAction.kt create mode 100644 feature/crashes/list/src/main/kotlin/com/f0x1d/logfox/feature/crashes/list/presentation/CrashesState.kt create mode 100644 feature/crashes/list/src/main/kotlin/com/f0x1d/logfox/feature/crashes/list/presentation/CrashesViewModel.kt rename feature/crashes/{src/main/kotlin/com/f0x1d/logfox/feature/crashes/ui/fragment/list => list/src/main/kotlin/com/f0x1d/logfox/feature/crashes/list/presentation/ui}/CrashesFragment.kt (84%) rename feature/crashes/{ => list}/src/main/res/layout/dialog_sorting.xml (100%) rename feature/crashes/{ => list}/src/main/res/layout/fragment_crashes.xml (100%) rename feature/crashes/{ => list}/src/main/res/layout/item_sort.xml (100%) rename feature/crashes/{ => list}/src/main/res/menu/crashes_menu.xml (100%) delete mode 100644 feature/crashes/src/main/kotlin/com/f0x1d/logfox/feature/crashes/viewmodel/list/AppCrashesViewModel.kt delete mode 100644 feature/crashes/src/main/kotlin/com/f0x1d/logfox/feature/crashes/viewmodel/list/CrashesViewModel.kt rename feature/{filters-core => filters/api}/.gitignore (100%) rename feature/{logging-core => filters/api}/build.gradle.kts (52%) create mode 100644 feature/filters/api/src/main/kotlin/com/f0x1d/logfox/feature/filters/api/data/FiltersRepository.kt delete mode 100644 feature/filters/build.gradle.kts create mode 100644 feature/filters/edit/.gitignore create mode 100644 feature/filters/edit/build.gradle.kts rename feature/filters/{src/main/kotlin/com/f0x1d/logfox/feature/filters => edit/src/main/kotlin/com/f0x1d/logfox/feature/filters/edit}/di/EditFilterViewModelModule.kt (92%) create mode 100644 feature/filters/edit/src/main/kotlin/com/f0x1d/logfox/feature/filters/edit/presentation/EditFilterAction.kt create mode 100644 feature/filters/edit/src/main/kotlin/com/f0x1d/logfox/feature/filters/edit/presentation/EditFilterState.kt create mode 100644 feature/filters/edit/src/main/kotlin/com/f0x1d/logfox/feature/filters/edit/presentation/EditFilterViewModel.kt rename feature/filters/{src/main/kotlin/com/f0x1d/logfox/feature/filters/ui/fragment => edit/src/main/kotlin/com/f0x1d/logfox/feature/filters/edit/presentation/ui}/EditFilterFragment.kt (60%) rename feature/filters/{ => edit}/src/main/res/layout/fragment_edit_filter.xml (100%) rename feature/filters/{ => edit}/src/main/res/menu/edit_filter_menu.xml (89%) rename feature/filters/{ => impl}/.gitignore (100%) create mode 100644 feature/filters/impl/build.gradle.kts rename feature/{filters-core/src/main/kotlin/com/f0x1d/logfox/feature/filters/core/repository/FiltersRepository.kt => filters/impl/src/main/kotlin/com/f0x1d/logfox/feature/filters/impl/data/FiltersRepositoryImpl.kt} (79%) rename feature/{filters-core/src/main/kotlin/com/f0x1d/logfox/feature/filters/core => filters/impl/src/main/kotlin/com/f0x1d/logfox/feature/filters/impl}/di/RepositoriesModule.kt (62%) create mode 100644 feature/filters/list/.gitignore create mode 100644 feature/filters/list/build.gradle.kts create mode 100644 feature/filters/list/src/main/kotlin/com/f0x1d/logfox/feature/filters/list/presentation/FiltersAction.kt create mode 100644 feature/filters/list/src/main/kotlin/com/f0x1d/logfox/feature/filters/list/presentation/FiltersState.kt rename feature/filters/{src/main/kotlin/com/f0x1d/logfox/feature/filters/viewmodel => list/src/main/kotlin/com/f0x1d/logfox/feature/filters/list/presentation}/FiltersViewModel.kt (71%) create mode 100644 feature/filters/list/src/main/kotlin/com/f0x1d/logfox/feature/filters/list/presentation/adapter/FiltersAdapter.kt rename feature/filters/{src/main/kotlin/com/f0x1d/logfox/feature/filters => list/src/main/kotlin/com/f0x1d/logfox/feature/filters/list/presentation}/ui/fragment/FiltersFragment.kt (81%) rename feature/filters/{src/main/kotlin/com/f0x1d/logfox/feature/filters => list/src/main/kotlin/com/f0x1d/logfox/feature/filters/list/presentation}/ui/viewholder/FilterViewHolder.kt (90%) rename feature/filters/{ => list}/src/main/res/layout/fragment_filters.xml (100%) rename feature/filters/{ => list}/src/main/res/layout/item_filter.xml (100%) rename feature/filters/{ => list}/src/main/res/layout/placeholder_filters.xml (100%) rename feature/filters/{ => list}/src/main/res/menu/filters_menu.xml (100%) delete mode 100644 feature/filters/src/main/kotlin/com/f0x1d/logfox/feature/filters/adapter/FiltersAdapter.kt delete mode 100644 feature/filters/src/main/kotlin/com/f0x1d/logfox/feature/filters/viewmodel/EditFilterViewModel.kt delete mode 100644 feature/logging-core/src/main/kotlin/com/f0x1d/logfox/feature/logging/core/di/StoresModule.kt delete mode 100644 feature/logging-core/src/main/kotlin/com/f0x1d/logfox/feature/logging/core/repository/LoggingRepository.kt rename feature/{logging-core => logging/api}/.gitignore (100%) rename feature/{filters-core => logging/api}/build.gradle.kts (52%) create mode 100644 feature/logging/api/src/main/kotlin/com/f0x1d/logfox/feature/logging/api/data/LoggingRepository.kt create mode 100644 feature/logging/api/src/main/kotlin/com/f0x1d/logfox/feature/logging/api/data/LogsDataSource.kt create mode 100644 feature/logging/api/src/main/kotlin/com/f0x1d/logfox/feature/logging/api/data/QueryDataSource.kt create mode 100644 feature/logging/api/src/main/kotlin/com/f0x1d/logfox/feature/logging/api/data/SelectedLogLinesDataSource.kt rename feature/{logging-core/src/main/kotlin/com/f0x1d/logfox/feature/logging/core => logging/api/src/main/kotlin/com/f0x1d/logfox/feature/logging/api}/model/LogLinesExt.kt (97%) create mode 100644 feature/logging/api/src/main/kotlin/com/f0x1d/logfox/feature/logging/api/presentation/LoggingServiceDelegate.kt delete mode 100644 feature/logging/build.gradle.kts rename feature/{recordings-core => logging/extended-copy}/.gitignore (100%) create mode 100644 feature/logging/extended-copy/build.gradle.kts create mode 100644 feature/logging/extended-copy/src/main/kotlin/com/f0x1d/logfox/feature/logging/extended/copy/presentation/LogsExtendedCopyAction.kt create mode 100644 feature/logging/extended-copy/src/main/kotlin/com/f0x1d/logfox/feature/logging/extended/copy/presentation/LogsExtendedCopyState.kt create mode 100644 feature/logging/extended-copy/src/main/kotlin/com/f0x1d/logfox/feature/logging/extended/copy/presentation/LogsExtendedCopyViewModel.kt rename feature/logging/{src/main/kotlin/com/f0x1d/feature/logging/ui/fragment => extended-copy/src/main/kotlin/com/f0x1d/logfox/feature/logging/extended/copy/presentation/ui}/LogsExtendedCopyFragment.kt (50%) rename feature/logging/{ => extended-copy}/src/main/res/layout/fragment_logs_extended_copy.xml (100%) rename feature/{crashes => logging/impl}/.gitignore (100%) create mode 100644 feature/logging/impl/build.gradle.kts create mode 100644 feature/logging/impl/src/main/kotlin/com/f0x1d/logfox/feature/logging/impl/data/LoggingRepositoryImpl.kt rename feature/{logging-core/src/main/kotlin/com/f0x1d/logfox/feature/logging/core/store/LoggingStore.kt => logging/impl/src/main/kotlin/com/f0x1d/logfox/feature/logging/impl/data/LogsDataSourceImpl.kt} (64%) create mode 100644 feature/logging/impl/src/main/kotlin/com/f0x1d/logfox/feature/logging/impl/data/QueryDataSourceImpl.kt create mode 100644 feature/logging/impl/src/main/kotlin/com/f0x1d/logfox/feature/logging/impl/data/SelectedLogLinesDataSourceImpl.kt create mode 100644 feature/logging/impl/src/main/kotlin/com/f0x1d/logfox/feature/logging/impl/di/DataSourcesModule.kt rename feature/{logging-core/src/main/kotlin/com/f0x1d/logfox/feature/logging/core => logging/impl/src/main/kotlin/com/f0x1d/logfox/feature/logging/impl}/di/RepositoriesModule.kt (62%) rename feature/{recordings => logging/list}/.gitignore (100%) create mode 100644 feature/logging/list/build.gradle.kts rename feature/logging/{src/main/kotlin/com/f0x1d/feature/logging => list/src/main/kotlin/com/f0x1d/logfox/feature/logging/list}/di/LogsViewModelModule.kt (93%) create mode 100644 feature/logging/list/src/main/kotlin/com/f0x1d/logfox/feature/logging/list/presentation/LogsAction.kt create mode 100644 feature/logging/list/src/main/kotlin/com/f0x1d/logfox/feature/logging/list/presentation/LogsState.kt create mode 100644 feature/logging/list/src/main/kotlin/com/f0x1d/logfox/feature/logging/list/presentation/LogsViewModel.kt rename feature/logging/{src/main/kotlin/com/f0x1d/feature/logging/viewmodel => list/src/main/kotlin/com/f0x1d/logfox/feature/logging/list/presentation}/UriExt.kt (77%) rename feature/logging/{src/main/kotlin/com/f0x1d/feature/logging => list/src/main/kotlin/com/f0x1d/logfox/feature/logging/list/presentation}/adapter/LogsAdapter.kt (79%) rename feature/logging/{src/main/kotlin/com/f0x1d/feature/logging => list/src/main/kotlin/com/f0x1d/logfox/feature/logging/list/presentation}/ui/fragment/LogsFragment.kt (64%) rename feature/logging/{src/main/kotlin/com/f0x1d/feature/logging => list/src/main/kotlin/com/f0x1d/logfox/feature/logging/list/presentation}/ui/viewholder/LogViewHolder.kt (71%) rename feature/logging/{ => list}/src/main/res/layout/fragment_logs.xml (100%) rename feature/logging/{ => list}/src/main/res/layout/item_log.xml (100%) rename feature/logging/{ => list}/src/main/res/layout/placeholder_logs.xml (100%) rename feature/logging/{ => list}/src/main/res/menu/log_menu.xml (100%) rename feature/logging/{ => list}/src/main/res/menu/logs_menu.xml (100%) create mode 100644 feature/logging/search/.gitignore create mode 100644 feature/logging/search/build.gradle.kts create mode 100644 feature/logging/search/src/main/kotlin/com/f0x1d/logfox/feature/logging/search/presentation/SearchLogsAction.kt create mode 100644 feature/logging/search/src/main/kotlin/com/f0x1d/logfox/feature/logging/search/presentation/SearchLogsState.kt create mode 100644 feature/logging/search/src/main/kotlin/com/f0x1d/logfox/feature/logging/search/presentation/SearchLogsViewModel.kt rename feature/logging/{src/main/kotlin/com/f0x1d/feature/logging/ui/dialog/SearchBottomSheet.kt => search/src/main/kotlin/com/f0x1d/logfox/feature/logging/search/presentation/ui/SearchLogsBottomSheetFragment.kt} (50%) rename feature/logging/{ => search}/src/main/res/layout/sheet_search.xml (100%) create mode 100644 feature/logging/service/.gitignore create mode 100644 feature/logging/service/build.gradle.kts rename feature/logging/{ => service}/src/main/AndroidManifest.xml (85%) create mode 100644 feature/logging/service/src/main/kotlin/com/f0x1d/logfox/feature/logging/service/di/LoggingServiceDelegateModule.kt rename feature/logging/{src/main/kotlin/com/f0x1d/feature/logging/service => service/src/main/kotlin/com/f0x1d/logfox/feature/logging/service/presentation}/LoggingService.kt (84%) create mode 100644 feature/logging/service/src/main/kotlin/com/f0x1d/logfox/feature/logging/service/presentation/LoggingServiceDelegateImpl.kt rename feature/logging/{src/main/kotlin/com/f0x1d/feature/logging/service => service/src/main/kotlin/com/f0x1d/logfox/feature/logging/service/presentation}/MainActivityPendingIntentProvider.kt (66%) delete mode 100644 feature/logging/src/main/kotlin/com/f0x1d/feature/logging/viewmodel/LogsViewModel.kt delete mode 100644 feature/recordings-core/build.gradle.kts create mode 100644 feature/recordings/api/.gitignore create mode 100644 feature/recordings/api/build.gradle.kts create mode 100644 feature/recordings/api/src/main/kotlin/com/f0x1d/logfox/feature/recordings/api/data/RecordingController.kt create mode 100644 feature/recordings/api/src/main/kotlin/com/f0x1d/logfox/feature/recordings/api/data/RecordingNotificationController.kt create mode 100644 feature/recordings/api/src/main/kotlin/com/f0x1d/logfox/feature/recordings/api/data/RecordingsRepository.kt rename feature/{recordings-core/src/main/kotlin/com/f0x1d/logfox/feature/recordings/core/controller => recordings/api/src/main/kotlin/com/f0x1d/logfox/feature/recordings/api/data}/reader/RecordingReader.kt (97%) delete mode 100644 feature/recordings/build.gradle.kts create mode 100644 feature/recordings/details/.gitignore create mode 100644 feature/recordings/details/build.gradle.kts rename feature/recordings/{src/main/kotlin/com/f0x1d/logfox/feature/recordings/di/RecordingViewModelModule.kt => details/src/main/kotlin/com/f0x1d/logfox/feature/recordings/details/di/RecordingDetailsViewModelModule.kt} (91%) create mode 100644 feature/recordings/details/src/main/kotlin/com/f0x1d/logfox/feature/recordings/details/presentation/RecordingDetailsAction.kt create mode 100644 feature/recordings/details/src/main/kotlin/com/f0x1d/logfox/feature/recordings/details/presentation/RecordingDetailsState.kt rename feature/recordings/{src/main/kotlin/com/f0x1d/logfox/feature/recordings/viewmodel/RecordingViewModel.kt => details/src/main/kotlin/com/f0x1d/logfox/feature/recordings/details/presentation/RecordingDetailsViewModel.kt} (63%) rename feature/recordings/{src/main/kotlin/com/f0x1d/logfox/feature/recordings/ui/dialog/RecordingBottomSheet.kt => details/src/main/kotlin/com/f0x1d/logfox/feature/recordings/details/presentation/ui/RecordingDetailsBottomSheetFragment.kt} (56%) rename feature/recordings/{src/main/res/layout/sheet_recording.xml => details/src/main/res/layout/sheet_recording_details.xml} (100%) create mode 100644 feature/recordings/impl/.gitignore create mode 100644 feature/recordings/impl/build.gradle.kts rename feature/{recordings-core => recordings/impl}/src/main/AndroidManifest.xml (67%) rename feature/{recordings-core/src/main/kotlin/com/f0x1d/logfox/feature/recordings/core/controller/RecordingController.kt => recordings/impl/src/main/kotlin/com/f0x1d/logfox/feature/recordings/impl/data/RecordingControllerImpl.kt} (85%) rename feature/{recordings-core/src/main/kotlin/com/f0x1d/logfox/feature/recordings/core/controller/RecordingNotificationController.kt => recordings/impl/src/main/kotlin/com/f0x1d/logfox/feature/recordings/impl/data/RecordingNotificationControllerImpl.kt} (89%) rename feature/{recordings-core/src/main/kotlin/com/f0x1d/logfox/feature/recordings/core/repository/RecordingsRepository.kt => recordings/impl/src/main/kotlin/com/f0x1d/logfox/feature/recordings/impl/data/RecordingsRepositoryImpl.kt} (91%) rename feature/{recordings-core/src/main/kotlin/com/f0x1d/logfox/feature/recordings/core => recordings/impl/src/main/kotlin/com/f0x1d/logfox/feature/recordings/impl}/di/ControllersModule.kt (56%) rename feature/{recordings-core/src/main/kotlin/com/f0x1d/logfox/feature/recordings/core => recordings/impl/src/main/kotlin/com/f0x1d/logfox/feature/recordings/impl}/di/RepositoriesModule.kt (61%) rename feature/{recordings-core/src/main/kotlin/com/f0x1d/logfox/feature/recordings/core => recordings/impl/src/main/kotlin/com/f0x1d/logfox/feature/recordings/impl/presentation}/receiver/RecordingReceiver.kt (89%) create mode 100644 feature/recordings/list/.gitignore create mode 100644 feature/recordings/list/build.gradle.kts create mode 100644 feature/recordings/list/src/main/kotlin/com/f0x1d/logfox/feature/recordings/list/presentation/RecordingsAction.kt create mode 100644 feature/recordings/list/src/main/kotlin/com/f0x1d/logfox/feature/recordings/list/presentation/RecordingsState.kt create mode 100644 feature/recordings/list/src/main/kotlin/com/f0x1d/logfox/feature/recordings/list/presentation/RecordingsViewModel.kt create mode 100644 feature/recordings/list/src/main/kotlin/com/f0x1d/logfox/feature/recordings/list/presentation/adapter/RecordingsAdapter.kt rename feature/recordings/{src/main/kotlin/com/f0x1d/logfox/feature/recordings => list/src/main/kotlin/com/f0x1d/logfox/feature/recordings/list/presentation}/ui/fragment/RecordingsFragment.kt (77%) rename feature/recordings/{src/main/kotlin/com/f0x1d/logfox/feature/recordings => list/src/main/kotlin/com/f0x1d/logfox/feature/recordings/list/presentation}/ui/viewholder/RecordingViewHolder.kt (76%) rename feature/recordings/{ => list}/src/main/res/layout/fragment_recordings.xml (100%) rename feature/recordings/{ => list}/src/main/res/layout/item_recording.xml (100%) rename feature/recordings/{ => list}/src/main/res/layout/placeholder_recordings.xml (100%) rename feature/recordings/{ => list}/src/main/res/menu/recordings_menu.xml (100%) delete mode 100644 feature/recordings/src/main/kotlin/com/f0x1d/logfox/feature/recordings/adapter/RecordingsAdapter.kt delete mode 100644 feature/recordings/src/main/kotlin/com/f0x1d/logfox/feature/recordings/viewmodel/RecordingsViewModel.kt delete mode 100644 feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/LoggingServiceDelegate.kt rename feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/{ => presentation}/IntArrayExt.kt (68%) rename feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/{ => presentation}/ui/fragment/SettingsCrashesFragment.kt (74%) rename feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/{ => presentation}/ui/fragment/SettingsLinksFragment.kt (74%) rename feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/{ => presentation}/ui/fragment/SettingsMenuFragment.kt (77%) rename feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/{ => presentation}/ui/fragment/SettingsNotificationsFragment.kt (93%) rename feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/{ => presentation}/ui/fragment/SettingsServiceFragment.kt (90%) rename feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/{ => presentation}/ui/fragment/SettingsUIFragment.kt (97%) rename feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/{ => presentation}/ui/fragment/base/BasePreferenceFragment.kt (88%) create mode 100644 feature/setup/src/main/kotlin/com/f0x1d/logfox/feature/setup/presentation/SetupAction.kt create mode 100644 feature/setup/src/main/kotlin/com/f0x1d/logfox/feature/setup/presentation/SetupState.kt rename feature/setup/src/main/kotlin/com/f0x1d/logfox/feature/setup/{viewmodel => presentation}/SetupViewModel.kt (79%) create mode 100644 feature/setup/src/main/kotlin/com/f0x1d/logfox/feature/setup/presentation/ui/SetupFragment.kt rename feature/setup/src/main/kotlin/com/f0x1d/logfox/feature/setup/{ui/fragment/setup/compose/SetupScreenState.kt => presentation/ui/SetupScreenListener.kt} (74%) rename feature/setup/src/main/kotlin/com/f0x1d/logfox/feature/setup/{ui/fragment/setup => presentation/ui}/compose/SetupScreenContent.kt (93%) delete mode 100644 feature/setup/src/main/kotlin/com/f0x1d/logfox/feature/setup/ui/fragment/setup/SetupFragment.kt rename feature/setup/src/test/kotlin/com/f0x1d/logfox/{setup => feature/setup/presentation/ui}/compose/SetupScreenContentTest.kt (90%) create mode 100644 feature/setup/src/test/screenshots/com.f0x1d.logfox.feature.setup.presentation.ui.compose.SetupScreenContentTest.shouldOpenAdbDialogOnSetupScreenContent.png create mode 100644 feature/setup/src/test/screenshots/com.f0x1d.logfox.feature.setup.presentation.ui.compose.SetupScreenContentTest.shouldShowAdbDialogOnSetupScreenContent.png rename feature/setup/src/test/screenshots/{com.f0x1d.logfox.setup.compose.SetupScreenContentTest.shouldShowDarkSetupScreenContent.png => com.f0x1d.logfox.feature.setup.presentation.ui.compose.SetupScreenContentTest.shouldShowDarkSetupScreenContent.png} (94%) create mode 100644 feature/setup/src/test/screenshots/com.f0x1d.logfox.feature.setup.presentation.ui.compose.SetupScreenContentTest.shouldShowSetupScreenContent.png delete mode 100644 feature/setup/src/test/screenshots/com.f0x1d.logfox.setup.compose.SetupScreenContentTest.shouldOpenAdbDialogOnSetupScreenContent.png delete mode 100644 feature/setup/src/test/screenshots/com.f0x1d.logfox.setup.compose.SetupScreenContentTest.shouldShowAdbDialogOnSetupScreenContent.png delete mode 100644 feature/setup/src/test/screenshots/com.f0x1d.logfox.setup.compose.SetupScreenContentTest.shouldShowSetupScreenContent.png rename {feature/logging => shared}/.gitignore (100%) rename {data => shared}/build.gradle.kts (82%) rename {data => shared}/src/main/kotlin/com/f0x1d/logfox/model/Device.kt (100%) rename {data => shared}/src/main/kotlin/com/f0x1d/logfox/model/Identifiable.kt (90%) rename {data => shared}/src/main/kotlin/com/f0x1d/logfox/model/UIDS.kt (100%) rename {data => shared}/src/main/kotlin/com/f0x1d/logfox/model/exception/TerminalNotSupportedException.kt (100%) rename {data => shared}/src/main/kotlin/com/f0x1d/logfox/model/logline/LogLine.kt (84%) rename {data => shared}/src/main/kotlin/com/f0x1d/logfox/model/logline/LogLineExt.kt (87%) rename {data => shared}/src/main/kotlin/com/f0x1d/logfox/model/preferences/ShowLogValues.kt (100%) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 6d01f6fd..0b6a0042 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -9,19 +9,38 @@ android { defaultConfig { applicationId = logFoxPackageName - versionCode = 62 - versionName = "2.0.2" + versionCode = 63 + versionName = "2.0.3" } } dependencies { - implementation(projects.feature.crashes) - implementation(projects.feature.filters) - implementation(projects.feature.logging) - implementation(projects.feature.recordings) + implementation(projects.feature.appsPicker.api) + implementation(projects.feature.appsPicker.impl) + + implementation(projects.feature.crashes.appsList) + implementation(projects.feature.crashes.details) + implementation(projects.feature.crashes.impl) + implementation(projects.feature.crashes.list) + + implementation(projects.feature.filters.edit) + implementation(projects.feature.filters.impl) + implementation(projects.feature.filters.list) + + implementation(projects.feature.logging.extendedCopy) + implementation(projects.feature.logging.impl) + implementation(projects.feature.logging.list) + implementation(projects.feature.logging.search) + implementation(projects.feature.logging.service) + + implementation(projects.feature.recordings.details) + implementation(projects.feature.recordings.impl) + implementation(projects.feature.recordings.list) + implementation(projects.feature.settings) implementation(projects.feature.setup) + implementation(libs.timber) implementation(libs.viewpump) implementation(libs.coil) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index cc226962..474177c5 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -14,10 +14,11 @@ android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.LogFox" - android:localeConfig="@xml/locales_config"> + android:localeConfig="@xml/locales_config" + android:enableOnBackInvokedCallback="true"> @@ -29,7 +30,7 @@ { + ) : Fetcher.Factory { override fun create( - data: InstalledApp, + data: com.f0x1d.logfox.feature.apps.picker.InstalledApp, options: Options, imageLoader: ImageLoader, ): Fetcher = AppIconFetcher( diff --git a/app/src/main/kotlin/com/f0x1d/logfox/di/logs/MainActivityPendingIntentProviderModule.kt b/app/src/main/kotlin/com/f0x1d/logfox/di/logs/MainActivityPendingIntentProviderModule.kt index 2fcaa6ce..c0ffa0a0 100644 --- a/app/src/main/kotlin/com/f0x1d/logfox/di/logs/MainActivityPendingIntentProviderModule.kt +++ b/app/src/main/kotlin/com/f0x1d/logfox/di/logs/MainActivityPendingIntentProviderModule.kt @@ -2,9 +2,9 @@ package com.f0x1d.logfox.di.logs import android.app.PendingIntent import android.content.Context -import com.f0x1d.feature.logging.service.MainActivityPendingIntentProvider import com.f0x1d.logfox.arch.makeActivityPendingIntent -import com.f0x1d.logfox.ui.activity.MainActivity +import com.f0x1d.logfox.feature.logging.service.presentation.MainActivityPendingIntentProvider +import com.f0x1d.logfox.presentation.ui.activity.MainActivity import dagger.Binds import dagger.Module import dagger.hilt.InstallIn diff --git a/app/src/main/kotlin/com/f0x1d/logfox/di/settings/LoggingServiceDelegateModule.kt b/app/src/main/kotlin/com/f0x1d/logfox/di/settings/LoggingServiceDelegateModule.kt deleted file mode 100644 index 7269f5eb..00000000 --- a/app/src/main/kotlin/com/f0x1d/logfox/di/settings/LoggingServiceDelegateModule.kt +++ /dev/null @@ -1,30 +0,0 @@ -package com.f0x1d.logfox.di.settings - -import android.content.Context -import com.f0x1d.feature.logging.service.LoggingService -import com.f0x1d.logfox.arch.sendService -import com.f0x1d.logfox.feature.settings.LoggingServiceDelegate -import dagger.Binds -import dagger.Module -import dagger.hilt.InstallIn -import dagger.hilt.android.qualifiers.ApplicationContext -import dagger.hilt.components.SingletonComponent -import javax.inject.Inject - -@Module -@InstallIn(SingletonComponent::class) -internal interface LoggingServiceDelegateModule { - - @Binds - fun bindLoggingServiceDelegate( - loggingServiceDelegateImpl: LoggingServiceDelegateImpl, - ): LoggingServiceDelegate -} - -internal class LoggingServiceDelegateImpl @Inject constructor( - @ApplicationContext private val context: Context, -) : LoggingServiceDelegate { - override fun restartLogging() { - context.sendService(action = LoggingService.ACTION_RESTART_LOGGING) - } -} diff --git a/app/src/main/kotlin/com/f0x1d/logfox/presentation/MainAction.kt b/app/src/main/kotlin/com/f0x1d/logfox/presentation/MainAction.kt new file mode 100644 index 00000000..a96e6e12 --- /dev/null +++ b/app/src/main/kotlin/com/f0x1d/logfox/presentation/MainAction.kt @@ -0,0 +1,5 @@ +package com.f0x1d.logfox.presentation + +sealed interface MainAction { + data object OpenSetup : MainAction +} diff --git a/app/src/main/kotlin/com/f0x1d/logfox/presentation/MainState.kt b/app/src/main/kotlin/com/f0x1d/logfox/presentation/MainState.kt new file mode 100644 index 00000000..25255c9c --- /dev/null +++ b/app/src/main/kotlin/com/f0x1d/logfox/presentation/MainState.kt @@ -0,0 +1,3 @@ +package com.f0x1d.logfox.presentation + +data object MainState diff --git a/app/src/main/kotlin/com/f0x1d/logfox/viewmodel/MainViewModel.kt b/app/src/main/kotlin/com/f0x1d/logfox/presentation/MainViewModel.kt similarity index 77% rename from app/src/main/kotlin/com/f0x1d/logfox/viewmodel/MainViewModel.kt rename to app/src/main/kotlin/com/f0x1d/logfox/presentation/MainViewModel.kt index 3640e272..731cd453 100644 --- a/app/src/main/kotlin/com/f0x1d/logfox/viewmodel/MainViewModel.kt +++ b/app/src/main/kotlin/com/f0x1d/logfox/presentation/MainViewModel.kt @@ -1,12 +1,10 @@ -package com.f0x1d.logfox.viewmodel +package com.f0x1d.logfox.presentation import android.app.Application import android.content.Intent -import com.f0x1d.feature.logging.service.LoggingService import com.f0x1d.logfox.arch.hasPermissionToReadLogs import com.f0x1d.logfox.arch.startForegroundServiceAvailable import com.f0x1d.logfox.arch.viewmodel.BaseViewModel -import com.f0x1d.logfox.arch.viewmodel.Event import com.f0x1d.logfox.preferences.shared.AppPreferences import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject @@ -15,8 +13,10 @@ import javax.inject.Inject class MainViewModel @Inject constructor( private val appPreferences: AppPreferences, application: Application, -): BaseViewModel(application) { - +) : BaseViewModel( + initialStateProvider = { MainState }, + application = application, +) { var askedNotificationsPermission get() = appPreferences.askedNotificationsPermission set(value) { appPreferences.askedNotificationsPermission = value } @@ -29,16 +29,14 @@ class MainViewModel @Inject constructor( private fun load() { if (ctx.hasPermissionToReadLogs) { - Intent(ctx, LoggingService::class.java).let { + Intent(ctx, com.f0x1d.logfox.feature.logging.service.presentation.LoggingService::class.java).let { if (startForegroundServiceAvailable) ctx.startForegroundService(it) else ctx.startService(it) } } else { - sendEvent(OpenSetup) + sendAction(MainAction.OpenSetup) } } } - -data object OpenSetup : Event diff --git a/app/src/main/kotlin/com/f0x1d/logfox/ui/activity/MainActivity.kt b/app/src/main/kotlin/com/f0x1d/logfox/presentation/ui/activity/MainActivity.kt similarity index 92% rename from app/src/main/kotlin/com/f0x1d/logfox/ui/activity/MainActivity.kt rename to app/src/main/kotlin/com/f0x1d/logfox/presentation/ui/activity/MainActivity.kt index 95ee0055..468cc31b 100644 --- a/app/src/main/kotlin/com/f0x1d/logfox/ui/activity/MainActivity.kt +++ b/app/src/main/kotlin/com/f0x1d/logfox/presentation/ui/activity/MainActivity.kt @@ -1,4 +1,4 @@ -package com.f0x1d.logfox.ui.activity +package com.f0x1d.logfox.presentation.ui.activity import android.Manifest import android.annotation.SuppressLint @@ -23,22 +23,21 @@ import com.f0x1d.logfox.arch.contrastedNavBarAvailable import com.f0x1d.logfox.arch.gesturesAvailable import com.f0x1d.logfox.arch.hasNotificationsPermission import com.f0x1d.logfox.arch.isHorizontalOrientation -import com.f0x1d.logfox.arch.ui.activity.BaseViewModelActivity -import com.f0x1d.logfox.arch.viewmodel.Event +import com.f0x1d.logfox.arch.presentation.ui.activity.BaseActivity import com.f0x1d.logfox.databinding.ActivityMainBinding import com.f0x1d.logfox.navigation.Directions import com.f0x1d.logfox.navigation.NavGraphs +import com.f0x1d.logfox.presentation.MainAction +import com.f0x1d.logfox.presentation.MainViewModel import com.f0x1d.logfox.strings.Strings import com.f0x1d.logfox.ui.Icons -import com.f0x1d.logfox.viewmodel.MainViewModel -import com.f0x1d.logfox.viewmodel.OpenSetup import com.google.android.material.dialog.MaterialAlertDialogBuilder import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint -class MainActivity: BaseViewModelActivity(), NavController.OnDestinationChangedListener { +class MainActivity: BaseActivity(), NavController.OnDestinationChangedListener { - override val viewModel by viewModels() + private val viewModel by viewModels() private val navController by lazy { val navHostFragment = supportFragmentManager.findFragmentById( @@ -94,6 +93,12 @@ class MainActivity: BaseViewModelActivity(), viewModel.askedNotificationsPermission = true } + + viewModel.actions.collectWithLifecycle { action -> + when (action) { + is MainAction.OpenSetup -> navController.navigate(Directions.action_global_setupFragment) + } + } } private fun ActivityMainBinding.setupNavigation() { @@ -139,14 +144,6 @@ class MainActivity: BaseViewModelActivity(), } } - override fun onEvent(event: Event) { - super.onEvent(event) - - when (event) { - is OpenSetup -> navController.navigate(Directions.action_global_setupFragment) - } - } - override fun onDestinationChanged(controller: NavController, destination: NavDestination, arguments: Bundle?) { val barShown = when (destination.id) { Directions.setupFragment -> false diff --git a/app/src/main/kotlin/com/f0x1d/logfox/ui/activity/OpenFileActivity.kt b/app/src/main/kotlin/com/f0x1d/logfox/presentation/ui/activity/OpenFileActivity.kt similarity index 91% rename from app/src/main/kotlin/com/f0x1d/logfox/ui/activity/OpenFileActivity.kt rename to app/src/main/kotlin/com/f0x1d/logfox/presentation/ui/activity/OpenFileActivity.kt index ebf36e4a..580f7b58 100644 --- a/app/src/main/kotlin/com/f0x1d/logfox/ui/activity/OpenFileActivity.kt +++ b/app/src/main/kotlin/com/f0x1d/logfox/presentation/ui/activity/OpenFileActivity.kt @@ -1,4 +1,4 @@ -package com.f0x1d.logfox.ui.activity +package com.f0x1d.logfox.presentation.ui.activity import android.content.Intent import android.os.Bundle @@ -19,4 +19,4 @@ class OpenFileActivity: AppCompatActivity() { ) finish() } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/f0x1d/logfox/receiver/BootReceiver.kt b/app/src/main/kotlin/com/f0x1d/logfox/receiver/BootReceiver.kt index c26d6bf2..d32ce56b 100644 --- a/app/src/main/kotlin/com/f0x1d/logfox/receiver/BootReceiver.kt +++ b/app/src/main/kotlin/com/f0x1d/logfox/receiver/BootReceiver.kt @@ -3,10 +3,10 @@ package com.f0x1d.logfox.receiver import android.content.BroadcastReceiver import android.content.Context import android.content.Intent -import com.f0x1d.feature.logging.service.LoggingService import com.f0x1d.logfox.arch.hasPermissionToReadLogs import com.f0x1d.logfox.arch.startForegroundServiceAvailable import com.f0x1d.logfox.arch.toast +import com.f0x1d.logfox.feature.logging.service.presentation.LoggingService import com.f0x1d.logfox.preferences.shared.AppPreferences import com.f0x1d.logfox.strings.Strings import com.f0x1d.logfox.terminals.ShizukuTerminal @@ -26,7 +26,7 @@ class BootReceiver: BroadcastReceiver() { } if (context.hasPermissionToReadLogs) { - Intent(context, LoggingService::class.java).let { + Intent(context, com.f0x1d.logfox.feature.logging.service.presentation.LoggingService::class.java).let { if (startForegroundServiceAvailable) context.startForegroundService(it) else diff --git a/app/src/main/res/xml/file_paths.xml b/app/src/main/res/xml/file_paths.xml index bc0204d6..de518d82 100644 --- a/app/src/main/res/xml/file_paths.xml +++ b/app/src/main/res/xml/file_paths.xml @@ -1,5 +1,6 @@ + - \ No newline at end of file + diff --git a/build-logic/convention/src/main/kotlin/extensions/Dependencies.kt b/build-logic/convention/src/main/kotlin/extensions/Dependencies.kt index 4543fbc5..d7bf9106 100644 --- a/build-logic/convention/src/main/kotlin/extensions/Dependencies.kt +++ b/build-logic/convention/src/main/kotlin/extensions/Dependencies.kt @@ -5,7 +5,7 @@ import org.gradle.kotlin.dsl.DependencyHandlerScope import org.gradle.kotlin.dsl.project internal fun DependencyHandlerScope.coreDependencies(withCompose: Boolean = true) { - implementation(project(":data")) + implementation(project(":shared")) implementation(project(":strings")) implementation(project(":core:arch")) @@ -43,10 +43,7 @@ internal fun DependencyHandlerScope.androidTestImplementation(dependency: Any): ) internal fun DependencyHandlerScope.implementation(bundle: List): List = bundle.map { - add( - configurationName = "implementation", - dependencyNotation = it, - ) + implementation(it) } internal fun DependencyHandlerScope.ksp(dependency: Any): Dependency? = add( diff --git a/build-logic/convention/src/main/kotlin/main/AndroidCoreConventionPlugin.kt b/build-logic/convention/src/main/kotlin/main/AndroidCoreConventionPlugin.kt index 4bffc49b..61b66ddb 100644 --- a/build-logic/convention/src/main/kotlin/main/AndroidCoreConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/main/AndroidCoreConventionPlugin.kt @@ -15,9 +15,11 @@ class AndroidCoreConventionPlugin : Plugin { } dependencies { - implementation(project(":data")) + implementation(project(":shared")) implementation(project(":strings")) + implementation(library("timber")) + implementation(library("material")) implementation(bundle("androidx")) } diff --git a/build-logic/convention/src/main/kotlin/main/feature/AndroidFeatureConventionPlugin.kt b/build-logic/convention/src/main/kotlin/main/feature/AndroidFeatureConventionPlugin.kt index 78023b90..885772d2 100644 --- a/build-logic/convention/src/main/kotlin/main/feature/AndroidFeatureConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/main/feature/AndroidFeatureConventionPlugin.kt @@ -19,6 +19,7 @@ class AndroidFeatureConventionPlugin : Plugin { dependencies { coreDependencies(withCompose = false) + implementation(library("timber")) implementation(library("material")) implementation(bundle("androidx")) implementation(bundle("androidx-navigation")) diff --git a/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/logs/TimberFileTree.kt b/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/logs/TimberFileTree.kt new file mode 100644 index 00000000..44e95b37 --- /dev/null +++ b/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/logs/TimberFileTree.kt @@ -0,0 +1,45 @@ +package com.f0x1d.logfox.arch.logs + +import android.content.Context +import com.f0x1d.logfox.arch.di.IODispatcher +import dagger.hilt.android.qualifiers.ApplicationContext +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.channels.Channel.Factory.UNLIMITED +import kotlinx.coroutines.launch +import timber.log.Timber +import java.io.File +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class TimberFileTree @Inject constructor( + @ApplicationContext private val context: Context, + @IODispatcher private val ioDispatcher: CoroutineDispatcher, +) : Timber.DebugTree() { + + private val logsFile = context.timberLogFile.apply { delete() } + + private val channel = Channel(capacity = UNLIMITED) + private val scope = CoroutineScope(ioDispatcher) + + init { + scope.launch { + for (value in channel) { + logsFile.appendText( + text = value + "\n", + ) + } + } + } + + override fun log(priority: Int, tag: String?, message: String, t: Throwable?) { + val exception = t?.stackTraceToString()?.let { "\n$it" } ?: "" + val line = "${tag ?: "NO_TAG"}: $message" + exception + + channel.trySend(line) + } +} + +val Context.timberLogFile: File get() = File(filesDir, "timber.log") diff --git a/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/adapter/BaseListAdapter.kt b/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/presentation/adapter/BaseListAdapter.kt similarity index 91% rename from core/arch/src/main/kotlin/com/f0x1d/logfox/arch/adapter/BaseListAdapter.kt rename to core/arch/src/main/kotlin/com/f0x1d/logfox/arch/presentation/adapter/BaseListAdapter.kt index 803b70e6..227b95ce 100644 --- a/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/adapter/BaseListAdapter.kt +++ b/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/presentation/adapter/BaseListAdapter.kt @@ -1,4 +1,4 @@ -package com.f0x1d.logfox.arch.adapter +package com.f0x1d.logfox.arch.presentation.adapter import android.view.LayoutInflater import android.view.ViewGroup @@ -6,7 +6,7 @@ import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView import androidx.viewbinding.ViewBinding -import com.f0x1d.logfox.arch.ui.viewholder.BaseViewHolder +import com.f0x1d.logfox.arch.presentation.ui.viewholder.BaseViewHolder abstract class BaseListAdapter( diffUtil: DiffUtil.ItemCallback, diff --git a/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/ui/SnackbarExt.kt b/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/presentation/ui/SnackbarExt.kt similarity index 79% rename from core/arch/src/main/kotlin/com/f0x1d/logfox/arch/ui/SnackbarExt.kt rename to core/arch/src/main/kotlin/com/f0x1d/logfox/arch/presentation/ui/SnackbarExt.kt index e7ba1bee..0e8a8001 100644 --- a/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/ui/SnackbarExt.kt +++ b/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/presentation/ui/SnackbarExt.kt @@ -1,4 +1,4 @@ -package com.f0x1d.logfox.arch.ui +package com.f0x1d.logfox.arch.presentation.ui import android.view.View import com.google.android.material.snackbar.Snackbar diff --git a/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/ui/WindowExt.kt b/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/presentation/ui/WindowExt.kt similarity index 97% rename from core/arch/src/main/kotlin/com/f0x1d/logfox/arch/ui/WindowExt.kt rename to core/arch/src/main/kotlin/com/f0x1d/logfox/arch/presentation/ui/WindowExt.kt index 53d4ae87..ad3e62c7 100644 --- a/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/ui/WindowExt.kt +++ b/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/presentation/ui/WindowExt.kt @@ -1,4 +1,4 @@ -package com.f0x1d.logfox.arch.ui +package com.f0x1d.logfox.arch.presentation.ui import android.content.Context import android.graphics.Color diff --git a/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/ui/activity/BaseActivity.kt b/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/presentation/ui/activity/BaseActivity.kt similarity index 89% rename from core/arch/src/main/kotlin/com/f0x1d/logfox/arch/ui/activity/BaseActivity.kt rename to core/arch/src/main/kotlin/com/f0x1d/logfox/arch/presentation/ui/activity/BaseActivity.kt index 79c1edb2..5686279c 100644 --- a/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/ui/activity/BaseActivity.kt +++ b/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/presentation/ui/activity/BaseActivity.kt @@ -1,12 +1,12 @@ -package com.f0x1d.logfox.arch.ui.activity +package com.f0x1d.logfox.arch.presentation.ui.activity import android.content.Context import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import androidx.viewbinding.ViewBinding -import com.f0x1d.logfox.arch.ui.base.SimpleLifecycleOwner -import com.f0x1d.logfox.arch.ui.enableEdgeToEdge -import com.f0x1d.logfox.arch.ui.snackbar +import com.f0x1d.logfox.arch.presentation.ui.base.SimpleLifecycleOwner +import com.f0x1d.logfox.arch.presentation.ui.enableEdgeToEdge +import com.f0x1d.logfox.arch.presentation.ui.snackbar import dagger.hilt.EntryPoint import dagger.hilt.InstallIn import dagger.hilt.android.EntryPointAccessors diff --git a/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/ui/base/SimpleLifecycleOwner.kt b/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/presentation/ui/base/SimpleLifecycleOwner.kt similarity index 95% rename from core/arch/src/main/kotlin/com/f0x1d/logfox/arch/ui/base/SimpleLifecycleOwner.kt rename to core/arch/src/main/kotlin/com/f0x1d/logfox/arch/presentation/ui/base/SimpleLifecycleOwner.kt index 9259c03f..b1fc822a 100644 --- a/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/ui/base/SimpleLifecycleOwner.kt +++ b/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/presentation/ui/base/SimpleLifecycleOwner.kt @@ -1,4 +1,4 @@ -package com.f0x1d.logfox.arch.ui.base +package com.f0x1d.logfox.arch.presentation.ui.base import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleOwner diff --git a/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/ui/dialog/BaseBottomSheet.kt b/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/presentation/ui/dialog/BaseBottomSheetFragment.kt similarity index 85% rename from core/arch/src/main/kotlin/com/f0x1d/logfox/arch/ui/dialog/BaseBottomSheet.kt rename to core/arch/src/main/kotlin/com/f0x1d/logfox/arch/presentation/ui/dialog/BaseBottomSheetFragment.kt index 0cacad25..a3f99805 100644 --- a/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/ui/dialog/BaseBottomSheet.kt +++ b/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/presentation/ui/dialog/BaseBottomSheetFragment.kt @@ -1,4 +1,4 @@ -package com.f0x1d.logfox.arch.ui.dialog +package com.f0x1d.logfox.arch.presentation.ui.dialog import android.annotation.SuppressLint import android.app.Dialog @@ -7,13 +7,14 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.viewbinding.ViewBinding -import com.f0x1d.logfox.arch.ui.base.SimpleFragmentLifecycleOwner -import com.f0x1d.logfox.arch.ui.enableEdgeToEdge +import com.f0x1d.logfox.arch.presentation.ui.base.SimpleFragmentLifecycleOwner +import com.f0x1d.logfox.arch.presentation.ui.enableEdgeToEdge import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialogFragment -abstract class BaseBottomSheet: BottomSheetDialogFragment(), SimpleFragmentLifecycleOwner { +abstract class BaseBottomSheetFragment: BottomSheetDialogFragment(), + SimpleFragmentLifecycleOwner { private var mutableBinding: T? = null protected val binding: T get() = mutableBinding!! diff --git a/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/ui/fragment/BaseFragment.kt b/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/presentation/ui/fragment/BaseFragment.kt similarity index 89% rename from core/arch/src/main/kotlin/com/f0x1d/logfox/arch/ui/fragment/BaseFragment.kt rename to core/arch/src/main/kotlin/com/f0x1d/logfox/arch/presentation/ui/fragment/BaseFragment.kt index b5dd7197..b29c989b 100644 --- a/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/ui/fragment/BaseFragment.kt +++ b/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/presentation/ui/fragment/BaseFragment.kt @@ -1,4 +1,4 @@ -package com.f0x1d.logfox.arch.ui.fragment +package com.f0x1d.logfox.arch.presentation.ui.fragment import android.content.res.Configuration import android.os.Bundle @@ -7,8 +7,8 @@ import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.viewbinding.ViewBinding -import com.f0x1d.logfox.arch.ui.base.SimpleFragmentLifecycleOwner -import com.f0x1d.logfox.arch.ui.snackbar +import com.f0x1d.logfox.arch.presentation.ui.base.SimpleFragmentLifecycleOwner +import com.f0x1d.logfox.arch.presentation.ui.snackbar import dev.chrisbanes.insetter.applyInsetter abstract class BaseFragment: Fragment(), SimpleFragmentLifecycleOwner { diff --git a/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/ui/fragment/compose/BaseComposeFragment.kt b/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/presentation/ui/fragment/compose/BaseComposeFragment.kt similarity index 70% rename from core/arch/src/main/kotlin/com/f0x1d/logfox/arch/ui/fragment/compose/BaseComposeFragment.kt rename to core/arch/src/main/kotlin/com/f0x1d/logfox/arch/presentation/ui/fragment/compose/BaseComposeFragment.kt index 16301ef9..9d803276 100644 --- a/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/ui/fragment/compose/BaseComposeFragment.kt +++ b/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/presentation/ui/fragment/compose/BaseComposeFragment.kt @@ -1,4 +1,4 @@ -package com.f0x1d.logfox.arch.ui.fragment.compose +package com.f0x1d.logfox.arch.presentation.ui.fragment.compose import android.os.Bundle import android.view.LayoutInflater @@ -9,7 +9,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.platform.ComposeView import androidx.compose.ui.platform.ViewCompositionStrategy import com.f0x1d.logfox.arch.databinding.FragmentComposeBinding -import com.f0x1d.logfox.arch.ui.fragment.BaseFragment +import com.f0x1d.logfox.arch.presentation.ui.fragment.BaseFragment abstract class BaseComposeFragment : BaseFragment() { @@ -25,11 +25,11 @@ abstract class BaseComposeFragment : BaseFragment() { @Composable abstract fun Content() -} -internal fun ComposeView.setup(content: @Composable () -> Unit) { - consumeWindowInsets = false - setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed) + private fun ComposeView.setup(content: @Composable () -> Unit) { + consumeWindowInsets = false + setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed) - setContent(content) + setContent(content) + } } diff --git a/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/ui/viewholder/BaseViewHolder.kt b/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/presentation/ui/viewholder/BaseViewHolder.kt similarity index 87% rename from core/arch/src/main/kotlin/com/f0x1d/logfox/arch/ui/viewholder/BaseViewHolder.kt rename to core/arch/src/main/kotlin/com/f0x1d/logfox/arch/presentation/ui/viewholder/BaseViewHolder.kt index 9d02d816..d9fd8724 100644 --- a/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/ui/viewholder/BaseViewHolder.kt +++ b/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/presentation/ui/viewholder/BaseViewHolder.kt @@ -1,8 +1,8 @@ -package com.f0x1d.logfox.arch.ui.viewholder +package com.f0x1d.logfox.arch.presentation.ui.viewholder import androidx.recyclerview.widget.RecyclerView import androidx.viewbinding.ViewBinding -import com.f0x1d.logfox.arch.adapter.BaseListAdapter +import com.f0x1d.logfox.arch.presentation.adapter.BaseListAdapter abstract class BaseViewHolder( protected val binding: D diff --git a/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/repository/BaseRepository.kt b/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/repository/BaseRepository.kt deleted file mode 100644 index 17b33596..00000000 --- a/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/repository/BaseRepository.kt +++ /dev/null @@ -1,3 +0,0 @@ -package com.f0x1d.logfox.arch.repository - -abstract class BaseRepository diff --git a/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/ui/activity/BaseViewModelActivity.kt b/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/ui/activity/BaseViewModelActivity.kt deleted file mode 100644 index 4fb01589..00000000 --- a/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/ui/activity/BaseViewModelActivity.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.f0x1d.logfox.arch.ui.activity - -import android.os.Bundle -import androidx.viewbinding.ViewBinding -import com.f0x1d.logfox.arch.viewmodel.BaseViewModel -import com.f0x1d.logfox.arch.viewmodel.Event -import com.f0x1d.logfox.arch.viewmodel.ShowSnackbar - -abstract class BaseViewModelActivity: BaseActivity() { - - abstract val viewModel: T - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - - viewModel.eventsFlow.collectWithLifecycle(collector = ::onEvent) - } - - open fun onEvent(event: Event) { - when (event) { - is ShowSnackbar -> snackbar(event.text) - } - } -} diff --git a/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/ui/dialog/BaseViewModelBottomSheet.kt b/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/ui/dialog/BaseViewModelBottomSheet.kt deleted file mode 100644 index f260ea79..00000000 --- a/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/ui/dialog/BaseViewModelBottomSheet.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.f0x1d.logfox.arch.ui.dialog - -import android.os.Bundle -import android.view.View -import androidx.viewbinding.ViewBinding -import com.f0x1d.logfox.arch.viewmodel.BaseViewModel -import com.f0x1d.logfox.arch.viewmodel.Event - -abstract class BaseViewModelBottomSheet: BaseBottomSheet() { - - abstract val viewModel: T - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - viewModel.eventsFlow.collectWithLifecycle(collector = ::onEvent) - } - - open fun onEvent(event: Event) = Unit -} diff --git a/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/ui/fragment/BaseViewModelFragment.kt b/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/ui/fragment/BaseViewModelFragment.kt deleted file mode 100644 index af4e719c..00000000 --- a/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/ui/fragment/BaseViewModelFragment.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.f0x1d.logfox.arch.ui.fragment - -import android.os.Bundle -import android.view.View -import androidx.viewbinding.ViewBinding -import com.f0x1d.logfox.arch.viewmodel.BaseViewModel -import com.f0x1d.logfox.arch.viewmodel.Event -import com.f0x1d.logfox.arch.viewmodel.ShowSnackbar - -abstract class BaseViewModelFragment: BaseFragment() { - - abstract val viewModel: T - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - viewModel.eventsFlow.collectWithLifecycle(collector = ::onEvent) - } - - open fun onEvent(event: Event) { - when (event) { - is ShowSnackbar -> snackbar(event.text) - } - } -} diff --git a/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/ui/fragment/compose/BaseComposeViewModelFragment.kt b/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/ui/fragment/compose/BaseComposeViewModelFragment.kt deleted file mode 100644 index c4b9e94a..00000000 --- a/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/ui/fragment/compose/BaseComposeViewModelFragment.kt +++ /dev/null @@ -1,37 +0,0 @@ -package com.f0x1d.logfox.arch.ui.fragment.compose - -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import androidx.compose.runtime.Composable -import com.f0x1d.logfox.arch.databinding.FragmentComposeBinding -import com.f0x1d.logfox.arch.ui.fragment.BaseViewModelFragment -import com.f0x1d.logfox.arch.ui.snackbar -import com.f0x1d.logfox.arch.viewmodel.BaseViewModel -import com.google.android.material.snackbar.Snackbar -import dev.chrisbanes.insetter.applyInsetter - -abstract class BaseComposeViewModelFragment : BaseViewModelFragment() { - - override fun inflateBinding( - inflater: LayoutInflater, - container: ViewGroup?, - ) = FragmentComposeBinding.inflate(inflater, container, false) - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - binding.composeView.setup { Content() } - } - - override fun snackbar(text: String): Snackbar = requireView().snackbar(text).apply { - view.applyInsetter { - type(navigationBars = true) { - margin() - } - } - } - - @Composable - abstract fun Content() -} diff --git a/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/viewmodel/BaseStateViewModel.kt b/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/viewmodel/BaseStateViewModel.kt deleted file mode 100644 index da539adb..00000000 --- a/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/viewmodel/BaseStateViewModel.kt +++ /dev/null @@ -1,18 +0,0 @@ -package com.f0x1d.logfox.arch.viewmodel - -import android.app.Application -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.flow.update - -abstract class BaseStateViewModel( - initialStateProvider: () -> T, - application: Application, -) : BaseViewModel(application) { - - private val mutableUiState = MutableStateFlow(initialStateProvider()) - val uiState = mutableUiState.asStateFlow() - val currentState: T = uiState.value - - protected fun state(block: T.() -> T) = mutableUiState.update(block) -} diff --git a/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/viewmodel/BaseViewModel.kt b/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/viewmodel/BaseViewModel.kt index 496497b2..f2ec8880 100644 --- a/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/viewmodel/BaseViewModel.kt +++ b/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/viewmodel/BaseViewModel.kt @@ -4,28 +4,43 @@ import android.app.Application import android.content.Context import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.viewModelScope -import com.f0x1d.logfox.strings.Strings import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.receiveAsFlow +import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import kotlin.coroutines.CoroutineContext -abstract class BaseViewModel( +abstract class BaseViewModel( + initialStateProvider: () -> S, application: Application, ) : AndroidViewModel(application) { + val state: StateFlow get() = mutableState.asStateFlow() + val actions: Flow get() = actionsChannel.receiveAsFlow() - private val eventsChannel = Channel(capacity = Channel.BUFFERED) - val eventsFlow = eventsChannel.receiveAsFlow() + val currentState: S get() = mutableState.value protected val ctx: Context get() = getApplication() + private val mutableState = MutableStateFlow(initialStateProvider()) + private val actionsChannel = Channel(capacity = Channel.UNLIMITED) + + protected fun reduce(block: S.() -> S) = mutableState.update(block) + + protected fun sendAction(action: A) { + actionsChannel.trySend(action) + } + protected fun launchCatching( context: CoroutineContext = Dispatchers.Main, - errorBlock: suspend CoroutineScope.() -> Unit = {}, + errorBlock: suspend CoroutineScope.() -> Unit = { }, block: suspend CoroutineScope.() -> Unit, ) = viewModelScope.launch(context) { try { @@ -38,17 +53,6 @@ abstract class BaseViewModel( errorBlock(this) e.printStackTrace() - - snackbar(ctx.getString(Strings.error, e.localizedMessage)) - } - } - - protected fun snackbar(id: Int) = snackbar(ctx.getString(id)) - protected fun snackbar(text: String) = sendEvent(ShowSnackbar(text)) - - protected fun sendEvent(event: Event) { - viewModelScope.launch { - eventsChannel.send(event) } } } diff --git a/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/viewmodel/Event.kt b/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/viewmodel/Event.kt deleted file mode 100644 index 43890554..00000000 --- a/core/arch/src/main/kotlin/com/f0x1d/logfox/arch/viewmodel/Event.kt +++ /dev/null @@ -1,7 +0,0 @@ -package com.f0x1d.logfox.arch.viewmodel - -interface Event - -data class ShowSnackbar( - val text: String, -) : Event diff --git a/core/navigation/src/main/res/navigation/crashes.xml b/core/navigation/src/main/res/navigation/crashes.xml index 0e44bf32..4b1a537c 100644 --- a/core/navigation/src/main/res/navigation/crashes.xml +++ b/core/navigation/src/main/res/navigation/crashes.xml @@ -6,7 +6,7 @@ diff --git a/core/navigation/src/main/res/navigation/logs.xml b/core/navigation/src/main/res/navigation/logs.xml index 464a692c..b9e15b91 100644 --- a/core/navigation/src/main/res/navigation/logs.xml +++ b/core/navigation/src/main/res/navigation/logs.xml @@ -6,7 +6,7 @@ diff --git a/core/navigation/src/main/res/navigation/nav_graph.xml b/core/navigation/src/main/res/navigation/nav_graph.xml index 7ea2c2de..7feb99de 100644 --- a/core/navigation/src/main/res/navigation/nav_graph.xml +++ b/core/navigation/src/main/res/navigation/nav_graph.xml @@ -11,7 +11,7 @@ diff --git a/core/terminals/src/main/aidl/com/f0x1d/logfox/IUserService.aidl b/core/terminals/src/main/aidl/com/f0x1d/logfox/IUserService.aidl index 3e0b6e52..5edecda9 100644 --- a/core/terminals/src/main/aidl/com/f0x1d/logfox/IUserService.aidl +++ b/core/terminals/src/main/aidl/com/f0x1d/logfox/IUserService.aidl @@ -1,6 +1,6 @@ package com.f0x1d.logfox; -import com.f0x1d.logfox.model.terminal.TerminalResult; +import com.f0x1d.logfox.models.TerminalResult; interface IUserService { void destroy() = 16777114; @@ -15,4 +15,4 @@ interface IUserService { ParcelFileDescriptor processInput(long processId) = 6; void destroyProcess(long processId) = 7; -} \ No newline at end of file +} diff --git a/core/terminals/src/main/aidl/com/f0x1d/logfox/model/terminal/TerminalResult.aidl b/core/terminals/src/main/aidl/com/f0x1d/logfox/model/terminal/TerminalResult.aidl deleted file mode 100644 index a1423c76..00000000 --- a/core/terminals/src/main/aidl/com/f0x1d/logfox/model/terminal/TerminalResult.aidl +++ /dev/null @@ -1,3 +0,0 @@ -package com.f0x1d.logfox.model.terminal; - -parcelable TerminalResult; \ No newline at end of file diff --git a/core/terminals/src/main/aidl/com/f0x1d/logfox/models/TerminalResult.aidl b/core/terminals/src/main/aidl/com/f0x1d/logfox/models/TerminalResult.aidl new file mode 100644 index 00000000..3cebf984 --- /dev/null +++ b/core/terminals/src/main/aidl/com/f0x1d/logfox/models/TerminalResult.aidl @@ -0,0 +1,3 @@ +package com.f0x1d.logfox.models; + +parcelable TerminalResult; diff --git a/data/src/main/kotlin/com/f0x1d/logfox/model/terminal/TerminalProcess.kt b/core/terminals/src/main/kotlin/com/f0x1d/logfox/models/TerminalProcess.kt similarity index 83% rename from data/src/main/kotlin/com/f0x1d/logfox/model/terminal/TerminalProcess.kt rename to core/terminals/src/main/kotlin/com/f0x1d/logfox/models/TerminalProcess.kt index 4b5a6c11..7afce199 100644 --- a/data/src/main/kotlin/com/f0x1d/logfox/model/terminal/TerminalProcess.kt +++ b/core/terminals/src/main/kotlin/com/f0x1d/logfox/models/TerminalProcess.kt @@ -1,4 +1,4 @@ -package com.f0x1d.logfox.model.terminal +package com.f0x1d.logfox.models import java.io.InputStream import java.io.OutputStream diff --git a/data/src/main/kotlin/com/f0x1d/logfox/model/terminal/TerminalResult.kt b/core/terminals/src/main/kotlin/com/f0x1d/logfox/models/TerminalResult.kt similarity index 86% rename from data/src/main/kotlin/com/f0x1d/logfox/model/terminal/TerminalResult.kt rename to core/terminals/src/main/kotlin/com/f0x1d/logfox/models/TerminalResult.kt index e69aa2c4..ee3409d0 100644 --- a/data/src/main/kotlin/com/f0x1d/logfox/model/terminal/TerminalResult.kt +++ b/core/terminals/src/main/kotlin/com/f0x1d/logfox/models/TerminalResult.kt @@ -1,4 +1,4 @@ -package com.f0x1d.logfox.model.terminal +package com.f0x1d.logfox.models import android.os.Parcelable import kotlinx.parcelize.Parcelize @@ -10,4 +10,4 @@ data class TerminalResult( val errorOutput: String = "" ): Parcelable { val isSuccessful get() = exitCode == 0 -} \ No newline at end of file +} diff --git a/core/terminals/src/main/kotlin/com/f0x1d/logfox/service/UserService.kt b/core/terminals/src/main/kotlin/com/f0x1d/logfox/service/UserService.kt index 248995c7..02a48523 100644 --- a/core/terminals/src/main/kotlin/com/f0x1d/logfox/service/UserService.kt +++ b/core/terminals/src/main/kotlin/com/f0x1d/logfox/service/UserService.kt @@ -6,7 +6,7 @@ import android.os.ParcelFileDescriptor.AutoCloseInputStream import android.os.ParcelFileDescriptor.AutoCloseOutputStream import androidx.annotation.Keep import com.f0x1d.logfox.IUserService -import com.f0x1d.logfox.model.terminal.TerminalResult +import com.f0x1d.logfox.models.TerminalResult import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob @@ -20,7 +20,7 @@ import java.io.InputStream import java.io.OutputStream import kotlin.system.exitProcess -class UserService(): IUserService.Stub() { +class UserService() : IUserService.Stub() { private val serviceScopeJob = SupervisorJob() private val serviceScope = CoroutineScope(Dispatchers.IO + serviceScopeJob) @@ -31,7 +31,7 @@ class UserService(): IUserService.Stub() { // Needed for shizuku v13 @Suppress("UNUSED_PARAMETER") @Keep - constructor(context: Context): this() + constructor(context: Context) : this() override fun destroy() { serviceScope.cancel() diff --git a/core/terminals/src/main/kotlin/com/f0x1d/logfox/terminals/DefaultTerminal.kt b/core/terminals/src/main/kotlin/com/f0x1d/logfox/terminals/DefaultTerminal.kt index b54b319f..bc039c31 100644 --- a/core/terminals/src/main/kotlin/com/f0x1d/logfox/terminals/DefaultTerminal.kt +++ b/core/terminals/src/main/kotlin/com/f0x1d/logfox/terminals/DefaultTerminal.kt @@ -1,8 +1,8 @@ package com.f0x1d.logfox.terminals import com.f0x1d.logfox.arch.di.IODispatcher -import com.f0x1d.logfox.model.terminal.TerminalProcess -import com.f0x1d.logfox.model.terminal.TerminalResult +import com.f0x1d.logfox.models.TerminalProcess +import com.f0x1d.logfox.models.TerminalResult import com.f0x1d.logfox.terminals.base.Terminal import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.async diff --git a/core/terminals/src/main/kotlin/com/f0x1d/logfox/terminals/RootTerminal.kt b/core/terminals/src/main/kotlin/com/f0x1d/logfox/terminals/RootTerminal.kt index 7be5716b..7b4af7ba 100644 --- a/core/terminals/src/main/kotlin/com/f0x1d/logfox/terminals/RootTerminal.kt +++ b/core/terminals/src/main/kotlin/com/f0x1d/logfox/terminals/RootTerminal.kt @@ -1,8 +1,8 @@ package com.f0x1d.logfox.terminals import com.f0x1d.logfox.arch.di.IODispatcher -import com.f0x1d.logfox.model.terminal.TerminalProcess -import com.f0x1d.logfox.model.terminal.TerminalResult +import com.f0x1d.logfox.models.TerminalProcess +import com.f0x1d.logfox.models.TerminalResult import com.f0x1d.logfox.terminals.base.Terminal import com.topjohnwu.superuser.Shell import kotlinx.coroutines.CoroutineDispatcher diff --git a/core/terminals/src/main/kotlin/com/f0x1d/logfox/terminals/ShizukuTerminal.kt b/core/terminals/src/main/kotlin/com/f0x1d/logfox/terminals/ShizukuTerminal.kt index 2d25681a..35d734a7 100644 --- a/core/terminals/src/main/kotlin/com/f0x1d/logfox/terminals/ShizukuTerminal.kt +++ b/core/terminals/src/main/kotlin/com/f0x1d/logfox/terminals/ShizukuTerminal.kt @@ -9,8 +9,8 @@ import android.os.ParcelFileDescriptor.AutoCloseInputStream import android.os.ParcelFileDescriptor.AutoCloseOutputStream import com.f0x1d.logfox.IUserService import com.f0x1d.logfox.arch.di.IODispatcher -import com.f0x1d.logfox.model.terminal.TerminalProcess -import com.f0x1d.logfox.model.terminal.TerminalResult +import com.f0x1d.logfox.models.TerminalProcess +import com.f0x1d.logfox.models.TerminalResult import com.f0x1d.logfox.service.UserService import com.f0x1d.logfox.strings.Strings import com.f0x1d.logfox.terminals.base.Terminal diff --git a/core/terminals/src/main/kotlin/com/f0x1d/logfox/terminals/base/Terminal.kt b/core/terminals/src/main/kotlin/com/f0x1d/logfox/terminals/base/Terminal.kt index e3fd00a0..b13b2930 100644 --- a/core/terminals/src/main/kotlin/com/f0x1d/logfox/terminals/base/Terminal.kt +++ b/core/terminals/src/main/kotlin/com/f0x1d/logfox/terminals/base/Terminal.kt @@ -1,7 +1,7 @@ package com.f0x1d.logfox.terminals.base -import com.f0x1d.logfox.model.terminal.TerminalProcess -import com.f0x1d.logfox.model.terminal.TerminalResult +import com.f0x1d.logfox.models.TerminalProcess +import com.f0x1d.logfox.models.TerminalResult interface Terminal { val title: Int diff --git a/feature/apps-picker/api/.gitignore b/feature/apps-picker/api/.gitignore new file mode 100644 index 00000000..42afabfd --- /dev/null +++ b/feature/apps-picker/api/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/feature/apps-picker/api/build.gradle.kts b/feature/apps-picker/api/build.gradle.kts new file mode 100644 index 00000000..b1e5bd81 --- /dev/null +++ b/feature/apps-picker/api/build.gradle.kts @@ -0,0 +1,9 @@ +plugins { + id("logfox.android.feature") +} + +android.namespace = "com.f0x1d.logfox.feature.apps.picker.api" + +dependencies { + +} diff --git a/feature/apps-picker/api/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/AppsPickerResultHandler.kt b/feature/apps-picker/api/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/AppsPickerResultHandler.kt new file mode 100644 index 00000000..e3926325 --- /dev/null +++ b/feature/apps-picker/api/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/AppsPickerResultHandler.kt @@ -0,0 +1,18 @@ +package com.f0x1d.logfox.feature.apps.picker + +import android.content.Context +import com.f0x1d.logfox.strings.Strings +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flowOf + +interface AppsPickerResultHandler { + val supportsMultiplySelection: Boolean get() = false + val checkedAppPackageNames: Flow> get() = flowOf(emptySet()) + + fun providePickerTopAppBarTitle(context: Context) = context.getString(Strings.apps) + + fun onAppChecked(app: InstalledApp, checked: Boolean) = Unit + + // pass true to close fragment + fun onAppSelected(app: InstalledApp): Boolean = false +} diff --git a/data/src/main/kotlin/com/f0x1d/logfox/model/InstalledApp.kt b/feature/apps-picker/api/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/InstalledApp.kt similarity index 61% rename from data/src/main/kotlin/com/f0x1d/logfox/model/InstalledApp.kt rename to feature/apps-picker/api/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/InstalledApp.kt index b77e3ea0..69680342 100644 --- a/data/src/main/kotlin/com/f0x1d/logfox/model/InstalledApp.kt +++ b/feature/apps-picker/api/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/InstalledApp.kt @@ -1,4 +1,6 @@ -package com.f0x1d.logfox.model +package com.f0x1d.logfox.feature.apps.picker + +import com.f0x1d.logfox.model.Identifiable data class InstalledApp( val title: String, diff --git a/data/.gitignore b/feature/apps-picker/impl/.gitignore similarity index 100% rename from data/.gitignore rename to feature/apps-picker/impl/.gitignore diff --git a/feature/apps-picker/build.gradle.kts b/feature/apps-picker/impl/build.gradle.kts similarity index 76% rename from feature/apps-picker/build.gradle.kts rename to feature/apps-picker/impl/build.gradle.kts index e215e003..8037462f 100644 --- a/feature/apps-picker/build.gradle.kts +++ b/feature/apps-picker/impl/build.gradle.kts @@ -5,5 +5,7 @@ plugins { android.namespace = "com.f0x1d.logfox.feature.apps.picker" dependencies { + implementation(projects.feature.appsPicker.api) + implementation(libs.coil.compose) } diff --git a/feature/apps-picker/impl/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/presentation/AppsPickerAction.kt b/feature/apps-picker/impl/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/presentation/AppsPickerAction.kt new file mode 100644 index 00000000..a45f1179 --- /dev/null +++ b/feature/apps-picker/impl/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/presentation/AppsPickerAction.kt @@ -0,0 +1,3 @@ +package com.f0x1d.logfox.feature.apps.picker.presentation + +sealed interface AppsPickerAction diff --git a/feature/apps-picker/impl/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/presentation/AppsPickerState.kt b/feature/apps-picker/impl/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/presentation/AppsPickerState.kt new file mode 100644 index 00000000..f82864e7 --- /dev/null +++ b/feature/apps-picker/impl/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/presentation/AppsPickerState.kt @@ -0,0 +1,18 @@ +package com.f0x1d.logfox.feature.apps.picker.presentation + +import com.f0x1d.logfox.feature.apps.picker.InstalledApp +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.ImmutableSet +import kotlinx.collections.immutable.persistentListOf +import kotlinx.collections.immutable.persistentSetOf + +data class AppsPickerState( + val topBarTitle: String = "Apps", + val apps: ImmutableList = persistentListOf(), + val checkedAppPackageNames: ImmutableSet = persistentSetOf(), + val searchedApps: ImmutableList = persistentListOf(), + val multiplySelectionEnabled: Boolean = true, + val isLoading: Boolean = true, + val searchActive: Boolean = false, + val query: String = "", +) diff --git a/feature/apps-picker/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/viewmodel/AppsPickerViewModel.kt b/feature/apps-picker/impl/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/presentation/AppsPickerViewModel.kt similarity index 63% rename from feature/apps-picker/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/viewmodel/AppsPickerViewModel.kt rename to feature/apps-picker/impl/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/presentation/AppsPickerViewModel.kt index ddbca2a3..f1ea3c64 100644 --- a/feature/apps-picker/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/viewmodel/AppsPickerViewModel.kt +++ b/feature/apps-picker/impl/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/presentation/AppsPickerViewModel.kt @@ -1,36 +1,31 @@ -package com.f0x1d.logfox.feature.apps.picker.viewmodel +package com.f0x1d.logfox.feature.apps.picker.presentation import android.app.Application import com.f0x1d.logfox.arch.di.DefaultDispatcher -import com.f0x1d.logfox.arch.viewmodel.BaseStateViewModel -import com.f0x1d.logfox.feature.apps.picker.ui.fragment.picker.compose.AppsPickerScreenState -import com.f0x1d.logfox.model.InstalledApp +import com.f0x1d.logfox.arch.viewmodel.BaseViewModel +import com.f0x1d.logfox.feature.apps.picker.InstalledApp import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.update import javax.inject.Inject @HiltViewModel class AppsPickerViewModel @Inject constructor( @DefaultDispatcher private val defaultDispatcher: CoroutineDispatcher, application: Application, -): BaseStateViewModel( - initialStateProvider = { AppsPickerScreenState() }, +): BaseViewModel( + initialStateProvider = { AppsPickerState() }, application = application, ) { - - private val query = MutableStateFlow("") - init { load() } - fun performBackAction(popBackStack: () -> Unit) = state { + fun performBackAction(popBackStack: () -> Unit) = reduce { if (searchActive) { copy(searchActive = false) } else { @@ -39,14 +34,12 @@ class AppsPickerViewModel @Inject constructor( } } - fun changeSearchActive(active: Boolean) = state { + fun changeSearchActive(active: Boolean) = reduce { copy(searchActive = active) } - fun updateQuery(text: String) = state { - copy(query = text) - }.also { - query.update { text } + fun updateQuery(query: String) = reduce { + copy(query = query) } private fun load() = launchCatching(defaultDispatcher) { @@ -54,19 +47,21 @@ class AppsPickerViewModel @Inject constructor( val installedApps = packageManager.getInstalledPackages(0).map { InstalledApp( - title = it.applicationInfo.loadLabel(packageManager).toString(), + title = it.applicationInfo?.loadLabel(packageManager).toString(), packageName = it.packageName, ) }.sortedBy(InstalledApp::title) - state { + reduce { copy( apps = installedApps.toImmutableList(), isLoading = false, ) } - query.map { query -> + state.map { state -> + state.query + }.distinctUntilChanged().map { query -> installedApps.filter { app -> app.title.contains(query, ignoreCase = true) || app.packageName.contains(query, ignoreCase = true) @@ -74,7 +69,7 @@ class AppsPickerViewModel @Inject constructor( }.flowOn( defaultDispatcher, ).collectLatest { apps -> - state { copy(searchedApps = apps.toImmutableList()) } + reduce { copy(searchedApps = apps.toImmutableList()) } } } } diff --git a/feature/apps-picker/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/ui/fragment/picker/AppsPickerFragment.kt b/feature/apps-picker/impl/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/presentation/ui/AppsPickerFragment.kt similarity index 60% rename from feature/apps-picker/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/ui/fragment/picker/AppsPickerFragment.kt rename to feature/apps-picker/impl/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/presentation/ui/AppsPickerFragment.kt index 2234fe25..0498ef13 100644 --- a/feature/apps-picker/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/ui/fragment/picker/AppsPickerFragment.kt +++ b/feature/apps-picker/impl/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/presentation/ui/AppsPickerFragment.kt @@ -1,16 +1,17 @@ -package com.f0x1d.logfox.feature.apps.picker.ui.fragment.picker +package com.f0x1d.logfox.feature.apps.picker.presentation.ui +import android.annotation.SuppressLint import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue +import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import androidx.navigation.fragment.findNavController -import com.f0x1d.logfox.arch.ui.fragment.compose.BaseComposeViewModelFragment -import com.f0x1d.logfox.feature.apps.picker.ui.fragment.picker.compose.AppsPickerScreenContent -import com.f0x1d.logfox.feature.apps.picker.ui.fragment.picker.compose.AppsPickerScreenListener -import com.f0x1d.logfox.feature.apps.picker.ui.fragment.picker.compose.AppsPickerScreenState -import com.f0x1d.logfox.feature.apps.picker.viewmodel.AppsPickerViewModel -import com.f0x1d.logfox.feature.apps.picker.viewmodel.resultHandler +import com.f0x1d.logfox.arch.presentation.ui.fragment.compose.BaseComposeFragment +import com.f0x1d.logfox.feature.apps.picker.AppsPickerResultHandler +import com.f0x1d.logfox.feature.apps.picker.presentation.AppsPickerState +import com.f0x1d.logfox.feature.apps.picker.presentation.AppsPickerViewModel +import com.f0x1d.logfox.feature.apps.picker.presentation.ui.compose.AppsPickerScreenContent import com.f0x1d.logfox.ui.compose.theme.LogFoxTheme import dagger.hilt.android.AndroidEntryPoint import kotlinx.collections.immutable.toImmutableSet @@ -19,9 +20,9 @@ import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.map @AndroidEntryPoint -class AppsPickerFragment: BaseComposeViewModelFragment() { +class AppsPickerFragment : BaseComposeFragment() { - override val viewModel by viewModels() + private val viewModel by viewModels() private val resultHandler by resultHandler() private val listener by lazy { @@ -40,9 +41,9 @@ class AppsPickerFragment: BaseComposeViewModelFragment() { ) } - private val uiState: Flow by lazy { + private val uiState: Flow by lazy { resultHandler?.let { handler -> - combine(viewModel.uiState, handler.checkedAppPackageNames) { state, checkedApps -> + combine(viewModel.state, handler.checkedAppPackageNames) { state, checkedApps -> state to checkedApps }.map { (state, checkedAppPackageNames) -> state.copy( @@ -51,7 +52,7 @@ class AppsPickerFragment: BaseComposeViewModelFragment() { multiplySelectionEnabled = handler.supportsMultiplySelection, ) } - } ?: viewModel.uiState + } ?: viewModel.state } @Composable @@ -65,4 +66,16 @@ class AppsPickerFragment: BaseComposeViewModelFragment() { ) } } + + @SuppressLint("RestrictedApi") + private fun Fragment.resultHandler(): Lazy = lazy { + val backStackEntry = findNavController().previousBackStackEntry + ?: return@lazy null + + val store = backStackEntry.viewModelStore + val availableViewModelKeys = store.keys() + + availableViewModelKeys + .firstNotNullOfOrNull { store[it] as? AppsPickerResultHandler } + } } diff --git a/feature/apps-picker/impl/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/presentation/ui/AppsPickerScreenListener.kt b/feature/apps-picker/impl/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/presentation/ui/AppsPickerScreenListener.kt new file mode 100644 index 00000000..e12eb9dc --- /dev/null +++ b/feature/apps-picker/impl/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/presentation/ui/AppsPickerScreenListener.kt @@ -0,0 +1,19 @@ +package com.f0x1d.logfox.feature.apps.picker.presentation.ui + +import com.f0x1d.logfox.feature.apps.picker.InstalledApp + +data class AppsPickerScreenListener( + val onBackClicked: () -> Unit, + val onAppClicked: (InstalledApp) -> Unit, + val onAppChecked: (InstalledApp, Boolean) -> Unit, + val onSearchActiveChanged: (Boolean) -> Unit, + val onQueryChanged: (String) -> Unit, +) + +internal val MockAppsPickerScreenListener = AppsPickerScreenListener( + onBackClicked = { }, + onAppClicked = { }, + onAppChecked = { _, _ -> }, + onSearchActiveChanged = { }, + onQueryChanged = { }, +) diff --git a/feature/apps-picker/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/ui/fragment/picker/compose/AppsPickerScreenContent.kt b/feature/apps-picker/impl/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/presentation/ui/compose/AppsPickerScreenContent.kt similarity index 92% rename from feature/apps-picker/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/ui/fragment/picker/compose/AppsPickerScreenContent.kt rename to feature/apps-picker/impl/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/presentation/ui/compose/AppsPickerScreenContent.kt index 47ce9044..1e3ca551 100644 --- a/feature/apps-picker/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/ui/fragment/picker/compose/AppsPickerScreenContent.kt +++ b/feature/apps-picker/impl/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/presentation/ui/compose/AppsPickerScreenContent.kt @@ -1,4 +1,4 @@ -package com.f0x1d.logfox.feature.apps.picker.ui.fragment.picker.compose +package com.f0x1d.logfox.feature.apps.picker.presentation.ui.compose import androidx.activity.compose.BackHandler import androidx.compose.foundation.ExperimentalFoundationApi @@ -37,7 +37,10 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import coil.compose.AsyncImage -import com.f0x1d.logfox.model.InstalledApp +import com.f0x1d.logfox.feature.apps.picker.InstalledApp +import com.f0x1d.logfox.feature.apps.picker.presentation.AppsPickerState +import com.f0x1d.logfox.feature.apps.picker.presentation.ui.AppsPickerScreenListener +import com.f0x1d.logfox.feature.apps.picker.presentation.ui.MockAppsPickerScreenListener import com.f0x1d.logfox.strings.Strings import com.f0x1d.logfox.ui.compose.component.button.NavigationBackButton import com.f0x1d.logfox.ui.compose.component.search.TopSearchBar @@ -50,7 +53,7 @@ import kotlinx.collections.immutable.persistentSetOf @Composable internal fun AppsPickerScreenContent( - state: AppsPickerScreenState = AppsPickerScreenState(), + state: AppsPickerState = AppsPickerState(), listener: AppsPickerScreenListener = MockAppsPickerScreenListener, ) { CompositionLocalProvider(LocalMultiplySelectionEnabled provides state.multiplySelectionEnabled) { @@ -83,7 +86,7 @@ internal fun AppsPickerScreenContent( @Composable private fun AppsSearchBar( - state: AppsPickerScreenState, + state: AppsPickerState, listener: AppsPickerScreenListener, modifier: Modifier = Modifier, ) { @@ -224,7 +227,7 @@ internal val MockApps = persistentListOf( InstalledApp("LogFox", "com.f0x1d.logfox"), InstalledApp("Sense", "com.f0x1d.sense"), ) -internal val MockAppsPickerScreenState = AppsPickerScreenState( +internal val MockAppsPickerState = AppsPickerState( apps = MockApps, searchedApps = MockApps, checkedAppPackageNames = persistentSetOf(MockApps.first().packageName), @@ -235,7 +238,7 @@ internal val MockAppsPickerScreenState = AppsPickerScreenState( @Composable private fun AppsPickerScreenContentPreview() = LogFoxTheme { AppsPickerScreenContent( - state = MockAppsPickerScreenState, + state = MockAppsPickerState, ) } @@ -243,7 +246,7 @@ private fun AppsPickerScreenContentPreview() = LogFoxTheme { @Composable private fun AppsPickerSearchScreenContentPreview() = LogFoxTheme { AppsPickerScreenContent( - state = MockAppsPickerScreenState.copy(searchActive = true), + state = MockAppsPickerState.copy(searchActive = true), ) } diff --git a/feature/apps-picker/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/ui/fragment/picker/compose/AppsPickerScreenState.kt b/feature/apps-picker/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/ui/fragment/picker/compose/AppsPickerScreenState.kt deleted file mode 100644 index 71ea5f39..00000000 --- a/feature/apps-picker/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/ui/fragment/picker/compose/AppsPickerScreenState.kt +++ /dev/null @@ -1,34 +0,0 @@ -package com.f0x1d.logfox.feature.apps.picker.ui.fragment.picker.compose - -import com.f0x1d.logfox.model.InstalledApp -import kotlinx.collections.immutable.ImmutableList -import kotlinx.collections.immutable.ImmutableSet -import kotlinx.collections.immutable.persistentListOf -import kotlinx.collections.immutable.persistentSetOf - -data class AppsPickerScreenState( - val topBarTitle: String = "Apps", - val apps: ImmutableList = persistentListOf(), - val checkedAppPackageNames: ImmutableSet = persistentSetOf(), - val searchedApps: ImmutableList = persistentListOf(), - val multiplySelectionEnabled: Boolean = true, - val isLoading: Boolean = true, - val searchActive: Boolean = false, - val query: String = "", -) - -data class AppsPickerScreenListener( - val onBackClicked: () -> Unit, - val onAppClicked: (InstalledApp) -> Unit, - val onAppChecked: (InstalledApp, Boolean) -> Unit, - val onSearchActiveChanged: (Boolean) -> Unit, - val onQueryChanged: (String) -> Unit, -) - -internal val MockAppsPickerScreenListener = AppsPickerScreenListener( - onBackClicked = { }, - onAppClicked = { }, - onAppChecked = { _, _ -> }, - onSearchActiveChanged = { }, - onQueryChanged = { }, -) diff --git a/feature/apps-picker/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/viewmodel/AppsPickerResultHandler.kt b/feature/apps-picker/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/viewmodel/AppsPickerResultHandler.kt deleted file mode 100644 index 819b36b3..00000000 --- a/feature/apps-picker/src/main/kotlin/com/f0x1d/logfox/feature/apps/picker/viewmodel/AppsPickerResultHandler.kt +++ /dev/null @@ -1,34 +0,0 @@ -package com.f0x1d.logfox.feature.apps.picker.viewmodel - -import android.annotation.SuppressLint -import android.content.Context -import androidx.fragment.app.Fragment -import androidx.navigation.fragment.findNavController -import com.f0x1d.logfox.model.InstalledApp -import com.f0x1d.logfox.strings.Strings -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.flowOf - -interface AppsPickerResultHandler { - val supportsMultiplySelection: Boolean get() = false - val checkedAppPackageNames: Flow> get() = flowOf(emptySet()) - - fun providePickerTopAppBarTitle(context: Context) = context.getString(Strings.apps) - - fun onAppChecked(app: InstalledApp, checked: Boolean) = Unit - - // pass true to close fragment - fun onAppSelected(app: InstalledApp): Boolean = false -} - -@SuppressLint("RestrictedApi") -internal fun Fragment.resultHandler(): Lazy = lazy { - val backStackEntry = findNavController().previousBackStackEntry - ?: return@lazy null - - val store = backStackEntry.viewModelStore - val availableViewModelKeys = store.keys() - - availableViewModelKeys - .firstNotNullOfOrNull { store[it] as? AppsPickerResultHandler } -} diff --git a/feature/crashes-core/.gitignore b/feature/crashes/api/.gitignore similarity index 100% rename from feature/crashes-core/.gitignore rename to feature/crashes/api/.gitignore diff --git a/feature/crashes-core/build.gradle.kts b/feature/crashes/api/build.gradle.kts similarity index 52% rename from feature/crashes-core/build.gradle.kts rename to feature/crashes/api/build.gradle.kts index b36df4d1..c4d94679 100644 --- a/feature/crashes-core/build.gradle.kts +++ b/feature/crashes/api/build.gradle.kts @@ -2,7 +2,7 @@ plugins { id("logfox.android.feature") } -android.namespace = "com.f0x1d.logfox.feature.crashes.core" +android.namespace = "com.f0x1d.logfox.feature.crashes.api" dependencies { diff --git a/feature/crashes/api/src/main/kotlin/com/f0x1d/logfox/feature/crashes/api/data/CrashesController.kt b/feature/crashes/api/src/main/kotlin/com/f0x1d/logfox/feature/crashes/api/data/CrashesController.kt new file mode 100644 index 00000000..b822538e --- /dev/null +++ b/feature/crashes/api/src/main/kotlin/com/f0x1d/logfox/feature/crashes/api/data/CrashesController.kt @@ -0,0 +1,7 @@ +package com.f0x1d.logfox.feature.crashes.api.data + +import com.f0x1d.logfox.model.logline.LogLine + +interface CrashesController { + val readers: List Unit> +} diff --git a/feature/crashes/api/src/main/kotlin/com/f0x1d/logfox/feature/crashes/api/data/CrashesNotificationsController.kt b/feature/crashes/api/src/main/kotlin/com/f0x1d/logfox/feature/crashes/api/data/CrashesNotificationsController.kt new file mode 100644 index 00000000..fb17043b --- /dev/null +++ b/feature/crashes/api/src/main/kotlin/com/f0x1d/logfox/feature/crashes/api/data/CrashesNotificationsController.kt @@ -0,0 +1,12 @@ +package com.f0x1d.logfox.feature.crashes.api.data + +import com.f0x1d.logfox.arch.CRASHES_CHANNEL_GROUP_ID +import com.f0x1d.logfox.database.entity.AppCrash + +interface CrashesNotificationsController { + fun sendErrorNotification(appCrash: AppCrash, crashLog: String?) + fun cancelCrashNotificationFor(appCrash: AppCrash) + fun cancelAllCrashNotifications() +} + +val AppCrash.notificationChannelId get() = "${CRASHES_CHANNEL_GROUP_ID}_${crashType.readableName}_$packageName" diff --git a/feature/crashes/api/src/main/kotlin/com/f0x1d/logfox/feature/crashes/api/data/CrashesRepository.kt b/feature/crashes/api/src/main/kotlin/com/f0x1d/logfox/feature/crashes/api/data/CrashesRepository.kt new file mode 100644 index 00000000..5ce3cb94 --- /dev/null +++ b/feature/crashes/api/src/main/kotlin/com/f0x1d/logfox/feature/crashes/api/data/CrashesRepository.kt @@ -0,0 +1,15 @@ +package com.f0x1d.logfox.feature.crashes.api.data + +import com.f0x1d.logfox.arch.repository.DatabaseProxyRepository +import com.f0x1d.logfox.database.entity.AppCrash + +interface CrashesRepository : DatabaseProxyRepository { + suspend fun getAllByDateAndTime( + dateAndTime: Long, + packageName: String, + ): List + + suspend fun insert(appCrash: AppCrash): Long + + suspend fun deleteAllByPackageName(appCrash: AppCrash) +} diff --git a/feature/crashes/api/src/main/kotlin/com/f0x1d/logfox/feature/crashes/api/data/DisabledAppsRepository.kt b/feature/crashes/api/src/main/kotlin/com/f0x1d/logfox/feature/crashes/api/data/DisabledAppsRepository.kt new file mode 100644 index 00000000..1c32f953 --- /dev/null +++ b/feature/crashes/api/src/main/kotlin/com/f0x1d/logfox/feature/crashes/api/data/DisabledAppsRepository.kt @@ -0,0 +1,13 @@ +package com.f0x1d.logfox.feature.crashes.api.data + +import com.f0x1d.logfox.arch.repository.DatabaseProxyRepository +import com.f0x1d.logfox.database.entity.DisabledApp +import kotlinx.coroutines.flow.Flow + +interface DisabledAppsRepository : DatabaseProxyRepository { + suspend fun isDisabledFor(packageName: String): Boolean + fun disabledForFlow(packageName: String): Flow + + suspend fun checkApp(packageName: String) + suspend fun checkApp(packageName: String, checked: Boolean) +} diff --git a/feature/crashes/apps-list/.gitignore b/feature/crashes/apps-list/.gitignore new file mode 100644 index 00000000..42afabfd --- /dev/null +++ b/feature/crashes/apps-list/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/feature/crashes/apps-list/build.gradle.kts b/feature/crashes/apps-list/build.gradle.kts new file mode 100644 index 00000000..6100bef7 --- /dev/null +++ b/feature/crashes/apps-list/build.gradle.kts @@ -0,0 +1,10 @@ +plugins { + id("logfox.android.feature") +} + +android.namespace = "com.f0x1d.logfox.feature.crashes.apps.list" + +dependencies { + implementation(projects.feature.crashes.api) + implementation(projects.feature.crashes.common) +} diff --git a/feature/crashes/src/main/kotlin/com/f0x1d/logfox/feature/crashes/di/AppCrashesViewModelModule.kt b/feature/crashes/apps-list/src/main/kotlin/com/f0x1d/logfox/feature/crashes/apps/list/di/AppCrashesViewModelModule.kt similarity index 93% rename from feature/crashes/src/main/kotlin/com/f0x1d/logfox/feature/crashes/di/AppCrashesViewModelModule.kt rename to feature/crashes/apps-list/src/main/kotlin/com/f0x1d/logfox/feature/crashes/apps/list/di/AppCrashesViewModelModule.kt index 96c750d7..3bb97a47 100644 --- a/feature/crashes/src/main/kotlin/com/f0x1d/logfox/feature/crashes/di/AppCrashesViewModelModule.kt +++ b/feature/crashes/apps-list/src/main/kotlin/com/f0x1d/logfox/feature/crashes/apps/list/di/AppCrashesViewModelModule.kt @@ -1,4 +1,4 @@ -package com.f0x1d.logfox.feature.crashes.di +package com.f0x1d.logfox.feature.crashes.apps.list.di import androidx.lifecycle.SavedStateHandle import dagger.Module diff --git a/feature/crashes/apps-list/src/main/kotlin/com/f0x1d/logfox/feature/crashes/apps/list/presentation/AppCrashesAction.kt b/feature/crashes/apps-list/src/main/kotlin/com/f0x1d/logfox/feature/crashes/apps/list/presentation/AppCrashesAction.kt new file mode 100644 index 00000000..85fd05af --- /dev/null +++ b/feature/crashes/apps-list/src/main/kotlin/com/f0x1d/logfox/feature/crashes/apps/list/presentation/AppCrashesAction.kt @@ -0,0 +1,3 @@ +package com.f0x1d.logfox.feature.crashes.apps.list.presentation + +sealed interface AppCrashesAction diff --git a/feature/crashes/apps-list/src/main/kotlin/com/f0x1d/logfox/feature/crashes/apps/list/presentation/AppCrashesState.kt b/feature/crashes/apps-list/src/main/kotlin/com/f0x1d/logfox/feature/crashes/apps/list/presentation/AppCrashesState.kt new file mode 100644 index 00000000..754a932d --- /dev/null +++ b/feature/crashes/apps-list/src/main/kotlin/com/f0x1d/logfox/feature/crashes/apps/list/presentation/AppCrashesState.kt @@ -0,0 +1,7 @@ +package com.f0x1d.logfox.feature.crashes.apps.list.presentation + +import com.f0x1d.logfox.database.entity.AppCrashesCount + +data class AppCrashesState( + val crashes: List = emptyList(), +) diff --git a/feature/crashes/apps-list/src/main/kotlin/com/f0x1d/logfox/feature/crashes/apps/list/presentation/AppCrashesViewModel.kt b/feature/crashes/apps-list/src/main/kotlin/com/f0x1d/logfox/feature/crashes/apps/list/presentation/AppCrashesViewModel.kt new file mode 100644 index 00000000..3d88f4f5 --- /dev/null +++ b/feature/crashes/apps-list/src/main/kotlin/com/f0x1d/logfox/feature/crashes/apps/list/presentation/AppCrashesViewModel.kt @@ -0,0 +1,56 @@ +package com.f0x1d.logfox.feature.crashes.apps.list.presentation + +import android.app.Application +import androidx.lifecycle.viewModelScope +import com.f0x1d.logfox.arch.di.DefaultDispatcher +import com.f0x1d.logfox.arch.viewmodel.BaseViewModel +import com.f0x1d.logfox.database.entity.AppCrash +import com.f0x1d.logfox.database.entity.AppCrashesCount +import com.f0x1d.logfox.feature.crashes.api.data.CrashesRepository +import com.f0x1d.logfox.feature.crashes.apps.list.di.AppName +import com.f0x1d.logfox.feature.crashes.apps.list.di.PackageName +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +class AppCrashesViewModel @Inject constructor( + @PackageName val packageName: String, + @AppName val appName: String?, + private val crashesRepository: CrashesRepository, + @DefaultDispatcher private val defaultDispatcher: CoroutineDispatcher, + application: Application, +): BaseViewModel( + initialStateProvider = { AppCrashesState() }, + application = application, +) { + init { + load() + } + + private fun load() { + viewModelScope.launch { + crashesRepository.getAllAsFlow() + .map { crashes -> + crashes.filter { crash -> + crash.packageName == packageName + }.map { + AppCrashesCount(it) + } + } + .flowOn(defaultDispatcher) + .collect { crashes -> + reduce { + copy(crashes = crashes) + } + } + } + } + + fun deleteCrash(appCrash: AppCrash) = launchCatching { + crashesRepository.delete(appCrash) + } +} diff --git a/feature/crashes/src/main/kotlin/com/f0x1d/logfox/feature/crashes/ui/fragment/list/AppCrashesFragment.kt b/feature/crashes/apps-list/src/main/kotlin/com/f0x1d/logfox/feature/crashes/apps/list/presentation/ui/AppCrashesFragment.kt similarity index 78% rename from feature/crashes/src/main/kotlin/com/f0x1d/logfox/feature/crashes/ui/fragment/list/AppCrashesFragment.kt rename to feature/crashes/apps-list/src/main/kotlin/com/f0x1d/logfox/feature/crashes/apps/list/presentation/ui/AppCrashesFragment.kt index 73682d89..889fffae 100644 --- a/feature/crashes/src/main/kotlin/com/f0x1d/logfox/feature/crashes/ui/fragment/list/AppCrashesFragment.kt +++ b/feature/crashes/apps-list/src/main/kotlin/com/f0x1d/logfox/feature/crashes/apps/list/presentation/ui/AppCrashesFragment.kt @@ -1,4 +1,4 @@ -package com.f0x1d.logfox.feature.crashes.ui.fragment.list +package com.f0x1d.logfox.feature.crashes.apps.list.presentation.ui import android.os.Bundle import android.view.LayoutInflater @@ -8,10 +8,10 @@ import androidx.core.os.bundleOf import androidx.fragment.app.viewModels import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.LinearLayoutManager -import com.f0x1d.logfox.arch.ui.fragment.BaseViewModelFragment -import com.f0x1d.logfox.feature.crashes.adapter.CrashesAdapter -import com.f0x1d.logfox.feature.crashes.databinding.FragmentAppCrashesBinding -import com.f0x1d.logfox.feature.crashes.viewmodel.list.AppCrashesViewModel +import com.f0x1d.logfox.arch.presentation.ui.fragment.BaseFragment +import com.f0x1d.logfox.feature.crashes.apps.list.databinding.FragmentAppCrashesBinding +import com.f0x1d.logfox.feature.crashes.apps.list.presentation.AppCrashesViewModel +import com.f0x1d.logfox.feature.crashes.common.presentation.adapter.CrashesAdapter import com.f0x1d.logfox.navigation.Directions import com.f0x1d.logfox.ui.density.dpToPx import com.f0x1d.logfox.ui.dialog.showAreYouSureDeleteDialog @@ -21,9 +21,9 @@ import dagger.hilt.android.AndroidEntryPoint import dev.chrisbanes.insetter.applyInsetter @AndroidEntryPoint -class AppCrashesFragment: BaseViewModelFragment() { +class AppCrashesFragment: BaseFragment() { - override val viewModel by viewModels() + private val viewModel by viewModels() private val adapter = CrashesAdapter( click = { @@ -73,8 +73,8 @@ class AppCrashesFragment: BaseViewModelFragment Unit, diff --git a/feature/crashes/src/main/kotlin/com/f0x1d/logfox/feature/crashes/ui/viewholder/CrashViewHolder.kt b/feature/crashes/common/src/main/kotlin/com/f0x1d/logfox/feature/crashes/common/presentation/ui/viewholder/CrashViewHolder.kt similarity index 85% rename from feature/crashes/src/main/kotlin/com/f0x1d/logfox/feature/crashes/ui/viewholder/CrashViewHolder.kt rename to feature/crashes/common/src/main/kotlin/com/f0x1d/logfox/feature/crashes/common/presentation/ui/viewholder/CrashViewHolder.kt index c1610c0a..38720b12 100644 --- a/feature/crashes/src/main/kotlin/com/f0x1d/logfox/feature/crashes/ui/viewholder/CrashViewHolder.kt +++ b/feature/crashes/common/src/main/kotlin/com/f0x1d/logfox/feature/crashes/common/presentation/ui/viewholder/CrashViewHolder.kt @@ -1,10 +1,10 @@ -package com.f0x1d.logfox.feature.crashes.ui.viewholder +package com.f0x1d.logfox.feature.crashes.common.presentation.ui.viewholder import android.annotation.SuppressLint import com.bumptech.glide.Glide -import com.f0x1d.logfox.arch.ui.viewholder.BaseViewHolder +import com.f0x1d.logfox.arch.presentation.ui.viewholder.BaseViewHolder import com.f0x1d.logfox.database.entity.AppCrashesCount -import com.f0x1d.logfox.feature.crashes.databinding.ItemCrashBinding +import com.f0x1d.logfox.feature.crashes.common.databinding.ItemCrashBinding import com.f0x1d.logfox.strings.Strings import com.f0x1d.logfox.ui.view.loadIcon import java.util.Date diff --git a/feature/crashes/src/main/res/layout/item_crash.xml b/feature/crashes/common/src/main/res/layout/item_crash.xml similarity index 100% rename from feature/crashes/src/main/res/layout/item_crash.xml rename to feature/crashes/common/src/main/res/layout/item_crash.xml diff --git a/feature/crashes/src/main/res/layout/placeholder_crashes.xml b/feature/crashes/common/src/main/res/layout/placeholder_crashes.xml similarity index 100% rename from feature/crashes/src/main/res/layout/placeholder_crashes.xml rename to feature/crashes/common/src/main/res/layout/placeholder_crashes.xml diff --git a/feature/crashes/details/.gitignore b/feature/crashes/details/.gitignore new file mode 100644 index 00000000..42afabfd --- /dev/null +++ b/feature/crashes/details/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/feature/crashes/details/build.gradle.kts b/feature/crashes/details/build.gradle.kts new file mode 100644 index 00000000..15b0ea8d --- /dev/null +++ b/feature/crashes/details/build.gradle.kts @@ -0,0 +1,10 @@ +plugins { + id("logfox.android.feature") +} + +android.namespace = "com.f0x1d.logfox.feature.crashes.details" + +dependencies { + implementation(projects.feature.crashes.api) + implementation(projects.feature.crashes.common) +} diff --git a/feature/crashes/src/main/kotlin/com/f0x1d/logfox/feature/crashes/di/CrashDetailsViewModelModule.kt b/feature/crashes/details/src/main/kotlin/com/f0x1d/logfox/feature/crashes/details/di/CrashDetailsViewModelModule.kt similarity index 91% rename from feature/crashes/src/main/kotlin/com/f0x1d/logfox/feature/crashes/di/CrashDetailsViewModelModule.kt rename to feature/crashes/details/src/main/kotlin/com/f0x1d/logfox/feature/crashes/details/di/CrashDetailsViewModelModule.kt index be96f1bf..932d7d95 100644 --- a/feature/crashes/src/main/kotlin/com/f0x1d/logfox/feature/crashes/di/CrashDetailsViewModelModule.kt +++ b/feature/crashes/details/src/main/kotlin/com/f0x1d/logfox/feature/crashes/details/di/CrashDetailsViewModelModule.kt @@ -1,4 +1,4 @@ -package com.f0x1d.logfox.feature.crashes.di +package com.f0x1d.logfox.feature.crashes.details.di import androidx.lifecycle.SavedStateHandle import dagger.Module diff --git a/feature/crashes/details/src/main/kotlin/com/f0x1d/logfox/feature/crashes/details/presentation/CrashDetailsAction.kt b/feature/crashes/details/src/main/kotlin/com/f0x1d/logfox/feature/crashes/details/presentation/CrashDetailsAction.kt new file mode 100644 index 00000000..d0c54ee8 --- /dev/null +++ b/feature/crashes/details/src/main/kotlin/com/f0x1d/logfox/feature/crashes/details/presentation/CrashDetailsAction.kt @@ -0,0 +1,3 @@ +package com.f0x1d.logfox.feature.crashes.details.presentation + +sealed interface CrashDetailsAction diff --git a/feature/crashes/details/src/main/kotlin/com/f0x1d/logfox/feature/crashes/details/presentation/CrashDetailsState.kt b/feature/crashes/details/src/main/kotlin/com/f0x1d/logfox/feature/crashes/details/presentation/CrashDetailsState.kt new file mode 100644 index 00000000..b5c5cfc3 --- /dev/null +++ b/feature/crashes/details/src/main/kotlin/com/f0x1d/logfox/feature/crashes/details/presentation/CrashDetailsState.kt @@ -0,0 +1,9 @@ +package com.f0x1d.logfox.feature.crashes.details.presentation + +import com.f0x1d.logfox.database.entity.AppCrash + +data class CrashDetailsState( + val crash: AppCrash? = null, + val crashLog: String? = null, + val blacklisted: Boolean? = null, +) diff --git a/feature/crashes/src/main/kotlin/com/f0x1d/logfox/feature/crashes/viewmodel/CrashDetailsViewModel.kt b/feature/crashes/details/src/main/kotlin/com/f0x1d/logfox/feature/crashes/details/presentation/CrashDetailsViewModel.kt similarity index 57% rename from feature/crashes/src/main/kotlin/com/f0x1d/logfox/feature/crashes/viewmodel/CrashDetailsViewModel.kt rename to feature/crashes/details/src/main/kotlin/com/f0x1d/logfox/feature/crashes/details/presentation/CrashDetailsViewModel.kt index 01ce1dd3..1f005f4d 100644 --- a/feature/crashes/src/main/kotlin/com/f0x1d/logfox/feature/crashes/viewmodel/CrashDetailsViewModel.kt +++ b/feature/crashes/details/src/main/kotlin/com/f0x1d/logfox/feature/crashes/details/presentation/CrashDetailsViewModel.kt @@ -1,4 +1,4 @@ -package com.f0x1d.logfox.feature.crashes.viewmodel +package com.f0x1d.logfox.feature.crashes.details.presentation import android.app.Application import android.net.Uri @@ -9,19 +9,21 @@ import com.f0x1d.logfox.arch.io.putZipEntry import com.f0x1d.logfox.arch.viewmodel.BaseViewModel import com.f0x1d.logfox.database.entity.AppCrash import com.f0x1d.logfox.datetime.DateTimeFormatter -import com.f0x1d.logfox.feature.crashes.core.repository.CrashesRepository -import com.f0x1d.logfox.feature.crashes.core.repository.DisabledAppsRepository -import com.f0x1d.logfox.feature.crashes.di.CrashId +import com.f0x1d.logfox.feature.crashes.api.data.CrashesRepository +import com.f0x1d.logfox.feature.crashes.api.data.DisabledAppsRepository +import com.f0x1d.logfox.feature.crashes.details.di.CrashId import com.f0x1d.logfox.model.deviceData import com.f0x1d.logfox.preferences.shared.AppPreferences import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.stateIn +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel @@ -33,42 +35,54 @@ class CrashDetailsViewModel @Inject constructor( @IODispatcher private val ioDispatcher: CoroutineDispatcher, dateTimeFormatter: DateTimeFormatter, application: Application, -): BaseViewModel(application), DateTimeFormatter by dateTimeFormatter { - - val crash = crashesRepository.getByIdAsFlow(crashId) - .map { - when (it) { - null -> null +): BaseViewModel( + initialStateProvider = { CrashDetailsState() }, + application = application, +), DateTimeFormatter by dateTimeFormatter { + val wrapCrashLogLines get() = appPreferences.wrapCrashLogLines + val useSeparateNotificationsChannelsForCrashes get() = appPreferences.useSeparateNotificationsChannelsForCrashes - else -> runCatching { - it to it.logFile?.readText() - }.getOrNull() - } - } - .stateIn( - scope = viewModelScope, - started = SharingStarted.Eagerly, - initialValue = null, - ) + init { + load() + } @OptIn(ExperimentalCoroutinesApi::class) - val blacklisted = crashesRepository.getByIdAsFlow(crashId) - .flatMapLatest { crash -> - crash?.let { - disabledAppsRepository.disabledForFlow(it.packageName) - } ?: flowOf(null) - } - .stateIn( - scope = viewModelScope, - started = SharingStarted.Eagerly, - initialValue = null, - ) + private fun load() { + viewModelScope.launch { + crashesRepository.getByIdAsFlow(crashId) + .map { + when (it) { + null -> null - val wrapCrashLogLines get() = appPreferences.wrapCrashLogLines - val useSeparateNotificationsChannelsForCrashes get() = appPreferences.useSeparateNotificationsChannelsForCrashes + else -> runCatching { + it to it.logFile?.readText() + }.getOrNull() + } + } + .flowOn(ioDispatcher) + .onEach { value -> + value?.let { (crash, crashLog) -> + reduce { copy(crash = crash, crashLog = crashLog) } + } + } + .launchIn(this) + + crashesRepository.getByIdAsFlow(crashId) + .flatMapLatest { crash -> + crash?.let { + disabledAppsRepository.disabledForFlow(it.packageName) + } ?: flowOf(null) + } + .onEach { blacklisted -> + reduce { copy(blacklisted = blacklisted) } + } + .launchIn(this) + } + } fun exportCrashToZip(uri: Uri) = launchCatching(ioDispatcher) { - val (appCrash, crashLog) = crash.value ?: return@launchCatching + val appCrash = currentState.crash ?: return@launchCatching + val crashLog = currentState.crashLog ctx.contentResolver.openOutputStream(uri)?.use { it.exportToZip { diff --git a/feature/crashes/src/main/kotlin/com/f0x1d/logfox/feature/crashes/ui/fragment/CrashDetailsFragment.kt b/feature/crashes/details/src/main/kotlin/com/f0x1d/logfox/feature/crashes/details/presentation/ui/CrashDetailsFragment.kt similarity index 69% rename from feature/crashes/src/main/kotlin/com/f0x1d/logfox/feature/crashes/ui/fragment/CrashDetailsFragment.kt rename to feature/crashes/details/src/main/kotlin/com/f0x1d/logfox/feature/crashes/details/presentation/ui/CrashDetailsFragment.kt index a11af621..c18516ab 100644 --- a/feature/crashes/src/main/kotlin/com/f0x1d/logfox/feature/crashes/ui/fragment/CrashDetailsFragment.kt +++ b/feature/crashes/details/src/main/kotlin/com/f0x1d/logfox/feature/crashes/details/presentation/ui/CrashDetailsFragment.kt @@ -1,4 +1,4 @@ -package com.f0x1d.logfox.feature.crashes.ui.fragment +package com.f0x1d.logfox.feature.crashes.details.presentation.ui import android.annotation.SuppressLint import android.content.Intent @@ -21,13 +21,13 @@ import androidx.fragment.app.viewModels import androidx.navigation.fragment.findNavController import com.f0x1d.logfox.arch.copyText import com.f0x1d.logfox.arch.notificationsChannelsAvailable +import com.f0x1d.logfox.arch.presentation.ui.fragment.BaseFragment import com.f0x1d.logfox.arch.shareIntent -import com.f0x1d.logfox.arch.ui.fragment.BaseViewModelFragment import com.f0x1d.logfox.database.entity.AppCrash -import com.f0x1d.logfox.feature.crashes.R -import com.f0x1d.logfox.feature.crashes.core.controller.notificationChannelId -import com.f0x1d.logfox.feature.crashes.databinding.FragmentCrashDetailsBinding -import com.f0x1d.logfox.feature.crashes.viewmodel.CrashDetailsViewModel +import com.f0x1d.logfox.feature.crashes.api.data.notificationChannelId +import com.f0x1d.logfox.feature.crashes.details.R +import com.f0x1d.logfox.feature.crashes.details.databinding.FragmentCrashDetailsBinding +import com.f0x1d.logfox.feature.crashes.details.presentation.CrashDetailsViewModel import com.f0x1d.logfox.strings.Strings import com.f0x1d.logfox.ui.Colors import com.f0x1d.logfox.ui.Icons @@ -41,9 +41,9 @@ import dev.chrisbanes.insetter.applyInsetter import java.util.Locale @AndroidEntryPoint -class CrashDetailsFragment: BaseViewModelFragment() { +class CrashDetailsFragment : BaseFragment() { - override val viewModel by viewModels() + private val viewModel by viewModels() private val zipCrashLauncher = registerForActivityResult( ActivityResultContracts.CreateDocument("application/zip"), @@ -75,6 +75,42 @@ class CrashDetailsFragment: BaseViewModelFragment + Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply { + data = Uri.fromParts("package", appCrash.packageName, null) + }.let(::startActivity) + } + } + setClickListenerOn(R.id.notifications_item) { + viewModel.currentState.crash?.let { appCrash -> + Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS).apply { + putExtra(Settings.EXTRA_APP_PACKAGE, requireContext().packageName) + putExtra(Settings.EXTRA_CHANNEL_ID, appCrash.notificationChannelId) + }.let(::startActivity) + } + } + setClickListenerOn(R.id.blacklist_item) { + viewModel.currentState.crash?.let { appCrash -> + if (viewModel.currentState.blacklisted == false) { + showAreYouSureDialog( + title = Strings.blacklist, + message = Strings.warning_blacklist, + ) { + viewModel.changeBlacklist(appCrash) + } + } else { + viewModel.changeBlacklist(appCrash) + } + } + } + setClickListenerOn(R.id.delete_item) { + showAreYouSureDeleteDialog { + viewModel.currentState.crash?.let(viewModel::deleteCrash) + findNavController().popBackStack() + } + } } searchItem.setOnActionExpandListener( object : MenuItem.OnActionExpandListener { @@ -100,18 +136,34 @@ class CrashDetailsFragment: BaseViewModelFragment + shareButton.setOnClickListener { + requireContext().shareIntent(viewModel.currentState.crashLog.orEmpty()) + } + + zipButton.setOnClickListener { + viewModel.currentState.crash?.let { appCrash -> + val pkg = appCrash.packageName.replace(".", "-") + val formattedDate = viewModel.formatForExport(appCrash.dateAndTime) + + zipCrashLauncher.launch("crash-$pkg-$formattedDate.zip") + } + } + + viewModel.state.collectWithLifecycle { state -> + state.crash?.let { setupFor(it to state.crashLog) } + toolbar.menu.findItem(R.id.blacklist_item).apply { - if (blacklisted == null) { + if (state.blacklisted == null) { isVisible = false } else { isVisible = true - setIcon(if (blacklisted) Icons.ic_check_circle else Icons.ic_block) - setTitle(if (blacklisted) Strings.remove_from_blacklist else Strings.add_to_blacklist) + setIcon(if (state.blacklisted) Icons.ic_check_circle else Icons.ic_block) + setTitle(if (state.blacklisted) Strings.remove_from_blacklist else Strings.add_to_blacklist) } } } @@ -121,8 +173,25 @@ class CrashDetailsFragment: BaseViewModelFragment) { + val (appCrash, crashLog) = item + + appLogo.loadIcon(appCrash.packageName) + appName.text = appCrash.appName ?: getString(Strings.unknown) + appPackage.text = appCrash.packageName + + viewModel.wrapCrashLogLines.let { wrap -> + logText.isVisible = wrap + logTextScrollableContainer.isVisible = wrap.not() + } + + logText.text = crashLog + logTextScrollable.text = crashLog + } + private fun FragmentCrashDetailsBinding.searchInLog(text: String) { - var stackTrace = viewModel.crash.value?.second ?: return + var stackTrace = viewModel.currentState.crashLog ?: return var query = text val span = stackTrace.toSpannable() @@ -147,71 +216,6 @@ class CrashDetailsFragment: BaseViewModelFragment) { - val (appCrash, crashLog) = item - - toolbar.menu.apply { - setClickListenerOn(R.id.info_item) { - Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply { - data = Uri.fromParts("package", appCrash.packageName, null) - }.let(::startActivity) - } - setClickListenerOn(R.id.notifications_item) { - Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS).apply { - putExtra(Settings.EXTRA_APP_PACKAGE, requireContext().packageName) - putExtra(Settings.EXTRA_CHANNEL_ID, appCrash.notificationChannelId) - }.let(::startActivity) - } - setClickListenerOn(R.id.blacklist_item) { - if (viewModel.blacklisted.value == false) { - showAreYouSureDialog( - title = Strings.blacklist, - message = Strings.warning_blacklist, - ) { - viewModel.changeBlacklist(appCrash) - } - } else { - viewModel.changeBlacklist(appCrash) - } - } - setClickListenerOn(R.id.delete_item) { - showAreYouSureDeleteDialog { - viewModel.deleteCrash(appCrash) - findNavController().popBackStack() - } - } - } - - appLogo.loadIcon(appCrash.packageName) - appName.text = appCrash.appName ?: getString(Strings.unknown) - appPackage.text = appCrash.packageName - - copyButton.setOnClickListener { - requireContext().copyText(crashLog ?: "") - snackbar(Strings.text_copied) - } - - shareButton.setOnClickListener { - requireContext().shareIntent(crashLog ?: "") - } - - zipButton.setOnClickListener { - val pkg = appCrash.packageName.replace(".", "-") - val formattedDate = viewModel.formatForExport(appCrash.dateAndTime) - - zipCrashLauncher.launch("crash-$pkg-$formattedDate.zip") - } - - viewModel.wrapCrashLogLines.let { wrap -> - logText.isVisible = wrap - logTextScrollableContainer.isVisible = wrap.not() - } - - logText.text = crashLog - logTextScrollable.text = crashLog - } - private val FragmentCrashDetailsBinding.searchItem get() = toolbar.menu.findItem(R.id.search_item) } diff --git a/feature/crashes/src/main/res/layout/fragment_crash_details.xml b/feature/crashes/details/src/main/res/layout/fragment_crash_details.xml similarity index 100% rename from feature/crashes/src/main/res/layout/fragment_crash_details.xml rename to feature/crashes/details/src/main/res/layout/fragment_crash_details.xml diff --git a/feature/crashes/src/main/res/menu/crash_details_menu.xml b/feature/crashes/details/src/main/res/menu/crash_details_menu.xml similarity index 100% rename from feature/crashes/src/main/res/menu/crash_details_menu.xml rename to feature/crashes/details/src/main/res/menu/crash_details_menu.xml diff --git a/feature/crashes/impl/.gitignore b/feature/crashes/impl/.gitignore new file mode 100644 index 00000000..42afabfd --- /dev/null +++ b/feature/crashes/impl/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/feature/crashes/impl/build.gradle.kts b/feature/crashes/impl/build.gradle.kts new file mode 100644 index 00000000..7033fbad --- /dev/null +++ b/feature/crashes/impl/build.gradle.kts @@ -0,0 +1,9 @@ +plugins { + id("logfox.android.feature") +} + +android.namespace = "com.f0x1d.logfox.feature.crashes.impl" + +dependencies { + implementation(projects.feature.crashes.api) +} diff --git a/feature/crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/controller/CrashesController.kt b/feature/crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/data/CrashesControllerImpl.kt similarity index 83% rename from feature/crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/controller/CrashesController.kt rename to feature/crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/data/CrashesControllerImpl.kt index 4d7b90d1..deb2c4f1 100644 --- a/feature/crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/controller/CrashesController.kt +++ b/feature/crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/data/CrashesControllerImpl.kt @@ -1,13 +1,15 @@ -package com.f0x1d.logfox.feature.crashes.core.controller +package com.f0x1d.logfox.feature.crashes.impl.data import android.content.Context import com.f0x1d.logfox.arch.di.IODispatcher import com.f0x1d.logfox.database.entity.AppCrash -import com.f0x1d.logfox.feature.crashes.core.repository.CrashesRepository -import com.f0x1d.logfox.feature.crashes.core.repository.DisabledAppsRepository -import com.f0x1d.logfox.feature.crashes.core.repository.reader.ANRDetector -import com.f0x1d.logfox.feature.crashes.core.repository.reader.JNICrashDetector -import com.f0x1d.logfox.feature.crashes.core.repository.reader.JavaCrashDetector +import com.f0x1d.logfox.feature.crashes.api.data.CrashesController +import com.f0x1d.logfox.feature.crashes.api.data.CrashesNotificationsController +import com.f0x1d.logfox.feature.crashes.api.data.CrashesRepository +import com.f0x1d.logfox.feature.crashes.api.data.DisabledAppsRepository +import com.f0x1d.logfox.feature.crashes.impl.data.reader.ANRDetector +import com.f0x1d.logfox.feature.crashes.impl.data.reader.JNICrashDetector +import com.f0x1d.logfox.feature.crashes.impl.data.reader.JavaCrashDetector import com.f0x1d.logfox.model.logline.LogLine import com.f0x1d.logfox.preferences.shared.AppPreferences import dagger.hilt.android.qualifiers.ApplicationContext @@ -16,10 +18,6 @@ import kotlinx.coroutines.withContext import java.io.File import javax.inject.Inject -interface CrashesController { - val readers: List Unit> -} - internal class CrashesControllerImpl @Inject constructor( @ApplicationContext private val context: Context, private val notificationsController: CrashesNotificationsController, diff --git a/feature/crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/controller/CrashesNotificationsController.kt b/feature/crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/data/CrashesNotificationsControllerImpl.kt similarity index 93% rename from feature/crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/controller/CrashesNotificationsController.kt rename to feature/crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/data/CrashesNotificationsControllerImpl.kt index bf01a755..3428644c 100644 --- a/feature/crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/controller/CrashesNotificationsController.kt +++ b/feature/crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/data/CrashesNotificationsControllerImpl.kt @@ -1,4 +1,4 @@ -package com.f0x1d.logfox.feature.crashes.core.controller +package com.f0x1d.logfox.feature.crashes.impl.data import android.annotation.SuppressLint import android.content.Context @@ -17,6 +17,8 @@ import com.f0x1d.logfox.arch.notificationManager import com.f0x1d.logfox.arch.notificationManagerCompat import com.f0x1d.logfox.arch.receiver.CopyReceiver import com.f0x1d.logfox.database.entity.AppCrash +import com.f0x1d.logfox.feature.crashes.api.data.CrashesNotificationsController +import com.f0x1d.logfox.feature.crashes.api.data.notificationChannelId import com.f0x1d.logfox.navigation.Directions import com.f0x1d.logfox.navigation.NavGraphs import com.f0x1d.logfox.preferences.shared.AppPreferences @@ -25,12 +27,6 @@ import com.f0x1d.logfox.ui.Icons import dagger.hilt.android.qualifiers.ApplicationContext import javax.inject.Inject -internal interface CrashesNotificationsController { - fun sendErrorNotification(appCrash: AppCrash, crashLog: String?) - fun cancelCrashNotificationFor(appCrash: AppCrash) - fun cancelAllCrashNotifications() -} - @SuppressLint("MissingPermission") internal class CrashesNotificationsControllerImpl @Inject constructor( @ApplicationContext private val context: Context, @@ -144,5 +140,3 @@ internal class CrashesNotificationsControllerImpl @Inject constructor( private const val CRASHES_CHANNEL_ID = "crashes" } } - -val AppCrash.notificationChannelId get() = "${CRASHES_CHANNEL_GROUP_ID}_${crashType.readableName}_$packageName" diff --git a/feature/crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/repository/CrashesRepository.kt b/feature/crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/data/CrashesRepositoryImpl.kt similarity index 83% rename from feature/crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/repository/CrashesRepository.kt rename to feature/crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/data/CrashesRepositoryImpl.kt index e8119600..840a8547 100644 --- a/feature/crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/repository/CrashesRepository.kt +++ b/feature/crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/data/CrashesRepositoryImpl.kt @@ -1,10 +1,10 @@ -package com.f0x1d.logfox.feature.crashes.core.repository +package com.f0x1d.logfox.feature.crashes.impl.data import com.f0x1d.logfox.arch.di.IODispatcher -import com.f0x1d.logfox.arch.repository.DatabaseProxyRepository import com.f0x1d.logfox.database.AppDatabase import com.f0x1d.logfox.database.entity.AppCrash -import com.f0x1d.logfox.feature.crashes.core.controller.CrashesNotificationsController +import com.f0x1d.logfox.feature.crashes.api.data.CrashesNotificationsController +import com.f0x1d.logfox.feature.crashes.api.data.CrashesRepository import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.distinctUntilChanged @@ -12,16 +12,6 @@ import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.withContext import javax.inject.Inject -interface CrashesRepository : DatabaseProxyRepository { - suspend fun getAllByDateAndTime( - dateAndTime: Long, - packageName: String, - ): List - suspend fun insert(appCrash: AppCrash): Long - - suspend fun deleteAllByPackageName(appCrash: AppCrash) -} - internal class CrashesRepositoryImpl @Inject constructor( private val notificationsController: CrashesNotificationsController, private val database: AppDatabase, diff --git a/feature/crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/repository/DisabledAppsRepository.kt b/feature/crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/data/DisabledAppsRepositoryImpl.kt similarity index 85% rename from feature/crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/repository/DisabledAppsRepository.kt rename to feature/crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/data/DisabledAppsRepositoryImpl.kt index 2bf10270..101bed3a 100644 --- a/feature/crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/repository/DisabledAppsRepository.kt +++ b/feature/crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/data/DisabledAppsRepositoryImpl.kt @@ -1,9 +1,9 @@ -package com.f0x1d.logfox.feature.crashes.core.repository +package com.f0x1d.logfox.feature.crashes.impl.data import com.f0x1d.logfox.arch.di.IODispatcher -import com.f0x1d.logfox.arch.repository.DatabaseProxyRepository import com.f0x1d.logfox.database.AppDatabase import com.f0x1d.logfox.database.entity.DisabledApp +import com.f0x1d.logfox.feature.crashes.api.data.DisabledAppsRepository import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.distinctUntilChanged @@ -12,14 +12,6 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.withContext import javax.inject.Inject -interface DisabledAppsRepository : DatabaseProxyRepository { - suspend fun isDisabledFor(packageName: String): Boolean - fun disabledForFlow(packageName: String): Flow - - suspend fun checkApp(packageName: String) - suspend fun checkApp(packageName: String, checked: Boolean) -} - internal class DisabledAppsRepositoryImpl @Inject constructor( private val database: AppDatabase, @IODispatcher private val ioDispatcher: CoroutineDispatcher, diff --git a/feature/crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/repository/reader/ANRDetector.kt b/feature/crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/data/reader/ANRDetector.kt similarity index 84% rename from feature/crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/repository/reader/ANRDetector.kt rename to feature/crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/data/reader/ANRDetector.kt index b0bf57c9..ef4f8389 100644 --- a/feature/crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/repository/reader/ANRDetector.kt +++ b/feature/crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/data/reader/ANRDetector.kt @@ -1,9 +1,9 @@ -package com.f0x1d.logfox.feature.crashes.core.repository.reader +package com.f0x1d.logfox.feature.crashes.impl.data.reader import android.content.Context import com.f0x1d.logfox.database.entity.AppCrash import com.f0x1d.logfox.database.entity.CrashType -import com.f0x1d.logfox.feature.crashes.core.repository.reader.base.BaseCrashDetector +import com.f0x1d.logfox.feature.crashes.impl.data.reader.base.BaseCrashDetector import com.f0x1d.logfox.model.logline.LogLine internal class ANRDetector( diff --git a/feature/crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/repository/reader/JNICrashDetector.kt b/feature/crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/data/reader/JNICrashDetector.kt similarity index 92% rename from feature/crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/repository/reader/JNICrashDetector.kt rename to feature/crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/data/reader/JNICrashDetector.kt index 1f3464b1..52e6c520 100644 --- a/feature/crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/repository/reader/JNICrashDetector.kt +++ b/feature/crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/data/reader/JNICrashDetector.kt @@ -1,9 +1,9 @@ -package com.f0x1d.logfox.feature.crashes.core.repository.reader +package com.f0x1d.logfox.feature.crashes.impl.data.reader import android.content.Context import com.f0x1d.logfox.database.entity.AppCrash import com.f0x1d.logfox.database.entity.CrashType -import com.f0x1d.logfox.feature.crashes.core.repository.reader.base.BaseCrashDetector +import com.f0x1d.logfox.feature.crashes.impl.data.reader.base.BaseCrashDetector import com.f0x1d.logfox.model.logline.LogLine import com.f0x1d.logfox.preferences.shared.appPreferences diff --git a/feature/crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/repository/reader/JavaCrashDetector.kt b/feature/crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/data/reader/JavaCrashDetector.kt similarity index 82% rename from feature/crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/repository/reader/JavaCrashDetector.kt rename to feature/crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/data/reader/JavaCrashDetector.kt index 563fc52d..f5b9c57e 100644 --- a/feature/crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/repository/reader/JavaCrashDetector.kt +++ b/feature/crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/data/reader/JavaCrashDetector.kt @@ -1,9 +1,9 @@ -package com.f0x1d.logfox.feature.crashes.core.repository.reader +package com.f0x1d.logfox.feature.crashes.impl.data.reader import android.content.Context import com.f0x1d.logfox.database.entity.AppCrash import com.f0x1d.logfox.database.entity.CrashType -import com.f0x1d.logfox.feature.crashes.core.repository.reader.base.BaseCrashDetector +import com.f0x1d.logfox.feature.crashes.impl.data.reader.base.BaseCrashDetector import com.f0x1d.logfox.model.logline.LogLine internal class JavaCrashDetector( diff --git a/feature/crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/repository/reader/base/BaseCrashDetector.kt b/feature/crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/data/reader/base/BaseCrashDetector.kt similarity index 96% rename from feature/crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/repository/reader/base/BaseCrashDetector.kt rename to feature/crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/data/reader/base/BaseCrashDetector.kt index d8967d58..74c0dd1d 100644 --- a/feature/crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/repository/reader/base/BaseCrashDetector.kt +++ b/feature/crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/data/reader/base/BaseCrashDetector.kt @@ -1,4 +1,4 @@ -package com.f0x1d.logfox.feature.crashes.core.repository.reader.base +package com.f0x1d.logfox.feature.crashes.impl.data.reader.base import android.content.Context import com.f0x1d.logfox.database.entity.AppCrash @@ -69,7 +69,7 @@ internal abstract class BaseCrashDetector( lines: List, ) = context.run { val appName = try { - packageManager.getPackageInfo(crashedAppPackageName, 0).applicationInfo.let { + packageManager.getPackageInfo(crashedAppPackageName, 0).applicationInfo?.let { packageManager.getApplicationLabel(it).toString() } } catch (e: Exception) { diff --git a/feature/crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/repository/reader/base/DefaultChecker.kt b/feature/crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/data/reader/base/DefaultChecker.kt similarity index 85% rename from feature/crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/repository/reader/base/DefaultChecker.kt rename to feature/crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/data/reader/base/DefaultChecker.kt index b5544078..67afceb9 100644 --- a/feature/crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/repository/reader/base/DefaultChecker.kt +++ b/feature/crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/data/reader/base/DefaultChecker.kt @@ -1,4 +1,4 @@ -package com.f0x1d.logfox.feature.crashes.core.repository.reader.base +package com.f0x1d.logfox.feature.crashes.impl.data.reader.base import com.f0x1d.logfox.model.logline.LogLine diff --git a/feature/crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/di/ControllersModule.kt b/feature/crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/di/ControllersModule.kt similarity index 57% rename from feature/crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/di/ControllersModule.kt rename to feature/crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/di/ControllersModule.kt index 0fb72389..e042eaed 100644 --- a/feature/crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/di/ControllersModule.kt +++ b/feature/crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/di/ControllersModule.kt @@ -1,9 +1,9 @@ -package com.f0x1d.logfox.feature.crashes.core.di +package com.f0x1d.logfox.feature.crashes.impl.di -import com.f0x1d.logfox.feature.crashes.core.controller.CrashesController -import com.f0x1d.logfox.feature.crashes.core.controller.CrashesControllerImpl -import com.f0x1d.logfox.feature.crashes.core.controller.CrashesNotificationsController -import com.f0x1d.logfox.feature.crashes.core.controller.CrashesNotificationsControllerImpl +import com.f0x1d.logfox.feature.crashes.api.data.CrashesController +import com.f0x1d.logfox.feature.crashes.api.data.CrashesNotificationsController +import com.f0x1d.logfox.feature.crashes.impl.data.CrashesControllerImpl +import com.f0x1d.logfox.feature.crashes.impl.data.CrashesNotificationsControllerImpl import dagger.Binds import dagger.Module import dagger.hilt.InstallIn diff --git a/feature/crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/di/RepositoriesModule.kt b/feature/crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/di/RepositoriesModule.kt similarity index 56% rename from feature/crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/di/RepositoriesModule.kt rename to feature/crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/di/RepositoriesModule.kt index 7249bba7..d6816df4 100644 --- a/feature/crashes-core/src/main/kotlin/com/f0x1d/logfox/feature/crashes/core/di/RepositoriesModule.kt +++ b/feature/crashes/impl/src/main/kotlin/com/f0x1d/logfox/feature/crashes/impl/di/RepositoriesModule.kt @@ -1,9 +1,9 @@ -package com.f0x1d.logfox.feature.crashes.core.di +package com.f0x1d.logfox.feature.crashes.impl.di -import com.f0x1d.logfox.feature.crashes.core.repository.CrashesRepository -import com.f0x1d.logfox.feature.crashes.core.repository.CrashesRepositoryImpl -import com.f0x1d.logfox.feature.crashes.core.repository.DisabledAppsRepository -import com.f0x1d.logfox.feature.crashes.core.repository.DisabledAppsRepositoryImpl +import com.f0x1d.logfox.feature.crashes.api.data.CrashesRepository +import com.f0x1d.logfox.feature.crashes.api.data.DisabledAppsRepository +import com.f0x1d.logfox.feature.crashes.impl.data.CrashesRepositoryImpl +import com.f0x1d.logfox.feature.crashes.impl.data.DisabledAppsRepositoryImpl import dagger.Binds import dagger.Module import dagger.hilt.InstallIn diff --git a/feature/crashes/list/.gitignore b/feature/crashes/list/.gitignore new file mode 100644 index 00000000..42afabfd --- /dev/null +++ b/feature/crashes/list/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/feature/crashes/list/build.gradle.kts b/feature/crashes/list/build.gradle.kts new file mode 100644 index 00000000..2d464dba --- /dev/null +++ b/feature/crashes/list/build.gradle.kts @@ -0,0 +1,12 @@ +plugins { + id("logfox.android.feature") +} + +android.namespace = "com.f0x1d.logfox.feature.crashes.list" + +dependencies { + implementation(projects.feature.crashes.api) + implementation(projects.feature.crashes.common) + + implementation(projects.feature.appsPicker.api) +} diff --git a/feature/crashes/list/src/main/kotlin/com/f0x1d/logfox/feature/crashes/list/presentation/CrashesAction.kt b/feature/crashes/list/src/main/kotlin/com/f0x1d/logfox/feature/crashes/list/presentation/CrashesAction.kt new file mode 100644 index 00000000..67f33d25 --- /dev/null +++ b/feature/crashes/list/src/main/kotlin/com/f0x1d/logfox/feature/crashes/list/presentation/CrashesAction.kt @@ -0,0 +1,3 @@ +package com.f0x1d.logfox.feature.crashes.list.presentation + +sealed interface CrashesAction diff --git a/feature/crashes/list/src/main/kotlin/com/f0x1d/logfox/feature/crashes/list/presentation/CrashesState.kt b/feature/crashes/list/src/main/kotlin/com/f0x1d/logfox/feature/crashes/list/presentation/CrashesState.kt new file mode 100644 index 00000000..f4c0b7fc --- /dev/null +++ b/feature/crashes/list/src/main/kotlin/com/f0x1d/logfox/feature/crashes/list/presentation/CrashesState.kt @@ -0,0 +1,12 @@ +package com.f0x1d.logfox.feature.crashes.list.presentation + +import com.f0x1d.logfox.database.entity.AppCrashesCount +import com.f0x1d.logfox.preferences.shared.crashes.CrashesSort + +data class CrashesState( + val crashes: List = emptyList(), + val searchedCrashes: List = emptyList(), + val currentSort: CrashesSort = CrashesSort.NEW, + val sortInReversedOrder: Boolean = false, + val query: String? = null, +) diff --git a/feature/crashes/list/src/main/kotlin/com/f0x1d/logfox/feature/crashes/list/presentation/CrashesViewModel.kt b/feature/crashes/list/src/main/kotlin/com/f0x1d/logfox/feature/crashes/list/presentation/CrashesViewModel.kt new file mode 100644 index 00000000..cdffcce5 --- /dev/null +++ b/feature/crashes/list/src/main/kotlin/com/f0x1d/logfox/feature/crashes/list/presentation/CrashesViewModel.kt @@ -0,0 +1,154 @@ +package com.f0x1d.logfox.feature.crashes.list.presentation + +import android.app.Application +import android.content.Context +import androidx.lifecycle.viewModelScope +import com.f0x1d.logfox.arch.di.DefaultDispatcher +import com.f0x1d.logfox.arch.viewmodel.BaseViewModel +import com.f0x1d.logfox.database.entity.AppCrash +import com.f0x1d.logfox.database.entity.AppCrashesCount +import com.f0x1d.logfox.database.entity.DisabledApp +import com.f0x1d.logfox.feature.apps.picker.AppsPickerResultHandler +import com.f0x1d.logfox.feature.apps.picker.InstalledApp +import com.f0x1d.logfox.feature.crashes.api.data.CrashesRepository +import com.f0x1d.logfox.feature.crashes.api.data.DisabledAppsRepository +import com.f0x1d.logfox.preferences.shared.AppPreferences +import com.f0x1d.logfox.preferences.shared.crashes.CrashesSort +import com.f0x1d.logfox.strings.Strings +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +class CrashesViewModel @Inject constructor( + private val crashesRepository: CrashesRepository, + private val disabledAppsRepository: DisabledAppsRepository, + private val appPreferences: AppPreferences, + @DefaultDispatcher private val defaultDispatcher: CoroutineDispatcher, + application: Application, +): BaseViewModel( + initialStateProvider = { CrashesState() }, + application = application, +), AppsPickerResultHandler { + init { + load() + } + + private fun load() { + viewModelScope.launch { + combine( + crashesRepository.getAllAsFlow(), + appPreferences.crashesSortType.asFlow(), + appPreferences.crashesSortReversedOrder.asFlow(), + ) { crashes, sortType, sortInReversedOrder -> + val groupedCrashes = crashes.groupBy { it.packageName } + + val appCrashes = groupedCrashes.map { + AppCrashesCount( + lastCrash = it.value.first(), + count = it.value.size + ) + }.let(sortType.sorter).let { result -> + if (sortInReversedOrder) { + result.asReversed() + } else { + result + } + } + + CrashesWithSort( + crashes = appCrashes, + sortType = sortType, + sortInReversedOrder = sortInReversedOrder, + ) + } + .distinctUntilChanged() + .flowOn(defaultDispatcher) + .onEach { data -> + reduce { + copy( + crashes = data.crashes, + currentSort = data.sortType, + sortInReversedOrder = data.sortInReversedOrder, + ) + } + } + .launchIn(this) + + combine( + crashesRepository.getAllAsFlow().distinctUntilChanged(), + state.map { it.query.orEmpty() }, + ) { crashes, query -> crashes to query } + .map { (crashes, query) -> + crashes.filter { crash -> + crash.packageName.contains(query, ignoreCase = true) + || crash.appName?.contains(query, ignoreCase = true) == true + }.map { AppCrashesCount(it) } + } + .distinctUntilChanged() + .flowOn(defaultDispatcher) + .onEach { searchedCrashes -> + reduce { copy(searchedCrashes = searchedCrashes) } + } + .launchIn(this) + } + } + + fun updateQuery(query: String) = reduce { + copy(query = query) + } + + fun updateSort(sortType: CrashesSort, sortInReversedOrder: Boolean) = appPreferences.updateCrashesSortSettings( + sortType = sortType, + sortInReversedOrder = sortInReversedOrder, + ) + + fun deleteCrashesByPackageName(appCrash: AppCrash) = launchCatching { + crashesRepository.deleteAllByPackageName(appCrash) + } + + fun deleteCrash(appCrash: AppCrash) = launchCatching { + crashesRepository.delete(appCrash) + } + + fun clearCrashes() = launchCatching { + crashesRepository.clear() + } + + override val supportsMultiplySelection: Boolean = true + + override val checkedAppPackageNames: Flow> = + disabledAppsRepository.getAllAsFlow().map { apps -> + apps.map(DisabledApp::packageName).toSet() + } + + override fun providePickerTopAppBarTitle(context: Context): String = + context.getString(Strings.blacklist) + + override fun onAppChecked(app: InstalledApp, checked: Boolean) { + viewModelScope.launch { + disabledAppsRepository.checkApp(app.packageName, checked) + } + } + + override fun onAppSelected(app: InstalledApp): Boolean { + viewModelScope.launch { + disabledAppsRepository.checkApp(app.packageName) + } + return false + } + + private data class CrashesWithSort( + val crashes: List, + val sortType: CrashesSort, + val sortInReversedOrder: Boolean, + ) +} diff --git a/feature/crashes/src/main/kotlin/com/f0x1d/logfox/feature/crashes/ui/fragment/list/CrashesFragment.kt b/feature/crashes/list/src/main/kotlin/com/f0x1d/logfox/feature/crashes/list/presentation/ui/CrashesFragment.kt similarity index 84% rename from feature/crashes/src/main/kotlin/com/f0x1d/logfox/feature/crashes/ui/fragment/list/CrashesFragment.kt rename to feature/crashes/list/src/main/kotlin/com/f0x1d/logfox/feature/crashes/list/presentation/ui/CrashesFragment.kt index d2e102ba..83b522b9 100644 --- a/feature/crashes/src/main/kotlin/com/f0x1d/logfox/feature/crashes/ui/fragment/list/CrashesFragment.kt +++ b/feature/crashes/list/src/main/kotlin/com/f0x1d/logfox/feature/crashes/list/presentation/ui/CrashesFragment.kt @@ -1,4 +1,4 @@ -package com.f0x1d.logfox.feature.crashes.ui.fragment.list +package com.f0x1d.logfox.feature.crashes.list.presentation.ui import android.os.Bundle import android.view.LayoutInflater @@ -12,13 +12,13 @@ import androidx.hilt.navigation.fragment.hiltNavGraphViewModels import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.LinearLayoutManager import com.f0x1d.logfox.arch.isHorizontalOrientation -import com.f0x1d.logfox.arch.ui.fragment.BaseViewModelFragment -import com.f0x1d.logfox.feature.crashes.R -import com.f0x1d.logfox.feature.crashes.adapter.CrashesAdapter -import com.f0x1d.logfox.feature.crashes.databinding.DialogSortingBinding -import com.f0x1d.logfox.feature.crashes.databinding.FragmentCrashesBinding -import com.f0x1d.logfox.feature.crashes.databinding.ItemSortBinding -import com.f0x1d.logfox.feature.crashes.viewmodel.list.CrashesViewModel +import com.f0x1d.logfox.arch.presentation.ui.fragment.BaseFragment +import com.f0x1d.logfox.feature.crashes.common.presentation.adapter.CrashesAdapter +import com.f0x1d.logfox.feature.crashes.list.R +import com.f0x1d.logfox.feature.crashes.list.databinding.DialogSortingBinding +import com.f0x1d.logfox.feature.crashes.list.databinding.FragmentCrashesBinding +import com.f0x1d.logfox.feature.crashes.list.databinding.ItemSortBinding +import com.f0x1d.logfox.feature.crashes.list.presentation.CrashesViewModel import com.f0x1d.logfox.navigation.Directions import com.f0x1d.logfox.preferences.shared.crashes.CrashesSort import com.f0x1d.logfox.strings.Strings @@ -33,9 +33,9 @@ import dagger.hilt.android.AndroidEntryPoint import dev.chrisbanes.insetter.applyInsetter @AndroidEntryPoint -class CrashesFragment: BaseViewModelFragment() { +class CrashesFragment : BaseFragment() { - override val viewModel by hiltNavGraphViewModels(Directions.crashesFragment) + private val viewModel by hiltNavGraphViewModels(Directions.crashesFragment) private val adapter = CrashesAdapter( click = { @@ -146,13 +146,11 @@ class CrashesFragment: BaseViewModelFragment + binding.placeholderLayout.root.isVisible = state.crashes.isEmpty() - adapter.submitList(it) - } - viewModel.searchedCrashes.collectWithLifecycle { - searchedAdapter.submitList(it) + adapter.submitList(state.crashes) + searchedAdapter.submitList(state.searchedCrashes) } requireActivity().onBackPressedDispatcher.apply { @@ -161,8 +159,8 @@ class CrashesFragment: BaseViewModelFragment @@ -181,7 +179,7 @@ class CrashesFragment: BaseViewModelFragment - crashes.filter { crash -> - crash.packageName == packageName - }.map { - AppCrashesCount(it) - } - } - .flowOn(defaultDispatcher) - .stateIn( - scope = viewModelScope, - started = SharingStarted.Eagerly, - initialValue = emptyList(), - ) - - fun deleteCrash(appCrash: AppCrash) = launchCatching { - crashesRepository.delete(appCrash) - } -} diff --git a/feature/crashes/src/main/kotlin/com/f0x1d/logfox/feature/crashes/viewmodel/list/CrashesViewModel.kt b/feature/crashes/src/main/kotlin/com/f0x1d/logfox/feature/crashes/viewmodel/list/CrashesViewModel.kt deleted file mode 100644 index 6f3860c5..00000000 --- a/feature/crashes/src/main/kotlin/com/f0x1d/logfox/feature/crashes/viewmodel/list/CrashesViewModel.kt +++ /dev/null @@ -1,150 +0,0 @@ -package com.f0x1d.logfox.feature.crashes.viewmodel.list - -import android.app.Application -import android.content.Context -import androidx.lifecycle.viewModelScope -import com.f0x1d.logfox.arch.di.DefaultDispatcher -import com.f0x1d.logfox.arch.viewmodel.BaseViewModel -import com.f0x1d.logfox.database.entity.AppCrash -import com.f0x1d.logfox.database.entity.AppCrashesCount -import com.f0x1d.logfox.database.entity.DisabledApp -import com.f0x1d.logfox.feature.apps.picker.viewmodel.AppsPickerResultHandler -import com.f0x1d.logfox.feature.crashes.core.repository.CrashesRepository -import com.f0x1d.logfox.feature.crashes.core.repository.DisabledAppsRepository -import com.f0x1d.logfox.model.InstalledApp -import com.f0x1d.logfox.preferences.shared.AppPreferences -import com.f0x1d.logfox.preferences.shared.crashes.CrashesSort -import com.f0x1d.logfox.strings.Strings -import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.SharingStarted -import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.flowOn -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.stateIn -import kotlinx.coroutines.flow.update -import kotlinx.coroutines.launch -import javax.inject.Inject - -@HiltViewModel -class CrashesViewModel @Inject constructor( - private val crashesRepository: CrashesRepository, - private val disabledAppsRepository: DisabledAppsRepository, - private val appPreferences: AppPreferences, - @DefaultDispatcher private val defaultDispatcher: CoroutineDispatcher, - application: Application, -): BaseViewModel(application), AppsPickerResultHandler { - - val currentSort get() = appPreferences.crashesSortType.get() - val currentSortInReversedOrder get() = appPreferences.crashesSortReversedOrder.get() - - val crashes = combine( - crashesRepository.getAllAsFlow(), - appPreferences.crashesSortType.asFlow(), - appPreferences.crashesSortReversedOrder.asFlow(), - ) { crashes, sortType, sortInReversedOrder -> - CrashesWithSort( - crashes = crashes, - sortType = sortType, - sortInReversedOrder = sortInReversedOrder, - ) - } - .distinctUntilChanged() - .map { crashesWithSort -> - val groupedCrashes = crashesWithSort.crashes.groupBy { it.packageName } - - groupedCrashes.map { - AppCrashesCount( - lastCrash = it.value.first(), - count = it.value.size - ) - }.let(crashesWithSort.sortType.sorter).let { result -> - if (crashesWithSort.sortInReversedOrder) { - result.asReversed() - } else { - result - } - } - } - .flowOn(defaultDispatcher) - .stateIn( - scope = viewModelScope, - started = SharingStarted.Eagerly, - initialValue = emptyList(), - ) - - val query = MutableStateFlow("") - - val searchedCrashes = combine( - crashesRepository.getAllAsFlow(), - query, - ) { crashes, query -> crashes to query } - .map { (crashes, query) -> - crashes.filter { crash -> - crash.packageName.contains(query, ignoreCase = true) - || crash.appName?.contains(query, ignoreCase = true) == true - }.map { AppCrashesCount(it) } - } - .distinctUntilChanged() - .flowOn(defaultDispatcher) - .stateIn( - scope = viewModelScope, - started = SharingStarted.Eagerly, - initialValue = emptyList(), - ) - - fun updateQuery(query: String) = this.query.update { query } - - fun updateSort(sortType: CrashesSort, sortInReversedOrder: Boolean) = appPreferences.updateCrashesSortSettings( - sortType = sortType, - sortInReversedOrder = sortInReversedOrder, - ) - - fun deleteCrashesByPackageName(appCrash: AppCrash) = launchCatching { - crashesRepository.deleteAllByPackageName(appCrash) - } - - fun deleteCrash(appCrash: AppCrash) = launchCatching { - crashesRepository.delete(appCrash) - } - - fun clearCrashes() = launchCatching { - crashesRepository.clear() - } - - override val supportsMultiplySelection: Boolean = true - - override val checkedAppPackageNames: Flow> = - disabledAppsRepository.getAllAsFlow().map { apps -> - apps.map(DisabledApp::packageName).toSet() - } - - override fun providePickerTopAppBarTitle(context: Context): String = - context.getString(Strings.blacklist) - - override fun onAppChecked(app: InstalledApp, checked: Boolean) { - viewModelScope.launch { - disabledAppsRepository.checkApp(app.packageName, checked) - } - } - - override fun onAppSelected(app: InstalledApp): Boolean { - viewModelScope.launch { - disabledAppsRepository.checkApp(app.packageName) - } - return false - } - - private data class CrashesWithSort( - val crashes: List, - val sortType: CrashesSort, - val sortInReversedOrder: Boolean, - ) - - companion object { - private const val SEARCH_DEBOUNCE_MILLIS = 500L - } -} diff --git a/feature/filters-core/.gitignore b/feature/filters/api/.gitignore similarity index 100% rename from feature/filters-core/.gitignore rename to feature/filters/api/.gitignore diff --git a/feature/logging-core/build.gradle.kts b/feature/filters/api/build.gradle.kts similarity index 52% rename from feature/logging-core/build.gradle.kts rename to feature/filters/api/build.gradle.kts index 6f91f895..82120138 100644 --- a/feature/logging-core/build.gradle.kts +++ b/feature/filters/api/build.gradle.kts @@ -2,7 +2,7 @@ plugins { id("logfox.android.feature") } -android.namespace = "com.f0x1d.logfox.feature.logging.core" +android.namespace = "com.f0x1d.logfox.feature.filters.api" dependencies { diff --git a/feature/filters/api/src/main/kotlin/com/f0x1d/logfox/feature/filters/api/data/FiltersRepository.kt b/feature/filters/api/src/main/kotlin/com/f0x1d/logfox/feature/filters/api/data/FiltersRepository.kt new file mode 100644 index 00000000..04078610 --- /dev/null +++ b/feature/filters/api/src/main/kotlin/com/f0x1d/logfox/feature/filters/api/data/FiltersRepository.kt @@ -0,0 +1,38 @@ +package com.f0x1d.logfox.feature.filters.api.data + +import com.f0x1d.logfox.arch.repository.DatabaseProxyRepository +import com.f0x1d.logfox.database.entity.UserFilter +import com.f0x1d.logfox.model.logline.LogLevel +import kotlinx.coroutines.flow.Flow + +interface FiltersRepository : DatabaseProxyRepository { + + fun getAllEnabledAsFlow(): Flow> + + suspend fun create( + including: Boolean, + enabledLogLevels: List, + uid: String?, + pid: String?, + tid: String?, + packageName: String?, + tag: String?, + content: String?, + ) + + suspend fun createAll(userFilters: List) + + suspend fun switch(userFilter: UserFilter, checked: Boolean) + + suspend fun update( + userFilter: UserFilter, + including: Boolean, + enabledLogLevels: List, + uid: String?, + pid: String?, + tid: String?, + packageName: String?, + tag: String?, + content: String?, + ) +} diff --git a/feature/filters/build.gradle.kts b/feature/filters/build.gradle.kts deleted file mode 100644 index 045b15ad..00000000 --- a/feature/filters/build.gradle.kts +++ /dev/null @@ -1,12 +0,0 @@ -plugins { - id("logfox.android.feature") -} - -android.namespace = "com.f0x1d.logfox.feature.filters" - -dependencies { - implementation(projects.feature.appsPicker) - implementation(projects.feature.filtersCore) - - implementation(libs.gson) -} diff --git a/feature/filters/edit/.gitignore b/feature/filters/edit/.gitignore new file mode 100644 index 00000000..42afabfd --- /dev/null +++ b/feature/filters/edit/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/feature/filters/edit/build.gradle.kts b/feature/filters/edit/build.gradle.kts new file mode 100644 index 00000000..922ec355 --- /dev/null +++ b/feature/filters/edit/build.gradle.kts @@ -0,0 +1,12 @@ +plugins { + id("logfox.android.feature") +} + +android.namespace = "com.f0x1d.logfox.feature.filters.edit" + +dependencies { + implementation(projects.feature.appsPicker.api) + implementation(projects.feature.filters.api) + + implementation(libs.gson) +} diff --git a/feature/filters/src/main/kotlin/com/f0x1d/logfox/feature/filters/di/EditFilterViewModelModule.kt b/feature/filters/edit/src/main/kotlin/com/f0x1d/logfox/feature/filters/edit/di/EditFilterViewModelModule.kt similarity index 92% rename from feature/filters/src/main/kotlin/com/f0x1d/logfox/feature/filters/di/EditFilterViewModelModule.kt rename to feature/filters/edit/src/main/kotlin/com/f0x1d/logfox/feature/filters/edit/di/EditFilterViewModelModule.kt index 32188533..5ff3d8d9 100644 --- a/feature/filters/src/main/kotlin/com/f0x1d/logfox/feature/filters/di/EditFilterViewModelModule.kt +++ b/feature/filters/edit/src/main/kotlin/com/f0x1d/logfox/feature/filters/edit/di/EditFilterViewModelModule.kt @@ -1,4 +1,4 @@ -package com.f0x1d.logfox.feature.filters.di +package com.f0x1d.logfox.feature.filters.edit.di import androidx.lifecycle.SavedStateHandle import dagger.Module diff --git a/feature/filters/edit/src/main/kotlin/com/f0x1d/logfox/feature/filters/edit/presentation/EditFilterAction.kt b/feature/filters/edit/src/main/kotlin/com/f0x1d/logfox/feature/filters/edit/presentation/EditFilterAction.kt new file mode 100644 index 00000000..c4ef1a3f --- /dev/null +++ b/feature/filters/edit/src/main/kotlin/com/f0x1d/logfox/feature/filters/edit/presentation/EditFilterAction.kt @@ -0,0 +1,5 @@ +package com.f0x1d.logfox.feature.filters.edit.presentation + +sealed interface EditFilterAction { + data class UpdatePackageNameText(val packageName: String) : EditFilterAction +} diff --git a/feature/filters/edit/src/main/kotlin/com/f0x1d/logfox/feature/filters/edit/presentation/EditFilterState.kt b/feature/filters/edit/src/main/kotlin/com/f0x1d/logfox/feature/filters/edit/presentation/EditFilterState.kt new file mode 100644 index 00000000..ed3d3ce5 --- /dev/null +++ b/feature/filters/edit/src/main/kotlin/com/f0x1d/logfox/feature/filters/edit/presentation/EditFilterState.kt @@ -0,0 +1,9 @@ +package com.f0x1d.logfox.feature.filters.edit.presentation + +import com.f0x1d.logfox.database.entity.UserFilter + +data class EditFilterState( + val filter: UserFilter? = null, + val including: Boolean = true, + val enabledLogLevels: List = emptyList(), +) diff --git a/feature/filters/edit/src/main/kotlin/com/f0x1d/logfox/feature/filters/edit/presentation/EditFilterViewModel.kt b/feature/filters/edit/src/main/kotlin/com/f0x1d/logfox/feature/filters/edit/presentation/EditFilterViewModel.kt new file mode 100644 index 00000000..c1319cfc --- /dev/null +++ b/feature/filters/edit/src/main/kotlin/com/f0x1d/logfox/feature/filters/edit/presentation/EditFilterViewModel.kt @@ -0,0 +1,133 @@ +package com.f0x1d.logfox.feature.filters.edit.presentation + +import android.app.Application +import android.net.Uri +import androidx.lifecycle.viewModelScope +import com.f0x1d.logfox.arch.di.IODispatcher +import com.f0x1d.logfox.arch.viewmodel.BaseViewModel +import com.f0x1d.logfox.feature.apps.picker.AppsPickerResultHandler +import com.f0x1d.logfox.feature.apps.picker.InstalledApp +import com.f0x1d.logfox.feature.filters.api.data.FiltersRepository +import com.f0x1d.logfox.model.logline.LogLevel +import com.google.gson.Gson +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.take +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +class EditFilterViewModel @Inject constructor( + @com.f0x1d.logfox.feature.filters.edit.di.FilterId val filterId: Long?, + private val filtersRepository: FiltersRepository, + private val gson: Gson, + @IODispatcher private val ioDispatcher: CoroutineDispatcher, + application: Application, +): BaseViewModel( + initialStateProvider = { EditFilterState() }, + application = application, +), AppsPickerResultHandler { + var uid: String? = null + var pid: String? = null + var tid: String? = null + var packageName: String? = null + var tag: String? = null + var content: String? = null + + init { + load() + } + + private fun load() { + viewModelScope.launch { + filtersRepository.getByIdAsFlow(filterId ?: -1L) + .distinctUntilChanged() + .take(1) // Not to handle changes + .collect { filter -> + if (filter == null) return@collect + + val enabledLogLevels = List(7) { false }.toMutableList() + val allowedLevels = filter.allowedLevels.map { it.ordinal } + for (i in 0 until enabledLogLevels.size) { + enabledLogLevels[i] = allowedLevels.contains(i) + } + + uid = filter.uid + pid = filter.pid + tid = filter.tid + packageName = filter.packageName + tag = filter.tag + content = filter.content + + reduce { + copy( + filter = filter, + including = filter.including, + enabledLogLevels = enabledLogLevels, + ) + } + } + } + } + + fun save() = launchCatching { + val state = currentState + + if (state.filter == null) { + filtersRepository.create( + including = state.including, + enabledLogLevels = state.enabledLogLevels.toEnabledLogLevels(), + uid = uid, + pid = pid, + tid = tid, + packageName = packageName, + tag = tag, + content = content, + ) + } else { + filtersRepository.update( + userFilter = state.filter, + including = state.including, + enabledLogLevels = state.enabledLogLevels.toEnabledLogLevels(), + uid = uid, + pid = pid, + tid = tid, + packageName = packageName, + tag = tag, + content = content, + ) + } + } + + fun export(uri: Uri) = launchCatching(ioDispatcher) { + ctx.contentResolver.openOutputStream(uri)?.use { outputStream -> + val filters = listOfNotNull(currentState.filter) + + outputStream.write(gson.toJson(filters).encodeToByteArray()) + } + } + + fun toggleIncluding() = reduce { copy(including = including.not()) } + + fun filterLevel(which: Int, filtering: Boolean) = reduce { + copy( + enabledLogLevels = enabledLogLevels.toMutableList().apply { + this[which] = filtering + }, + ) + } + + override fun onAppSelected(app: InstalledApp): Boolean { + packageName = app.packageName + sendAction(EditFilterAction.UpdatePackageNameText(app.packageName)) + return true + } + + private fun List.toEnabledLogLevels() = mapIndexed { index, value -> + if (value) + enumValues()[index] + else + null + }.filterNotNull() +} diff --git a/feature/filters/src/main/kotlin/com/f0x1d/logfox/feature/filters/ui/fragment/EditFilterFragment.kt b/feature/filters/edit/src/main/kotlin/com/f0x1d/logfox/feature/filters/edit/presentation/ui/EditFilterFragment.kt similarity index 60% rename from feature/filters/src/main/kotlin/com/f0x1d/logfox/feature/filters/ui/fragment/EditFilterFragment.kt rename to feature/filters/edit/src/main/kotlin/com/f0x1d/logfox/feature/filters/edit/presentation/ui/EditFilterFragment.kt index 3fa577c6..3434d8ad 100644 --- a/feature/filters/src/main/kotlin/com/f0x1d/logfox/feature/filters/ui/fragment/EditFilterFragment.kt +++ b/feature/filters/edit/src/main/kotlin/com/f0x1d/logfox/feature/filters/edit/presentation/ui/EditFilterFragment.kt @@ -1,21 +1,19 @@ -package com.f0x1d.logfox.feature.filters.ui.fragment +package com.f0x1d.logfox.feature.filters.edit.presentation.ui import android.content.res.ColorStateList import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.widget.EditText import androidx.activity.result.contract.ActivityResultContracts import androidx.core.widget.doAfterTextChanged import androidx.hilt.navigation.fragment.hiltNavGraphViewModels import androidx.navigation.fragment.findNavController -import com.f0x1d.logfox.arch.ui.fragment.BaseViewModelFragment -import com.f0x1d.logfox.arch.viewmodel.Event -import com.f0x1d.logfox.feature.filters.R -import com.f0x1d.logfox.feature.filters.databinding.FragmentEditFilterBinding -import com.f0x1d.logfox.feature.filters.viewmodel.EditFilterViewModel -import com.f0x1d.logfox.feature.filters.viewmodel.UpdatePackageNameText +import com.f0x1d.logfox.arch.presentation.ui.fragment.BaseFragment +import com.f0x1d.logfox.feature.filters.edit.R +import com.f0x1d.logfox.feature.filters.edit.databinding.FragmentEditFilterBinding +import com.f0x1d.logfox.feature.filters.edit.presentation.EditFilterAction +import com.f0x1d.logfox.feature.filters.edit.presentation.EditFilterViewModel import com.f0x1d.logfox.model.logline.LogLevel import com.f0x1d.logfox.navigation.Directions import com.f0x1d.logfox.strings.Strings @@ -26,14 +24,11 @@ import com.google.android.material.color.MaterialColors import com.google.android.material.dialog.MaterialAlertDialogBuilder import dagger.hilt.android.AndroidEntryPoint import dev.chrisbanes.insetter.applyInsetter -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.take -import kotlinx.coroutines.flow.update @AndroidEntryPoint -class EditFilterFragment: BaseViewModelFragment() { +class EditFilterFragment : BaseFragment() { - override val viewModel by hiltNavGraphViewModels(Directions.editFilterFragment) + private val viewModel by hiltNavGraphViewModels(Directions.editFilterFragment) private val exportFilterLauncher = registerForActivityResult( ActivityResultContracts.CreateDocument("application/json"), @@ -68,9 +63,14 @@ class EditFilterFragment: BaseViewModelFragment - updateIncludingButton(enabled) - } - - viewModel.filter.collectWithLifecycle { - viewModel.uid.toText(uidText) - viewModel.pid.toText(pidText) - viewModel.tid.toText(tidText) - viewModel.packageName.toText(packageNameText) - viewModel.tag.toText(tagText) - viewModel.content.toText(contentText) + uidText.doAfterTextChanged { viewModel.uid = it?.toString().orEmpty() } + pidText.doAfterTextChanged { viewModel.pid = it?.toString().orEmpty() } + tidText.doAfterTextChanged { viewModel.tid = it?.toString().orEmpty() } + packageNameText.doAfterTextChanged { viewModel.packageName = it?.toString().orEmpty() } + tagText.doAfterTextChanged { viewModel.tag = it?.toString().orEmpty() } + contentText.doAfterTextChanged { viewModel.tag = it?.toString().orEmpty() } - if (it == null) return@collectWithLifecycle + viewModel.state.collectWithLifecycle { state -> + updateIncludingButton(state.including) - toolbar.menu.apply { - findItem(R.id.export_item).isVisible = true + uidText.setText(viewModel.uid.orEmpty()) + pidText.setText(viewModel.pid.orEmpty()) + tidText.setText(viewModel.tid.orEmpty()) + packageNameText.setText(viewModel.packageName.orEmpty()) + tagText.setText(viewModel.tag.orEmpty()) + contentText.setText(viewModel.content.orEmpty()) - setClickListenerOn(R.id.export_item) { - exportFilterLauncher.launch("filter.json") - } - } - - saveFab.setOnClickListener { _ -> - viewModel.update(it) - findNavController().popBackStack() - } + toolbar.menu.findItem(R.id.export_item).isVisible = state.filter != null } - } - - override fun onEvent(event: Event) { - super.onEvent(event) - when (event) { - is UpdatePackageNameText -> { - binding.packageNameText.setText(viewModel.packageName.value) - } - } - } - - private fun MutableStateFlow.toText(editText: EditText) { - take(1).collectWithLifecycle { - editText.apply { - setText(it) - doAfterTextChanged { value -> update { value?.toString() } } + viewModel.actions.collectWithLifecycle { action -> + when (action) { + is EditFilterAction.UpdatePackageNameText -> { + binding.packageNameText.setText(action.packageName) + } } } } @@ -161,7 +142,7 @@ class EditFilterFragment: BaseViewModelFragment viewModel.filterLevel(which, checked) } diff --git a/feature/filters/src/main/res/layout/fragment_edit_filter.xml b/feature/filters/edit/src/main/res/layout/fragment_edit_filter.xml similarity index 100% rename from feature/filters/src/main/res/layout/fragment_edit_filter.xml rename to feature/filters/edit/src/main/res/layout/fragment_edit_filter.xml diff --git a/feature/filters/src/main/res/menu/edit_filter_menu.xml b/feature/filters/edit/src/main/res/menu/edit_filter_menu.xml similarity index 89% rename from feature/filters/src/main/res/menu/edit_filter_menu.xml rename to feature/filters/edit/src/main/res/menu/edit_filter_menu.xml index b3557327..e6721418 100644 --- a/feature/filters/src/main/res/menu/edit_filter_menu.xml +++ b/feature/filters/edit/src/main/res/menu/edit_filter_menu.xml @@ -6,7 +6,6 @@ android:id="@+id/export_item" android:title="@string/export" android:icon="@drawable/ic_export" - android:visible="false" app:showAsAction="always" /> - \ No newline at end of file + diff --git a/feature/filters/.gitignore b/feature/filters/impl/.gitignore similarity index 100% rename from feature/filters/.gitignore rename to feature/filters/impl/.gitignore diff --git a/feature/filters/impl/build.gradle.kts b/feature/filters/impl/build.gradle.kts new file mode 100644 index 00000000..b49ee523 --- /dev/null +++ b/feature/filters/impl/build.gradle.kts @@ -0,0 +1,12 @@ +plugins { + id("logfox.android.feature") +} + +android.namespace = "com.f0x1d.logfox.feature.filters.impl" + +dependencies { + implementation(projects.feature.appsPicker.api) + implementation(projects.feature.filters.api) + + implementation(libs.gson) +} diff --git a/feature/filters-core/src/main/kotlin/com/f0x1d/logfox/feature/filters/core/repository/FiltersRepository.kt b/feature/filters/impl/src/main/kotlin/com/f0x1d/logfox/feature/filters/impl/data/FiltersRepositoryImpl.kt similarity index 79% rename from feature/filters-core/src/main/kotlin/com/f0x1d/logfox/feature/filters/core/repository/FiltersRepository.kt rename to feature/filters/impl/src/main/kotlin/com/f0x1d/logfox/feature/filters/impl/data/FiltersRepositoryImpl.kt index 18f75bb8..50f11a02 100644 --- a/feature/filters-core/src/main/kotlin/com/f0x1d/logfox/feature/filters/core/repository/FiltersRepository.kt +++ b/feature/filters/impl/src/main/kotlin/com/f0x1d/logfox/feature/filters/impl/data/FiltersRepositoryImpl.kt @@ -1,9 +1,9 @@ -package com.f0x1d.logfox.feature.filters.core.repository +package com.f0x1d.logfox.feature.filters.impl.data import com.f0x1d.logfox.arch.di.IODispatcher -import com.f0x1d.logfox.arch.repository.DatabaseProxyRepository import com.f0x1d.logfox.database.AppDatabase import com.f0x1d.logfox.database.entity.UserFilter +import com.f0x1d.logfox.feature.filters.api.data.FiltersRepository import com.f0x1d.logfox.model.logline.LogLevel import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.Flow @@ -12,38 +12,6 @@ import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.withContext import javax.inject.Inject -interface FiltersRepository : DatabaseProxyRepository { - - fun getAllEnabledAsFlow(): Flow> - - suspend fun create( - including: Boolean, - enabledLogLevels: List, - uid: String?, - pid: String?, - tid: String?, - packageName: String?, - tag: String?, - content: String?, - ) - - suspend fun createAll(userFilters: List) - - suspend fun switch(userFilter: UserFilter, checked: Boolean) - - suspend fun update( - userFilter: UserFilter, - including: Boolean, - enabledLogLevels: List, - uid: String?, - pid: String?, - tid: String?, - packageName: String?, - tag: String?, - content: String?, - ) -} - internal class FiltersRepositoryImpl @Inject constructor( private val database: AppDatabase, @IODispatcher private val ioDispatcher: CoroutineDispatcher, diff --git a/feature/filters-core/src/main/kotlin/com/f0x1d/logfox/feature/filters/core/di/RepositoriesModule.kt b/feature/filters/impl/src/main/kotlin/com/f0x1d/logfox/feature/filters/impl/di/RepositoriesModule.kt similarity index 62% rename from feature/filters-core/src/main/kotlin/com/f0x1d/logfox/feature/filters/core/di/RepositoriesModule.kt rename to feature/filters/impl/src/main/kotlin/com/f0x1d/logfox/feature/filters/impl/di/RepositoriesModule.kt index bb1dbff0..3a44cfd9 100644 --- a/feature/filters-core/src/main/kotlin/com/f0x1d/logfox/feature/filters/core/di/RepositoriesModule.kt +++ b/feature/filters/impl/src/main/kotlin/com/f0x1d/logfox/feature/filters/impl/di/RepositoriesModule.kt @@ -1,7 +1,7 @@ -package com.f0x1d.logfox.feature.filters.core.di +package com.f0x1d.logfox.feature.filters.impl.di -import com.f0x1d.logfox.feature.filters.core.repository.FiltersRepository -import com.f0x1d.logfox.feature.filters.core.repository.FiltersRepositoryImpl +import com.f0x1d.logfox.feature.filters.api.data.FiltersRepository +import com.f0x1d.logfox.feature.filters.impl.data.FiltersRepositoryImpl import dagger.Binds import dagger.Module import dagger.hilt.InstallIn diff --git a/feature/filters/list/.gitignore b/feature/filters/list/.gitignore new file mode 100644 index 00000000..42afabfd --- /dev/null +++ b/feature/filters/list/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/feature/filters/list/build.gradle.kts b/feature/filters/list/build.gradle.kts new file mode 100644 index 00000000..aef3028f --- /dev/null +++ b/feature/filters/list/build.gradle.kts @@ -0,0 +1,11 @@ +plugins { + id("logfox.android.feature") +} + +android.namespace = "com.f0x1d.logfox.feature.filters.list" + +dependencies { + implementation(projects.feature.filters.api) + + implementation(libs.gson) +} diff --git a/feature/filters/list/src/main/kotlin/com/f0x1d/logfox/feature/filters/list/presentation/FiltersAction.kt b/feature/filters/list/src/main/kotlin/com/f0x1d/logfox/feature/filters/list/presentation/FiltersAction.kt new file mode 100644 index 00000000..bbb92a0a --- /dev/null +++ b/feature/filters/list/src/main/kotlin/com/f0x1d/logfox/feature/filters/list/presentation/FiltersAction.kt @@ -0,0 +1,3 @@ +package com.f0x1d.logfox.feature.filters.list.presentation + +sealed interface FiltersAction diff --git a/feature/filters/list/src/main/kotlin/com/f0x1d/logfox/feature/filters/list/presentation/FiltersState.kt b/feature/filters/list/src/main/kotlin/com/f0x1d/logfox/feature/filters/list/presentation/FiltersState.kt new file mode 100644 index 00000000..b00ef2f0 --- /dev/null +++ b/feature/filters/list/src/main/kotlin/com/f0x1d/logfox/feature/filters/list/presentation/FiltersState.kt @@ -0,0 +1,7 @@ +package com.f0x1d.logfox.feature.filters.list.presentation + +import com.f0x1d.logfox.database.entity.UserFilter + +data class FiltersState( + val filters: List = emptyList(), +) diff --git a/feature/filters/src/main/kotlin/com/f0x1d/logfox/feature/filters/viewmodel/FiltersViewModel.kt b/feature/filters/list/src/main/kotlin/com/f0x1d/logfox/feature/filters/list/presentation/FiltersViewModel.kt similarity index 71% rename from feature/filters/src/main/kotlin/com/f0x1d/logfox/feature/filters/viewmodel/FiltersViewModel.kt rename to feature/filters/list/src/main/kotlin/com/f0x1d/logfox/feature/filters/list/presentation/FiltersViewModel.kt index 91c1212b..a5a3118b 100644 --- a/feature/filters/src/main/kotlin/com/f0x1d/logfox/feature/filters/viewmodel/FiltersViewModel.kt +++ b/feature/filters/list/src/main/kotlin/com/f0x1d/logfox/feature/filters/list/presentation/FiltersViewModel.kt @@ -1,4 +1,4 @@ -package com.f0x1d.logfox.feature.filters.viewmodel +package com.f0x1d.logfox.feature.filters.list.presentation import android.app.Application import android.net.Uri @@ -6,14 +6,13 @@ import androidx.lifecycle.viewModelScope import com.f0x1d.logfox.arch.di.IODispatcher import com.f0x1d.logfox.arch.viewmodel.BaseViewModel import com.f0x1d.logfox.database.entity.UserFilter -import com.f0x1d.logfox.feature.filters.core.repository.FiltersRepository +import com.f0x1d.logfox.feature.filters.api.data.FiltersRepository import com.google.gson.Gson import com.google.gson.reflect.TypeToken import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.stateIn +import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel @@ -22,15 +21,23 @@ class FiltersViewModel @Inject constructor( private val gson: Gson, @IODispatcher private val ioDispatcher: CoroutineDispatcher, application: Application, -): BaseViewModel(application) { +) : BaseViewModel( + initialStateProvider = { FiltersState() }, + application = application, +) { + init { + load() + } - val filters = filtersRepository.getAllAsFlow() - .distinctUntilChanged() - .stateIn( - scope = viewModelScope, - started = SharingStarted.Eagerly, - initialValue = emptyList(), - ) + private fun load() { + viewModelScope.launch { + filtersRepository.getAllAsFlow() + .distinctUntilChanged() + .collect { filters -> + reduce { copy(filters = filters) } + } + } + } fun import(uri: Uri) = launchCatching(ioDispatcher) { ctx.contentResolver.openInputStream(uri)?.use { @@ -44,7 +51,7 @@ class FiltersViewModel @Inject constructor( } fun exportAll(uri: Uri) = launchCatching(ioDispatcher) { - val filters = filters.value + val filters = currentState.filters ctx.contentResolver.openOutputStream(uri)?.use { it.write(gson.toJson(filters).encodeToByteArray()) diff --git a/feature/filters/list/src/main/kotlin/com/f0x1d/logfox/feature/filters/list/presentation/adapter/FiltersAdapter.kt b/feature/filters/list/src/main/kotlin/com/f0x1d/logfox/feature/filters/list/presentation/adapter/FiltersAdapter.kt new file mode 100644 index 00000000..1e438b24 --- /dev/null +++ b/feature/filters/list/src/main/kotlin/com/f0x1d/logfox/feature/filters/list/presentation/adapter/FiltersAdapter.kt @@ -0,0 +1,24 @@ +package com.f0x1d.logfox.feature.filters.list.presentation.adapter + +import android.view.LayoutInflater +import android.view.ViewGroup +import com.f0x1d.logfox.arch.presentation.adapter.BaseListAdapter +import com.f0x1d.logfox.database.entity.UserFilter +import com.f0x1d.logfox.feature.filters.list.databinding.ItemFilterBinding +import com.f0x1d.logfox.feature.filters.list.presentation.ui.viewholder.FilterViewHolder +import com.f0x1d.logfox.model.diffCallback + +class FiltersAdapter( + private val click: (UserFilter) -> Unit, + private val delete: (UserFilter) -> Unit, + private val checked: (UserFilter, Boolean) -> Unit +) : BaseListAdapter(diffCallback()) { + + override fun createHolder(layoutInflater: LayoutInflater, parent: ViewGroup) = + FilterViewHolder( + binding = ItemFilterBinding.inflate(layoutInflater, parent, false), + click = click, + delete = delete, + checked = checked, + ) +} diff --git a/feature/filters/src/main/kotlin/com/f0x1d/logfox/feature/filters/ui/fragment/FiltersFragment.kt b/feature/filters/list/src/main/kotlin/com/f0x1d/logfox/feature/filters/list/presentation/ui/fragment/FiltersFragment.kt similarity index 81% rename from feature/filters/src/main/kotlin/com/f0x1d/logfox/feature/filters/ui/fragment/FiltersFragment.kt rename to feature/filters/list/src/main/kotlin/com/f0x1d/logfox/feature/filters/list/presentation/ui/fragment/FiltersFragment.kt index 31e1de03..93b6560c 100644 --- a/feature/filters/src/main/kotlin/com/f0x1d/logfox/feature/filters/ui/fragment/FiltersFragment.kt +++ b/feature/filters/list/src/main/kotlin/com/f0x1d/logfox/feature/filters/list/presentation/ui/fragment/FiltersFragment.kt @@ -1,4 +1,4 @@ -package com.f0x1d.logfox.feature.filters.ui.fragment +package com.f0x1d.logfox.feature.filters.list.presentation.ui.fragment import android.os.Bundle import android.view.LayoutInflater @@ -11,11 +11,11 @@ import androidx.fragment.app.viewModels import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.LinearLayoutManager import com.f0x1d.logfox.arch.canPickJSON -import com.f0x1d.logfox.arch.ui.fragment.BaseViewModelFragment -import com.f0x1d.logfox.feature.filters.R -import com.f0x1d.logfox.feature.filters.adapter.FiltersAdapter -import com.f0x1d.logfox.feature.filters.databinding.FragmentFiltersBinding -import com.f0x1d.logfox.feature.filters.viewmodel.FiltersViewModel +import com.f0x1d.logfox.arch.presentation.ui.fragment.BaseFragment +import com.f0x1d.logfox.feature.filters.list.R +import com.f0x1d.logfox.feature.filters.list.databinding.FragmentFiltersBinding +import com.f0x1d.logfox.feature.filters.list.presentation.FiltersViewModel +import com.f0x1d.logfox.feature.filters.list.presentation.adapter.FiltersAdapter import com.f0x1d.logfox.navigation.Directions import com.f0x1d.logfox.ui.dialog.showAreYouSureClearDialog import com.f0x1d.logfox.ui.dialog.showAreYouSureDeleteDialog @@ -25,9 +25,9 @@ import dagger.hilt.android.AndroidEntryPoint import dev.chrisbanes.insetter.applyInsetter @AndroidEntryPoint -class FiltersFragment: BaseViewModelFragment() { +class FiltersFragment : BaseFragment() { - override val viewModel by viewModels() + private val viewModel by viewModels() private val adapter = FiltersAdapter( click = { @@ -96,10 +96,10 @@ class FiltersFragment: BaseViewModelFragment + placeholderLayout.root.isVisible = state.filters.isEmpty() - adapter.submitList(it) + adapter.submitList(state.filters) } } } diff --git a/feature/filters/src/main/kotlin/com/f0x1d/logfox/feature/filters/ui/viewholder/FilterViewHolder.kt b/feature/filters/list/src/main/kotlin/com/f0x1d/logfox/feature/filters/list/presentation/ui/viewholder/FilterViewHolder.kt similarity index 90% rename from feature/filters/src/main/kotlin/com/f0x1d/logfox/feature/filters/ui/viewholder/FilterViewHolder.kt rename to feature/filters/list/src/main/kotlin/com/f0x1d/logfox/feature/filters/list/presentation/ui/viewholder/FilterViewHolder.kt index 8e398cba..d5ffd249 100644 --- a/feature/filters/src/main/kotlin/com/f0x1d/logfox/feature/filters/ui/viewholder/FilterViewHolder.kt +++ b/feature/filters/list/src/main/kotlin/com/f0x1d/logfox/feature/filters/list/presentation/ui/viewholder/FilterViewHolder.kt @@ -1,11 +1,11 @@ -package com.f0x1d.logfox.feature.filters.ui.viewholder +package com.f0x1d.logfox.feature.filters.list.presentation.ui.viewholder import android.text.Html import android.view.View import android.widget.TextView -import com.f0x1d.logfox.arch.ui.viewholder.BaseViewHolder +import com.f0x1d.logfox.arch.presentation.ui.viewholder.BaseViewHolder import com.f0x1d.logfox.database.entity.UserFilter -import com.f0x1d.logfox.feature.filters.databinding.ItemFilterBinding +import com.f0x1d.logfox.feature.filters.list.databinding.ItemFilterBinding import com.f0x1d.logfox.strings.Strings import com.f0x1d.logfox.ui.view.OnlyUserCheckedChangeListener diff --git a/feature/filters/src/main/res/layout/fragment_filters.xml b/feature/filters/list/src/main/res/layout/fragment_filters.xml similarity index 100% rename from feature/filters/src/main/res/layout/fragment_filters.xml rename to feature/filters/list/src/main/res/layout/fragment_filters.xml diff --git a/feature/filters/src/main/res/layout/item_filter.xml b/feature/filters/list/src/main/res/layout/item_filter.xml similarity index 100% rename from feature/filters/src/main/res/layout/item_filter.xml rename to feature/filters/list/src/main/res/layout/item_filter.xml diff --git a/feature/filters/src/main/res/layout/placeholder_filters.xml b/feature/filters/list/src/main/res/layout/placeholder_filters.xml similarity index 100% rename from feature/filters/src/main/res/layout/placeholder_filters.xml rename to feature/filters/list/src/main/res/layout/placeholder_filters.xml diff --git a/feature/filters/src/main/res/menu/filters_menu.xml b/feature/filters/list/src/main/res/menu/filters_menu.xml similarity index 100% rename from feature/filters/src/main/res/menu/filters_menu.xml rename to feature/filters/list/src/main/res/menu/filters_menu.xml diff --git a/feature/filters/src/main/kotlin/com/f0x1d/logfox/feature/filters/adapter/FiltersAdapter.kt b/feature/filters/src/main/kotlin/com/f0x1d/logfox/feature/filters/adapter/FiltersAdapter.kt deleted file mode 100644 index e473e5aa..00000000 --- a/feature/filters/src/main/kotlin/com/f0x1d/logfox/feature/filters/adapter/FiltersAdapter.kt +++ /dev/null @@ -1,32 +0,0 @@ -package com.f0x1d.logfox.feature.filters.adapter - -import android.view.LayoutInflater -import android.view.ViewGroup -import androidx.recyclerview.widget.DiffUtil -import com.f0x1d.logfox.arch.adapter.BaseListAdapter -import com.f0x1d.logfox.database.entity.UserFilter -import com.f0x1d.logfox.feature.filters.databinding.ItemFilterBinding -import com.f0x1d.logfox.feature.filters.ui.viewholder.FilterViewHolder -import com.f0x1d.logfox.model.diffCallback - -class FiltersAdapter( - private val click: (UserFilter) -> Unit, - private val delete: (UserFilter) -> Unit, - private val checked: (UserFilter, Boolean) -> Unit -): BaseListAdapter(diffCallback()) { - - companion object { - private val FILTER_DIFF = object : DiffUtil.ItemCallback() { - override fun areItemsTheSame(oldItem: UserFilter, newItem: UserFilter) = oldItem.id == newItem.id - - override fun areContentsTheSame(oldItem: UserFilter, newItem: UserFilter) = oldItem == newItem - } - } - - override fun createHolder(layoutInflater: LayoutInflater, parent: ViewGroup) = FilterViewHolder( - binding = ItemFilterBinding.inflate(layoutInflater, parent, false), - click = click, - delete = delete, - checked = checked, - ) -} diff --git a/feature/filters/src/main/kotlin/com/f0x1d/logfox/feature/filters/viewmodel/EditFilterViewModel.kt b/feature/filters/src/main/kotlin/com/f0x1d/logfox/feature/filters/viewmodel/EditFilterViewModel.kt deleted file mode 100644 index 726de3cd..00000000 --- a/feature/filters/src/main/kotlin/com/f0x1d/logfox/feature/filters/viewmodel/EditFilterViewModel.kt +++ /dev/null @@ -1,117 +0,0 @@ -package com.f0x1d.logfox.feature.filters.viewmodel - -import android.app.Application -import android.net.Uri -import androidx.lifecycle.viewModelScope -import com.f0x1d.logfox.arch.di.IODispatcher -import com.f0x1d.logfox.arch.viewmodel.BaseViewModel -import com.f0x1d.logfox.arch.viewmodel.Event -import com.f0x1d.logfox.database.entity.UserFilter -import com.f0x1d.logfox.feature.apps.picker.viewmodel.AppsPickerResultHandler -import com.f0x1d.logfox.feature.filters.core.repository.FiltersRepository -import com.f0x1d.logfox.feature.filters.di.FilterId -import com.f0x1d.logfox.model.InstalledApp -import com.f0x1d.logfox.model.logline.LogLevel -import com.google.gson.Gson -import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.SharingStarted -import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.flow.stateIn -import kotlinx.coroutines.flow.take -import kotlinx.coroutines.flow.update -import javax.inject.Inject - -@HiltViewModel -class EditFilterViewModel @Inject constructor( - @FilterId val filterId: Long?, - private val filtersRepository: FiltersRepository, - private val gson: Gson, - @IODispatcher private val ioDispatcher: CoroutineDispatcher, - application: Application, -): BaseViewModel(application), AppsPickerResultHandler { - - val filter = filtersRepository.getByIdAsFlow(filterId ?: -1L) - .distinctUntilChanged() - .take(1) // Not to handle changes - .onEach { filter -> - if (filter == null) return@onEach - - including.update { filter.including } - - val allowedLevels = filter.allowedLevels.map { it.ordinal } - for (i in 0 until enabledLogLevels.size) { - enabledLogLevels[i] = allowedLevels.contains(i) - } - - uid.update { filter.uid } - pid.update { filter.pid } - tid.update { filter.tid } - packageName.update { filter.packageName } - tag.update { filter.tag } - content.update { filter.content } - } - .stateIn( - scope = viewModelScope, - started = SharingStarted.Eagerly, - initialValue = null, - ) - - val including = MutableStateFlow(true) - val enabledLogLevels = mutableListOf(true, true, true, true, true, true, true) - val uid = MutableStateFlow(null) - val pid = MutableStateFlow(null) - val tid = MutableStateFlow(null) - val packageName = MutableStateFlow(null) - val tag = MutableStateFlow(null) - val content = MutableStateFlow(null) - - fun create() = launchCatching { - filtersRepository.create( - including.value, - enabledLogLevels.toEnabledLogLevels(), - uid.value, pid.value, tid.value, packageName.value, tag.value, content.value - ) - } - - fun update(userFilter: UserFilter) = launchCatching { - filtersRepository.update( - userFilter, - including.value, - enabledLogLevels.toEnabledLogLevels(), - uid.value, pid.value, tid.value, packageName.value, tag.value, content.value - ) - } - - fun export(uri: Uri) = launchCatching(ioDispatcher) { - ctx.contentResolver.openOutputStream(uri)?.use { outputStream -> - val filters = filter.value?.let { listOf(it) } ?: emptyList() - - outputStream.write(gson.toJson(filters).encodeToByteArray()) - } - } - - fun filterLevel(which: Int, filtering: Boolean) { - enabledLogLevels[which] = filtering - } - - override fun onAppSelected(app: InstalledApp): Boolean { - packageName.update { - app.packageName - }.also { - sendEvent(UpdatePackageNameText) - } - return true - } - - private fun List.toEnabledLogLevels() = mapIndexed { index, value -> - if (value) - enumValues()[index] - else - null - }.filterNotNull() -} - -data object UpdatePackageNameText : Event diff --git a/feature/logging-core/src/main/kotlin/com/f0x1d/logfox/feature/logging/core/di/StoresModule.kt b/feature/logging-core/src/main/kotlin/com/f0x1d/logfox/feature/logging/core/di/StoresModule.kt deleted file mode 100644 index a94fac1e..00000000 --- a/feature/logging-core/src/main/kotlin/com/f0x1d/logfox/feature/logging/core/di/StoresModule.kt +++ /dev/null @@ -1,18 +0,0 @@ -package com.f0x1d.logfox.feature.logging.core.di - -import com.f0x1d.logfox.feature.logging.core.store.LoggingStore -import com.f0x1d.logfox.feature.logging.core.store.LoggingStoreImpl -import dagger.Binds -import dagger.Module -import dagger.hilt.InstallIn -import dagger.hilt.components.SingletonComponent - -@Module -@InstallIn(SingletonComponent::class) -internal interface StoresModule { - - @Binds - fun bindLoggingStore( - loggingStoreImpl: LoggingStoreImpl, - ): LoggingStore -} diff --git a/feature/logging-core/src/main/kotlin/com/f0x1d/logfox/feature/logging/core/repository/LoggingRepository.kt b/feature/logging-core/src/main/kotlin/com/f0x1d/logfox/feature/logging/core/repository/LoggingRepository.kt deleted file mode 100644 index bafe767d..00000000 --- a/feature/logging-core/src/main/kotlin/com/f0x1d/logfox/feature/logging/core/repository/LoggingRepository.kt +++ /dev/null @@ -1,102 +0,0 @@ -package com.f0x1d.logfox.feature.logging.core.repository - -import android.content.Context -import com.f0x1d.logfox.arch.di.IODispatcher -import com.f0x1d.logfox.arch.repository.BaseRepository -import com.f0x1d.logfox.model.exception.TerminalNotSupportedException -import com.f0x1d.logfox.model.logline.LogLine -import com.f0x1d.logfox.preferences.shared.AppPreferences -import com.f0x1d.logfox.terminals.base.Terminal -import dagger.hilt.android.qualifiers.ApplicationContext -import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.FlowCollector -import kotlinx.coroutines.flow.flow -import kotlinx.coroutines.flow.flowOn -import javax.inject.Inject - -interface LoggingRepository { - - companion object { - val COMMAND = arrayOf("logcat" , "-v", "uid", "-v", "epoch") - - val DUMP_FLAG = arrayOf("-d") - val SHOW_LOGS_FROM_NOW_FLAGS = arrayOf("-T", "1") - } - - fun startLogging( - terminal: Terminal, - startingId: Long = 0, - ): Flow - - fun dumpLogs(terminal: Terminal): Flow -} - -internal class LoggingRepositoryImpl @Inject constructor( - @ApplicationContext private val context: Context, - private val appPreferences: AppPreferences, - @IODispatcher private val ioDispatcher: CoroutineDispatcher, -): BaseRepository(), LoggingRepository { - - override fun startLogging( - terminal: Terminal, - startingId: Long, - ): Flow = flow { - val command = LoggingRepository.COMMAND + when (appPreferences.showLogsFromAppLaunch) { - true -> LoggingRepository.SHOW_LOGS_FROM_NOW_FLAGS - - else -> emptyArray() - } - - emitLines( - terminal = terminal, - command = command, - startingId = startingId, - ) - }.flowOn(ioDispatcher) - - override fun dumpLogs(terminal: Terminal): Flow = flow { - val command = LoggingRepository.COMMAND + LoggingRepository.DUMP_FLAG - - emitLines( - terminal = terminal, - command = command, - startingId = 0, - ) - }.flowOn(ioDispatcher) - - private suspend fun FlowCollector.emitLines( - terminal: Terminal, - command: Array, - startingId: Long = 0, - ) { - if (terminal.isSupported().not()) { - throw TerminalNotSupportedException() - } - - val process = terminal.execute(*command) ?: throw TerminalNotSupportedException() - - var idsCounter = startingId - - try { - process.output.bufferedReader().useLines { - var droppedFirst = !appPreferences.showLogsFromAppLaunch - // avoiding getting the same line after logging restart because of - // WARNING: -T 0 invalid, setting to 1 - for (line in it) { - val logLine = LogLine(idsCounter++, line, context) ?: continue - if (!droppedFirst) { - droppedFirst = true - continue - } - - emit(logLine) - } - } - } finally { - runCatching { - process.destroy() - } - } - } -} diff --git a/feature/logging-core/.gitignore b/feature/logging/api/.gitignore similarity index 100% rename from feature/logging-core/.gitignore rename to feature/logging/api/.gitignore diff --git a/feature/filters-core/build.gradle.kts b/feature/logging/api/build.gradle.kts similarity index 52% rename from feature/filters-core/build.gradle.kts rename to feature/logging/api/build.gradle.kts index cddf00c9..3bc15241 100644 --- a/feature/filters-core/build.gradle.kts +++ b/feature/logging/api/build.gradle.kts @@ -2,7 +2,7 @@ plugins { id("logfox.android.feature") } -android.namespace = "com.f0x1d.logfox.feature.filters.core" +android.namespace = "com.f0x1d.logfox.feature.logging.api" dependencies { diff --git a/feature/logging/api/src/main/kotlin/com/f0x1d/logfox/feature/logging/api/data/LoggingRepository.kt b/feature/logging/api/src/main/kotlin/com/f0x1d/logfox/feature/logging/api/data/LoggingRepository.kt new file mode 100644 index 00000000..aa976498 --- /dev/null +++ b/feature/logging/api/src/main/kotlin/com/f0x1d/logfox/feature/logging/api/data/LoggingRepository.kt @@ -0,0 +1,22 @@ +package com.f0x1d.logfox.feature.logging.api.data + +import com.f0x1d.logfox.model.logline.LogLine +import com.f0x1d.logfox.terminals.base.Terminal +import kotlinx.coroutines.flow.Flow + +interface LoggingRepository { + + companion object { + val COMMAND = arrayOf("logcat" , "-v", "uid", "-v", "epoch") + + val DUMP_FLAG = arrayOf("-d") + val SHOW_LOGS_FROM_NOW_FLAGS = arrayOf("-T", "1") + } + + fun startLogging( + terminal: Terminal, + startingId: Long = 0, + ): Flow + + fun dumpLogs(terminal: Terminal): Flow +} diff --git a/feature/logging/api/src/main/kotlin/com/f0x1d/logfox/feature/logging/api/data/LogsDataSource.kt b/feature/logging/api/src/main/kotlin/com/f0x1d/logfox/feature/logging/api/data/LogsDataSource.kt new file mode 100644 index 00000000..63c04abd --- /dev/null +++ b/feature/logging/api/src/main/kotlin/com/f0x1d/logfox/feature/logging/api/data/LogsDataSource.kt @@ -0,0 +1,10 @@ +package com.f0x1d.logfox.feature.logging.api.data + +import com.f0x1d.logfox.model.logline.LogLine +import kotlinx.coroutines.flow.Flow + +interface LogsDataSource { + val logs: Flow> + + suspend fun updateLogs(logs: List) +} diff --git a/feature/logging/api/src/main/kotlin/com/f0x1d/logfox/feature/logging/api/data/QueryDataSource.kt b/feature/logging/api/src/main/kotlin/com/f0x1d/logfox/feature/logging/api/data/QueryDataSource.kt new file mode 100644 index 00000000..da6df653 --- /dev/null +++ b/feature/logging/api/src/main/kotlin/com/f0x1d/logfox/feature/logging/api/data/QueryDataSource.kt @@ -0,0 +1,9 @@ +package com.f0x1d.logfox.feature.logging.api.data + +import kotlinx.coroutines.flow.Flow + +interface QueryDataSource { + val query: Flow + + suspend fun updateQuery(query: String?) +} diff --git a/feature/logging/api/src/main/kotlin/com/f0x1d/logfox/feature/logging/api/data/SelectedLogLinesDataSource.kt b/feature/logging/api/src/main/kotlin/com/f0x1d/logfox/feature/logging/api/data/SelectedLogLinesDataSource.kt new file mode 100644 index 00000000..3645bd35 --- /dev/null +++ b/feature/logging/api/src/main/kotlin/com/f0x1d/logfox/feature/logging/api/data/SelectedLogLinesDataSource.kt @@ -0,0 +1,10 @@ +package com.f0x1d.logfox.feature.logging.api.data + +import com.f0x1d.logfox.model.logline.LogLine +import kotlinx.coroutines.flow.Flow + +interface SelectedLogLinesDataSource { + val selectedLines: Flow> + + suspend fun updateSelectedLines(selectedLines: List) +} diff --git a/feature/logging-core/src/main/kotlin/com/f0x1d/logfox/feature/logging/core/model/LogLinesExt.kt b/feature/logging/api/src/main/kotlin/com/f0x1d/logfox/feature/logging/api/model/LogLinesExt.kt similarity index 97% rename from feature/logging-core/src/main/kotlin/com/f0x1d/logfox/feature/logging/core/model/LogLinesExt.kt rename to feature/logging/api/src/main/kotlin/com/f0x1d/logfox/feature/logging/api/model/LogLinesExt.kt index 9f0204f0..92068f41 100644 --- a/feature/logging-core/src/main/kotlin/com/f0x1d/logfox/feature/logging/core/model/LogLinesExt.kt +++ b/feature/logging/api/src/main/kotlin/com/f0x1d/logfox/feature/logging/api/model/LogLinesExt.kt @@ -1,4 +1,4 @@ -package com.f0x1d.logfox.feature.logging.core.model +package com.f0x1d.logfox.feature.logging.api.model import com.f0x1d.logfox.database.entity.UserFilter import com.f0x1d.logfox.model.logline.LogLine diff --git a/feature/logging/api/src/main/kotlin/com/f0x1d/logfox/feature/logging/api/presentation/LoggingServiceDelegate.kt b/feature/logging/api/src/main/kotlin/com/f0x1d/logfox/feature/logging/api/presentation/LoggingServiceDelegate.kt new file mode 100644 index 00000000..4996713a --- /dev/null +++ b/feature/logging/api/src/main/kotlin/com/f0x1d/logfox/feature/logging/api/presentation/LoggingServiceDelegate.kt @@ -0,0 +1,7 @@ +package com.f0x1d.logfox.feature.logging.api.presentation + +interface LoggingServiceDelegate { + fun clearLogs() + fun restartLogging() + fun killService() +} diff --git a/feature/logging/build.gradle.kts b/feature/logging/build.gradle.kts deleted file mode 100644 index 26490df9..00000000 --- a/feature/logging/build.gradle.kts +++ /dev/null @@ -1,12 +0,0 @@ -plugins { - id("logfox.android.feature") -} - -android.namespace = "com.f0x1d.logfox.feature.logging" - -dependencies { - implementation(projects.feature.crashesCore) - implementation(projects.feature.filtersCore) - implementation(projects.feature.loggingCore) - implementation(projects.feature.recordingsCore) -} diff --git a/feature/recordings-core/.gitignore b/feature/logging/extended-copy/.gitignore similarity index 100% rename from feature/recordings-core/.gitignore rename to feature/logging/extended-copy/.gitignore diff --git a/feature/logging/extended-copy/build.gradle.kts b/feature/logging/extended-copy/build.gradle.kts new file mode 100644 index 00000000..a76d5f33 --- /dev/null +++ b/feature/logging/extended-copy/build.gradle.kts @@ -0,0 +1,9 @@ +plugins { + id("logfox.android.feature") +} + +android.namespace = "com.f0x1d.logfox.feature.logging.extended.copy" + +dependencies { + implementation(projects.feature.logging.api) +} diff --git a/feature/logging/extended-copy/src/main/kotlin/com/f0x1d/logfox/feature/logging/extended/copy/presentation/LogsExtendedCopyAction.kt b/feature/logging/extended-copy/src/main/kotlin/com/f0x1d/logfox/feature/logging/extended/copy/presentation/LogsExtendedCopyAction.kt new file mode 100644 index 00000000..cf25e416 --- /dev/null +++ b/feature/logging/extended-copy/src/main/kotlin/com/f0x1d/logfox/feature/logging/extended/copy/presentation/LogsExtendedCopyAction.kt @@ -0,0 +1,3 @@ +package com.f0x1d.logfox.feature.logging.extended.copy.presentation + +sealed interface LogsExtendedCopyAction diff --git a/feature/logging/extended-copy/src/main/kotlin/com/f0x1d/logfox/feature/logging/extended/copy/presentation/LogsExtendedCopyState.kt b/feature/logging/extended-copy/src/main/kotlin/com/f0x1d/logfox/feature/logging/extended/copy/presentation/LogsExtendedCopyState.kt new file mode 100644 index 00000000..37ed0038 --- /dev/null +++ b/feature/logging/extended-copy/src/main/kotlin/com/f0x1d/logfox/feature/logging/extended/copy/presentation/LogsExtendedCopyState.kt @@ -0,0 +1,5 @@ +package com.f0x1d.logfox.feature.logging.extended.copy.presentation + +data class LogsExtendedCopyState( + val text: String? = null, +) diff --git a/feature/logging/extended-copy/src/main/kotlin/com/f0x1d/logfox/feature/logging/extended/copy/presentation/LogsExtendedCopyViewModel.kt b/feature/logging/extended-copy/src/main/kotlin/com/f0x1d/logfox/feature/logging/extended/copy/presentation/LogsExtendedCopyViewModel.kt new file mode 100644 index 00000000..1c7c00da --- /dev/null +++ b/feature/logging/extended-copy/src/main/kotlin/com/f0x1d/logfox/feature/logging/extended/copy/presentation/LogsExtendedCopyViewModel.kt @@ -0,0 +1,50 @@ +package com.f0x1d.logfox.feature.logging.extended.copy.presentation + +import android.app.Application +import androidx.lifecycle.viewModelScope +import com.f0x1d.logfox.arch.di.DefaultDispatcher +import com.f0x1d.logfox.arch.viewmodel.BaseViewModel +import com.f0x1d.logfox.datetime.DateTimeFormatter +import com.f0x1d.logfox.feature.logging.api.data.SelectedLogLinesDataSource +import com.f0x1d.logfox.preferences.shared.AppPreferences +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +class LogsExtendedCopyViewModel @Inject constructor( + private val selectedLogLinesDataSource: SelectedLogLinesDataSource, + private val appPreferences: AppPreferences, + @DefaultDispatcher private val defaultDispatcher: CoroutineDispatcher, + dateTimeFormatter: DateTimeFormatter, + application: Application, +) : BaseViewModel( + initialStateProvider = { LogsExtendedCopyState() }, + application = application, +), DateTimeFormatter by dateTimeFormatter { + init { + load() + } + + private fun load() { + viewModelScope.launch { + selectedLogLinesDataSource.selectedLines + .map { lines -> + lines.joinToString("\n") { line -> + appPreferences.originalOf( + logLine = line, + formatDate = ::formatDate, + formatTime = ::formatTime, + ) + } + } + .flowOn(defaultDispatcher) + .collect { text -> + reduce { copy(text = text) } + } + } + } +} diff --git a/feature/logging/src/main/kotlin/com/f0x1d/feature/logging/ui/fragment/LogsExtendedCopyFragment.kt b/feature/logging/extended-copy/src/main/kotlin/com/f0x1d/logfox/feature/logging/extended/copy/presentation/ui/LogsExtendedCopyFragment.kt similarity index 50% rename from feature/logging/src/main/kotlin/com/f0x1d/feature/logging/ui/fragment/LogsExtendedCopyFragment.kt rename to feature/logging/extended-copy/src/main/kotlin/com/f0x1d/logfox/feature/logging/extended/copy/presentation/ui/LogsExtendedCopyFragment.kt index 0bd96f27..3c93a4fa 100644 --- a/feature/logging/src/main/kotlin/com/f0x1d/feature/logging/ui/fragment/LogsExtendedCopyFragment.kt +++ b/feature/logging/extended-copy/src/main/kotlin/com/f0x1d/logfox/feature/logging/extended/copy/presentation/ui/LogsExtendedCopyFragment.kt @@ -1,20 +1,21 @@ -package com.f0x1d.feature.logging.ui.fragment +package com.f0x1d.logfox.feature.logging.extended.copy.presentation.ui import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.hilt.navigation.fragment.hiltNavGraphViewModels -import com.f0x1d.feature.logging.viewmodel.LogsViewModel -import com.f0x1d.logfox.arch.ui.fragment.BaseViewModelFragment -import com.f0x1d.logfox.feature.logging.databinding.FragmentLogsExtendedCopyBinding -import com.f0x1d.logfox.navigation.Directions +import androidx.fragment.app.viewModels +import com.f0x1d.logfox.arch.presentation.ui.fragment.BaseFragment +import com.f0x1d.logfox.feature.logging.extended.copy.databinding.FragmentLogsExtendedCopyBinding +import com.f0x1d.logfox.feature.logging.extended.copy.presentation.LogsExtendedCopyViewModel import com.f0x1d.logfox.ui.view.setupBackButtonForNavController +import dagger.hilt.android.AndroidEntryPoint import dev.chrisbanes.insetter.applyInsetter -class LogsExtendedCopyFragment: BaseViewModelFragment() { +@AndroidEntryPoint +class LogsExtendedCopyFragment : BaseFragment() { - override val viewModel by hiltNavGraphViewModels(Directions.logsFragment) + private val viewModel by viewModels() override fun inflateBinding( inflater: LayoutInflater, @@ -29,6 +30,8 @@ class LogsExtendedCopyFragment: BaseViewModelFragment + logText.text = state.text + } } } diff --git a/feature/logging/src/main/res/layout/fragment_logs_extended_copy.xml b/feature/logging/extended-copy/src/main/res/layout/fragment_logs_extended_copy.xml similarity index 100% rename from feature/logging/src/main/res/layout/fragment_logs_extended_copy.xml rename to feature/logging/extended-copy/src/main/res/layout/fragment_logs_extended_copy.xml diff --git a/feature/crashes/.gitignore b/feature/logging/impl/.gitignore similarity index 100% rename from feature/crashes/.gitignore rename to feature/logging/impl/.gitignore diff --git a/feature/logging/impl/build.gradle.kts b/feature/logging/impl/build.gradle.kts new file mode 100644 index 00000000..1bee1f41 --- /dev/null +++ b/feature/logging/impl/build.gradle.kts @@ -0,0 +1,9 @@ +plugins { + id("logfox.android.feature") +} + +android.namespace = "com.f0x1d.logfox.feature.logging.impl" + +dependencies { + implementation(projects.feature.logging.api) +} diff --git a/feature/logging/impl/src/main/kotlin/com/f0x1d/logfox/feature/logging/impl/data/LoggingRepositoryImpl.kt b/feature/logging/impl/src/main/kotlin/com/f0x1d/logfox/feature/logging/impl/data/LoggingRepositoryImpl.kt new file mode 100644 index 00000000..650a538c --- /dev/null +++ b/feature/logging/impl/src/main/kotlin/com/f0x1d/logfox/feature/logging/impl/data/LoggingRepositoryImpl.kt @@ -0,0 +1,118 @@ +package com.f0x1d.logfox.feature.logging.impl.data + +import android.content.Context +import com.f0x1d.logfox.arch.di.IODispatcher +import com.f0x1d.logfox.feature.logging.api.data.LoggingRepository +import com.f0x1d.logfox.model.exception.TerminalNotSupportedException +import com.f0x1d.logfox.model.logline.LogLine +import com.f0x1d.logfox.preferences.shared.AppPreferences +import com.f0x1d.logfox.terminals.base.Terminal +import dagger.hilt.android.qualifiers.ApplicationContext +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.cancel +import kotlinx.coroutines.channels.ProducerScope +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.channelFlow +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.launch +import kotlinx.coroutines.withTimeout +import timber.log.Timber +import javax.inject.Inject +import kotlin.time.Duration.Companion.seconds + +internal class LoggingRepositoryImpl @Inject constructor( + @ApplicationContext private val context: Context, + private val appPreferences: AppPreferences, + @IODispatcher private val ioDispatcher: CoroutineDispatcher, +) : LoggingRepository { + + override fun startLogging( + terminal: Terminal, + startingId: Long, + ): Flow = channelFlow { + val command = LoggingRepository.COMMAND + when (appPreferences.showLogsFromAppLaunch) { + true -> LoggingRepository.SHOW_LOGS_FROM_NOW_FLAGS + + else -> emptyArray() + } + + emitLines( + terminal = terminal, + command = command, + startingId = startingId, + ) + }.flowOn(ioDispatcher) + + override fun dumpLogs(terminal: Terminal): Flow = channelFlow { + val command = LoggingRepository.COMMAND + LoggingRepository.DUMP_FLAG + + emitLines( + terminal = terminal, + command = command, + startingId = 0, + ) + }.flowOn(ioDispatcher) + + private suspend fun ProducerScope.emitLines( + terminal: Terminal, + command: Array, + startingId: Long = 0, + ) { + if (terminal.isSupported().not()) { + Timber.d("terminal $terminal is not supported") + throw TerminalNotSupportedException() + } + + val process = terminal.execute(*command) ?: throw TerminalNotSupportedException() + Timber.d("started process") + + var idsCounter = startingId + Timber.d("starting with id $idsCounter") + + try { + val readerScope = CoroutineScope(ioDispatcher + SupervisorJob()) + invokeOnClose { readerScope.cancel() } + + process.output.bufferedReader().useLines { linesSequence -> + var droppedFirst = !appPreferences.showLogsFromAppLaunch + // avoiding getting the same line after logging restart because of + // WARNING: -T 0 invalid, setting to 1 + val iterator = linesSequence.iterator() + + var looping = true + while (looping) { + withTimeout(10.seconds) { + readerScope.launch { + if (iterator.hasNext().not()) { + looping = false + } else { + val line = iterator.next() + Timber.d("got line $line") + + val logLine = LogLine( + id = idsCounter++, + line = line, + context = context, + ) + Timber.d("successfully parsed $line to $logLine") + + if (droppedFirst.not()) { + droppedFirst = true + } else { + logLine?.let { send(it) } + } + } + }.join() + } + } + } + } finally { + Timber.d("destroying process") + runCatching { + process.destroy() + } + } + } +} diff --git a/feature/logging-core/src/main/kotlin/com/f0x1d/logfox/feature/logging/core/store/LoggingStore.kt b/feature/logging/impl/src/main/kotlin/com/f0x1d/logfox/feature/logging/impl/data/LogsDataSourceImpl.kt similarity index 64% rename from feature/logging-core/src/main/kotlin/com/f0x1d/logfox/feature/logging/core/store/LoggingStore.kt rename to feature/logging/impl/src/main/kotlin/com/f0x1d/logfox/feature/logging/impl/data/LogsDataSourceImpl.kt index 92ba381b..5d472ab9 100644 --- a/feature/logging-core/src/main/kotlin/com/f0x1d/logfox/feature/logging/core/store/LoggingStore.kt +++ b/feature/logging/impl/src/main/kotlin/com/f0x1d/logfox/feature/logging/impl/data/LogsDataSourceImpl.kt @@ -1,31 +1,25 @@ -package com.f0x1d.logfox.feature.logging.core.store +package com.f0x1d.logfox.feature.logging.impl.data import com.f0x1d.logfox.arch.di.DefaultDispatcher +import com.f0x1d.logfox.feature.logging.api.data.LogsDataSource import com.f0x1d.logfox.model.logline.LogLine import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update import kotlinx.coroutines.withContext import javax.inject.Inject import javax.inject.Singleton -// I completely don't like it -// I really want to get rid of Singletons in project -interface LoggingStore { - val logs: Flow> - - suspend fun updateLogs(logs: List) -} - @Singleton -internal class LoggingStoreImpl @Inject constructor( +internal class LogsDataSourceImpl @Inject constructor( @DefaultDispatcher private val defaultDispatcher: CoroutineDispatcher, -) : LoggingStore { +) : LogsDataSource { private val mutableLogs = MutableStateFlow(emptyList()) - override val logs: Flow> = mutableLogs + override val logs: Flow> get() = mutableLogs.asStateFlow() override suspend fun updateLogs(logs: List) = withContext(defaultDispatcher) { mutableLogs.update { logs.toMutableList() } diff --git a/feature/logging/impl/src/main/kotlin/com/f0x1d/logfox/feature/logging/impl/data/QueryDataSourceImpl.kt b/feature/logging/impl/src/main/kotlin/com/f0x1d/logfox/feature/logging/impl/data/QueryDataSourceImpl.kt new file mode 100644 index 00000000..ca44e16c --- /dev/null +++ b/feature/logging/impl/src/main/kotlin/com/f0x1d/logfox/feature/logging/impl/data/QueryDataSourceImpl.kt @@ -0,0 +1,25 @@ +package com.f0x1d.logfox.feature.logging.impl.data + +import com.f0x1d.logfox.arch.di.DefaultDispatcher +import com.f0x1d.logfox.feature.logging.api.data.QueryDataSource +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.withContext +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +internal class QueryDataSourceImpl @Inject constructor( + @DefaultDispatcher private val defaultDispatcher: CoroutineDispatcher, +) : QueryDataSource { + private val mutableQuery = MutableStateFlow(null) + + override val query: Flow get() = mutableQuery.asStateFlow() + + override suspend fun updateQuery(query: String?) = withContext(defaultDispatcher) { + mutableQuery.update { query } + } +} diff --git a/feature/logging/impl/src/main/kotlin/com/f0x1d/logfox/feature/logging/impl/data/SelectedLogLinesDataSourceImpl.kt b/feature/logging/impl/src/main/kotlin/com/f0x1d/logfox/feature/logging/impl/data/SelectedLogLinesDataSourceImpl.kt new file mode 100644 index 00000000..54fdf0de --- /dev/null +++ b/feature/logging/impl/src/main/kotlin/com/f0x1d/logfox/feature/logging/impl/data/SelectedLogLinesDataSourceImpl.kt @@ -0,0 +1,26 @@ +package com.f0x1d.logfox.feature.logging.impl.data + +import com.f0x1d.logfox.arch.di.DefaultDispatcher +import com.f0x1d.logfox.feature.logging.api.data.SelectedLogLinesDataSource +import com.f0x1d.logfox.model.logline.LogLine +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.withContext +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +internal class SelectedLogLinesDataSourceImpl @Inject constructor( + @DefaultDispatcher private val defaultDispatcher: CoroutineDispatcher, +) : SelectedLogLinesDataSource { + private val mutableLines = MutableStateFlow(emptyList()) + + override val selectedLines: Flow> get() = mutableLines.asStateFlow() + + override suspend fun updateSelectedLines(selectedLines: List) = withContext(defaultDispatcher) { + mutableLines.update { selectedLines.toMutableList() } + } +} diff --git a/feature/logging/impl/src/main/kotlin/com/f0x1d/logfox/feature/logging/impl/di/DataSourcesModule.kt b/feature/logging/impl/src/main/kotlin/com/f0x1d/logfox/feature/logging/impl/di/DataSourcesModule.kt new file mode 100644 index 00000000..b72a83b4 --- /dev/null +++ b/feature/logging/impl/src/main/kotlin/com/f0x1d/logfox/feature/logging/impl/di/DataSourcesModule.kt @@ -0,0 +1,32 @@ +package com.f0x1d.logfox.feature.logging.impl.di + +import com.f0x1d.logfox.feature.logging.api.data.LogsDataSource +import com.f0x1d.logfox.feature.logging.api.data.QueryDataSource +import com.f0x1d.logfox.feature.logging.api.data.SelectedLogLinesDataSource +import com.f0x1d.logfox.feature.logging.impl.data.LogsDataSourceImpl +import com.f0x1d.logfox.feature.logging.impl.data.QueryDataSourceImpl +import com.f0x1d.logfox.feature.logging.impl.data.SelectedLogLinesDataSourceImpl +import dagger.Binds +import dagger.Module +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent + +@Module +@InstallIn(SingletonComponent::class) +internal interface DataSourcesModule { + + @Binds + fun bindLogsDataSource( + logsDataSourceImpl: LogsDataSourceImpl, + ): LogsDataSource + + @Binds + fun bindQueryDataSource( + queryDataSourceImpl: QueryDataSourceImpl, + ): QueryDataSource + + @Binds + fun bindSelectedLogLinesDataSource( + selectedLogLinesDataSourceImpl: SelectedLogLinesDataSourceImpl, + ): SelectedLogLinesDataSource +} diff --git a/feature/logging-core/src/main/kotlin/com/f0x1d/logfox/feature/logging/core/di/RepositoriesModule.kt b/feature/logging/impl/src/main/kotlin/com/f0x1d/logfox/feature/logging/impl/di/RepositoriesModule.kt similarity index 62% rename from feature/logging-core/src/main/kotlin/com/f0x1d/logfox/feature/logging/core/di/RepositoriesModule.kt rename to feature/logging/impl/src/main/kotlin/com/f0x1d/logfox/feature/logging/impl/di/RepositoriesModule.kt index 5b8d7760..a7b862e7 100644 --- a/feature/logging-core/src/main/kotlin/com/f0x1d/logfox/feature/logging/core/di/RepositoriesModule.kt +++ b/feature/logging/impl/src/main/kotlin/com/f0x1d/logfox/feature/logging/impl/di/RepositoriesModule.kt @@ -1,7 +1,7 @@ -package com.f0x1d.logfox.feature.logging.core.di +package com.f0x1d.logfox.feature.logging.impl.di -import com.f0x1d.logfox.feature.logging.core.repository.LoggingRepository -import com.f0x1d.logfox.feature.logging.core.repository.LoggingRepositoryImpl +import com.f0x1d.logfox.feature.logging.api.data.LoggingRepository +import com.f0x1d.logfox.feature.logging.impl.data.LoggingRepositoryImpl import dagger.Binds import dagger.Module import dagger.hilt.InstallIn diff --git a/feature/recordings/.gitignore b/feature/logging/list/.gitignore similarity index 100% rename from feature/recordings/.gitignore rename to feature/logging/list/.gitignore diff --git a/feature/logging/list/build.gradle.kts b/feature/logging/list/build.gradle.kts new file mode 100644 index 00000000..01b3df10 --- /dev/null +++ b/feature/logging/list/build.gradle.kts @@ -0,0 +1,12 @@ +plugins { + id("logfox.android.feature") +} + +android.namespace = "com.f0x1d.logfox.feature.logging.list" + +dependencies { + implementation(projects.feature.crashes.api) + implementation(projects.feature.filters.api) + implementation(projects.feature.logging.api) + implementation(projects.feature.recordings.api) +} diff --git a/feature/logging/src/main/kotlin/com/f0x1d/feature/logging/di/LogsViewModelModule.kt b/feature/logging/list/src/main/kotlin/com/f0x1d/logfox/feature/logging/list/di/LogsViewModelModule.kt similarity index 93% rename from feature/logging/src/main/kotlin/com/f0x1d/feature/logging/di/LogsViewModelModule.kt rename to feature/logging/list/src/main/kotlin/com/f0x1d/logfox/feature/logging/list/di/LogsViewModelModule.kt index d286626e..898dd320 100644 --- a/feature/logging/src/main/kotlin/com/f0x1d/feature/logging/di/LogsViewModelModule.kt +++ b/feature/logging/list/src/main/kotlin/com/f0x1d/logfox/feature/logging/list/di/LogsViewModelModule.kt @@ -1,4 +1,4 @@ -package com.f0x1d.feature.logging.di +package com.f0x1d.logfox.feature.logging.list.di import android.content.Intent import android.net.Uri diff --git a/feature/logging/list/src/main/kotlin/com/f0x1d/logfox/feature/logging/list/presentation/LogsAction.kt b/feature/logging/list/src/main/kotlin/com/f0x1d/logfox/feature/logging/list/presentation/LogsAction.kt new file mode 100644 index 00000000..461401eb --- /dev/null +++ b/feature/logging/list/src/main/kotlin/com/f0x1d/logfox/feature/logging/list/presentation/LogsAction.kt @@ -0,0 +1,3 @@ +package com.f0x1d.logfox.feature.logging.list.presentation + +sealed interface LogsAction diff --git a/feature/logging/list/src/main/kotlin/com/f0x1d/logfox/feature/logging/list/presentation/LogsState.kt b/feature/logging/list/src/main/kotlin/com/f0x1d/logfox/feature/logging/list/presentation/LogsState.kt new file mode 100644 index 00000000..5737d374 --- /dev/null +++ b/feature/logging/list/src/main/kotlin/com/f0x1d/logfox/feature/logging/list/presentation/LogsState.kt @@ -0,0 +1,12 @@ +package com.f0x1d.logfox.feature.logging.list.presentation + +import com.f0x1d.logfox.database.entity.UserFilter +import com.f0x1d.logfox.model.logline.LogLine + +data class LogsState( + val logs: List = emptyList(), + val paused: Boolean = false, + val query: String? = null, + val filters: List = emptyList(), + val selectedItems: Set = emptySet(), +) diff --git a/feature/logging/list/src/main/kotlin/com/f0x1d/logfox/feature/logging/list/presentation/LogsViewModel.kt b/feature/logging/list/src/main/kotlin/com/f0x1d/logfox/feature/logging/list/presentation/LogsViewModel.kt new file mode 100644 index 00000000..fa812212 --- /dev/null +++ b/feature/logging/list/src/main/kotlin/com/f0x1d/logfox/feature/logging/list/presentation/LogsViewModel.kt @@ -0,0 +1,195 @@ +package com.f0x1d.logfox.feature.logging.list.presentation + +import android.app.Application +import android.net.Uri +import androidx.lifecycle.viewModelScope +import com.f0x1d.logfox.arch.di.DefaultDispatcher +import com.f0x1d.logfox.arch.di.IODispatcher +import com.f0x1d.logfox.arch.viewmodel.BaseViewModel +import com.f0x1d.logfox.database.entity.UserFilter +import com.f0x1d.logfox.datetime.DateTimeFormatter +import com.f0x1d.logfox.feature.filters.api.data.FiltersRepository +import com.f0x1d.logfox.feature.logging.api.data.LogsDataSource +import com.f0x1d.logfox.feature.logging.api.data.QueryDataSource +import com.f0x1d.logfox.feature.logging.api.data.SelectedLogLinesDataSource +import com.f0x1d.logfox.feature.logging.api.model.filterAndSearch +import com.f0x1d.logfox.feature.logging.list.di.FileUri +import com.f0x1d.logfox.feature.recordings.api.data.RecordingsRepository +import com.f0x1d.logfox.model.logline.LogLine +import com.f0x1d.logfox.preferences.shared.AppPreferences +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.mapNotNull +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.scan +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import javax.inject.Inject + +@HiltViewModel +class LogsViewModel @Inject constructor( + @FileUri val fileUri: Uri?, + private val logsDataSource: LogsDataSource, + private val queryDataSource: QueryDataSource, + private val selectedLogLinesDataSource: SelectedLogLinesDataSource, + private val filtersRepository: FiltersRepository, + private val recordingsRepository: RecordingsRepository, + private val appPreferences: AppPreferences, + @DefaultDispatcher private val defaultDispatcher: CoroutineDispatcher, + @IODispatcher private val ioDispatcher: CoroutineDispatcher, + dateTimeFormatter: DateTimeFormatter, + application: Application, +): BaseViewModel( + initialStateProvider = { LogsState() }, + application = application, +), DateTimeFormatter by dateTimeFormatter { + val viewingFile = fileUri != null + val viewingFileName = fileUri?.readFileName(ctx) + + val resumeLoggingWithBottomTouch get() = appPreferences.resumeLoggingWithBottomTouch + val logsTextSize get() = appPreferences.logsTextSize.toFloat() + val logsExpanded get() = appPreferences.logsExpanded + val logsFormat get() = appPreferences.showLogValues + + val selectedItemsContent get() = currentState.selectedItems.joinToString("\n") { + originalOf(it) + } + + init { + load() + } + + private fun load() { + viewModelScope.launch { + state + .map { it.selectedItems } + .distinctUntilChanged() + .onEach { selectedLogLinesDataSource.updateSelectedLines(it.toList()) } + .launchIn(this) + + combine( + fileUri?.readFileContentsAsFlow( + context = ctx, + logsDisplayLimit = appPreferences.logsDisplayLimit, + ) ?: logsDataSource.logs, + filtersRepository.getAllEnabledAsFlow(), + queryDataSource.query, + if (viewingFile.not()) { + state + .map { it.paused } + .distinctUntilChanged() + } else { + flowOf(false) + }, + ) { logs, filters, query, paused -> + LogsData( + logs = logs, + filters = filters, + query = query, + paused = paused, + ) + }.scan(LogsData()) { accumulator, data -> + when { + !data.paused + // In case they were cleared + || data.logs.isEmpty() -> data + + data.query != accumulator.query + || data.filters != accumulator.filters + -> data.copy( + logs = accumulator.logs, + ) + + else -> data.copy( + logs = accumulator.logs, + passing = false, + ) + } + }.filter { data -> + data.passing + }.mapNotNull { data -> + data.copy( + logs = data.logs.filterAndSearch( + filters = data.filters, + query = data.query, + ) + ) + }.flowOn( + defaultDispatcher, + ).onEach { data -> + reduce { + copy( + logs = data.logs, + query = data.query, + filters = data.filters, + ) + } + }.launchIn(this) + } + } + + fun selectLine(logLine: LogLine, selected: Boolean) = reduce { + copy( + selectedItems = selectedItems.toMutableSet().apply { + if (selected) add( + logLine + ) else remove( + logLine + ) + } + ) + } + + fun selectAll() = reduce { + copy( + selectedItems = if (selectedItems.containsAll(logs)) { + emptySet() + } else { + logs.toSet() + }, + ) + } + + fun selectedToRecording() = launchCatching { + recordingsRepository.createRecordingFrom( + lines = withContext(defaultDispatcher) { + currentState.selectedItems.sortedBy { it.dateAndTime } + }, + ) + } + + fun exportSelectedLogsTo(uri: Uri) = launchCatching(ioDispatcher) { + ctx.contentResolver.openOutputStream(uri)?.use { + it.write(selectedItemsContent.encodeToByteArray()) + } + } + + fun switchState() = reduce { copy(paused = paused.not()) } + fun pause() = reduce { copy(paused = true) } + fun resume() = reduce { copy(paused = false) } + + fun originalOf(logLine: LogLine): String = appPreferences.originalOf( + logLine = logLine, + formatDate = ::formatDate, + formatTime = ::formatTime, + ) + + fun clearSelection() = reduce { + copy(selectedItems = emptySet()) + } + + private data class LogsData( + val logs: List = emptyList(), + val filters: List = emptyList(), + val query: String? = null, + val paused: Boolean = false, + val passing: Boolean = true, + ) +} diff --git a/feature/logging/src/main/kotlin/com/f0x1d/feature/logging/viewmodel/UriExt.kt b/feature/logging/list/src/main/kotlin/com/f0x1d/logfox/feature/logging/list/presentation/UriExt.kt similarity index 77% rename from feature/logging/src/main/kotlin/com/f0x1d/feature/logging/viewmodel/UriExt.kt rename to feature/logging/list/src/main/kotlin/com/f0x1d/logfox/feature/logging/list/presentation/UriExt.kt index e770ac14..d81af537 100644 --- a/feature/logging/src/main/kotlin/com/f0x1d/feature/logging/viewmodel/UriExt.kt +++ b/feature/logging/list/src/main/kotlin/com/f0x1d/logfox/feature/logging/list/presentation/UriExt.kt @@ -1,8 +1,9 @@ -package com.f0x1d.feature.logging.viewmodel +package com.f0x1d.logfox.feature.logging.list.presentation import android.content.Context import android.net.Uri import androidx.documentfile.provider.DocumentFile +import com.f0x1d.logfox.model.logline.LogLevel import com.f0x1d.logfox.model.logline.LogLine import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.flow @@ -26,6 +27,13 @@ internal fun Uri?.readFileContentsAsFlow( for (line in lines) { val logLine = LogLine(id, line, context) ?: LogLine( id = id, + dateAndTime = System.currentTimeMillis(), + uid = "", + pid = "", + tid = "", + packageName = null, + level = LogLevel.INFO, + tag = "", content = line, originalContent = line, ) diff --git a/feature/logging/src/main/kotlin/com/f0x1d/feature/logging/adapter/LogsAdapter.kt b/feature/logging/list/src/main/kotlin/com/f0x1d/logfox/feature/logging/list/presentation/adapter/LogsAdapter.kt similarity index 79% rename from feature/logging/src/main/kotlin/com/f0x1d/feature/logging/adapter/LogsAdapter.kt rename to feature/logging/list/src/main/kotlin/com/f0x1d/logfox/feature/logging/list/presentation/adapter/LogsAdapter.kt index 4c4a68d1..c60e7ac1 100644 --- a/feature/logging/src/main/kotlin/com/f0x1d/feature/logging/adapter/LogsAdapter.kt +++ b/feature/logging/list/src/main/kotlin/com/f0x1d/logfox/feature/logging/list/presentation/adapter/LogsAdapter.kt @@ -1,10 +1,10 @@ -package com.f0x1d.feature.logging.adapter +package com.f0x1d.logfox.feature.logging.list.presentation.adapter import android.view.LayoutInflater import android.view.ViewGroup -import com.f0x1d.feature.logging.ui.viewholder.LogViewHolder -import com.f0x1d.logfox.arch.adapter.BaseListAdapter -import com.f0x1d.logfox.feature.logging.databinding.ItemLogBinding +import com.f0x1d.logfox.arch.presentation.adapter.BaseListAdapter +import com.f0x1d.logfox.feature.logging.list.databinding.ItemLogBinding +import com.f0x1d.logfox.feature.logging.list.presentation.ui.viewholder.LogViewHolder import com.f0x1d.logfox.model.diffCallback import com.f0x1d.logfox.model.logline.LogLine import com.f0x1d.logfox.model.preferences.ShowLogValues diff --git a/feature/logging/src/main/kotlin/com/f0x1d/feature/logging/ui/fragment/LogsFragment.kt b/feature/logging/list/src/main/kotlin/com/f0x1d/logfox/feature/logging/list/presentation/ui/fragment/LogsFragment.kt similarity index 64% rename from feature/logging/src/main/kotlin/com/f0x1d/feature/logging/ui/fragment/LogsFragment.kt rename to feature/logging/list/src/main/kotlin/com/f0x1d/logfox/feature/logging/list/presentation/ui/fragment/LogsFragment.kt index b49f0570..ca212df9 100644 --- a/feature/logging/src/main/kotlin/com/f0x1d/feature/logging/ui/fragment/LogsFragment.kt +++ b/feature/logging/list/src/main/kotlin/com/f0x1d/logfox/feature/logging/list/presentation/ui/fragment/LogsFragment.kt @@ -1,4 +1,4 @@ -package com.f0x1d.feature.logging.ui.fragment +package com.f0x1d.logfox.feature.logging.list.presentation.ui.fragment import android.os.Bundle import android.view.LayoutInflater @@ -6,20 +6,19 @@ import android.view.View import android.view.ViewGroup import androidx.activity.OnBackPressedCallback import androidx.activity.result.contract.ActivityResultContracts -import androidx.core.os.bundleOf -import androidx.hilt.navigation.fragment.hiltNavGraphViewModels +import androidx.fragment.app.viewModels import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView -import com.f0x1d.feature.logging.adapter.LogsAdapter -import com.f0x1d.feature.logging.service.LoggingService -import com.f0x1d.feature.logging.viewmodel.LogsViewModel import com.f0x1d.logfox.arch.copyText import com.f0x1d.logfox.arch.isHorizontalOrientation -import com.f0x1d.logfox.arch.sendService -import com.f0x1d.logfox.arch.ui.fragment.BaseViewModelFragment -import com.f0x1d.logfox.feature.logging.R -import com.f0x1d.logfox.feature.logging.databinding.FragmentLogsBinding +import com.f0x1d.logfox.arch.presentation.ui.fragment.BaseFragment +import com.f0x1d.logfox.database.entity.UserFilter +import com.f0x1d.logfox.feature.logging.api.presentation.LoggingServiceDelegate +import com.f0x1d.logfox.feature.logging.list.R +import com.f0x1d.logfox.feature.logging.list.databinding.FragmentLogsBinding +import com.f0x1d.logfox.feature.logging.list.presentation.LogsViewModel +import com.f0x1d.logfox.feature.logging.list.presentation.adapter.LogsAdapter import com.f0x1d.logfox.model.logline.LogLine import com.f0x1d.logfox.navigation.Directions import com.f0x1d.logfox.strings.Plurals @@ -31,12 +30,15 @@ import com.f0x1d.logfox.ui.view.setupBackButtonForNavController import com.f0x1d.logfox.ui.view.setupCloseButton import dagger.hilt.android.AndroidEntryPoint import dev.chrisbanes.insetter.applyInsetter -import kotlinx.coroutines.flow.update +import javax.inject.Inject @AndroidEntryPoint -class LogsFragment: BaseViewModelFragment() { +class LogsFragment : BaseFragment() { - override val viewModel by hiltNavGraphViewModels(Directions.logsFragment) + private val viewModel by viewModels() + + @Inject + lateinit var loggingServiceDelegate: LoggingServiceDelegate private val adapter by lazy { LogsAdapter( @@ -52,22 +54,21 @@ class LogsFragment: BaseViewModelFragment() }, ) } - private var changingState = false private val clearSelectionOnBackPressedCallback = object : OnBackPressedCallback(false) { override fun handleOnBackPressed() { - viewModel.selectedItems.update { - emptySet() - } + viewModel.clearSelection() } } private val exportLogsLauncher = registerForActivityResult( - ActivityResultContracts.CreateDocument("text/*") + ActivityResultContracts.CreateDocument("text/*"), ) { viewModel.exportSelectedLogsTo(it ?: return@registerForActivityResult) } + private var lastPauseEventTimeMillis = 0L + override fun inflateBinding( inflater: LayoutInflater, container: ViewGroup?, @@ -105,12 +106,7 @@ class LogsFragment: BaseViewModelFragment() snackbar(Strings.text_copied) } setClickListenerOn(R.id.extended_copy_selected_item) { - findNavController().navigate( - resId = Directions.action_logsFragment_to_logsExtendedCopyFragment, - args = bundleOf( - "content" to viewModel.selectedItemsContent, - ), - ) + findNavController().navigate(Directions.action_logsFragment_to_logsExtendedCopyFragment) } setClickListenerOn(R.id.selected_to_recording_item) { viewModel.selectedToRecording() @@ -122,13 +118,13 @@ class LogsFragment: BaseViewModelFragment() ) } setClickListenerOn(R.id.clear_item) { - requireContext().sendService(action = LoggingService.ACTION_CLEAR_LOGS) + loggingServiceDelegate.clearLogs() } setClickListenerOn(R.id.restart_logging_item) { - requireContext().sendService(action = LoggingService.ACTION_RESTART_LOGGING) + loggingServiceDelegate.restartLogging() } setClickListenerOn(R.id.exit_item) { - requireContext().sendService(action = LoggingService.ACTION_KILL_SERVICE) + loggingServiceDelegate.killService() } } @@ -136,17 +132,19 @@ class LogsFragment: BaseViewModelFragment() logsRecycler.itemAnimator = null logsRecycler.recycledViewPool.setMaxRecycledViews(0, 50) logsRecycler.adapter = adapter - logsRecycler.addOnScrollListener(object : RecyclerView.OnScrollListener() { - override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { - if (changingState) - return - - if (viewModel.paused.value && !recyclerView.canScrollVertically(1)) { - if (viewModel.resumeLoggingWithBottomTouch) viewModel.resume() - } else - viewModel.pause() - } - }) + logsRecycler.addOnScrollListener( + object : RecyclerView.OnScrollListener() { + override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { + if (viewModel.currentState.paused && !recyclerView.canScrollVertically(1)) { + val enoughTimePassed = (System.currentTimeMillis() - lastPauseEventTimeMillis) > 300 + if (viewModel.resumeLoggingWithBottomTouch && enoughTimePassed) viewModel.resume() + } else { + lastPauseEventTimeMillis = System.currentTimeMillis() + viewModel.pause() + } + } + }, + ) scrollFab.setOnClickListener { if (viewModel.resumeLoggingWithBottomTouch) @@ -155,65 +153,66 @@ class LogsFragment: BaseViewModelFragment() scrollLogToBottom() } - viewModel.queryAndFilters.collectWithLifecycle { - val (query, filters) = it + viewModel.state.collectWithLifecycle { state -> + processQueryAndFilters( + query = state.query, + filters = state.filters, + ) + processSelectedItems(selectedItems = state.selectedItems) + processPaused(paused = state.paused) - val subtitle = buildString { - if (query != null) { - append(query) + updateLogsList(items = state.logs) + } - if (filters.isNotEmpty()) - append(", ") - } + requireActivity().onBackPressedDispatcher.apply { + addCallback(viewLifecycleOwner, clearSelectionOnBackPressedCallback) + } + } + + private fun FragmentLogsBinding.processQueryAndFilters(query: String?, filters: List) { + val subtitle = buildString { + if (query != null) { + append(query) if (filters.isNotEmpty()) - append(resources.getQuantityString(Plurals.filters_count, filters.size, filters.size)) + append(", ") } - toolbar.subtitle = subtitle - placeholderLayout.placeholderText.setText( - when { - viewModel.viewingFile -> Strings.no_logs - - subtitle.isEmpty() -> Strings.waiting_for_logs - - else -> Strings.all_logs_were_filtered_out - } - ) + if (filters.isNotEmpty()) + append(resources.getQuantityString(Plurals.filters_count, filters.size, filters.size)) } - viewModel.selectedItems.collectWithLifecycle { - val selecting = it.isNotEmpty() - - clearSelectionOnBackPressedCallback.isEnabled = selecting + toolbar.subtitle = subtitle + placeholderLayout.placeholderText.setText( + when { + viewModel.viewingFile -> Strings.no_logs - adapter.selectedItems = it - setupToolbarForSelection(selecting, it.size) - } + subtitle.isEmpty() -> Strings.waiting_for_logs - viewModel.logs.collectWithLifecycle { - updateLogsList(it) - } + else -> Strings.all_logs_were_filtered_out + } + ) + } - viewModel.paused.collectWithLifecycle { paused -> - changingState = true + private fun FragmentLogsBinding.processSelectedItems(selectedItems: Set) { + val selecting = selectedItems.isNotEmpty() - toolbar.menu.findItem(R.id.pause_item) - .setIcon(if (paused) Icons.ic_play else Icons.ic_pause) - .setTitle(if (paused) Strings.resume else Strings.pause) + clearSelectionOnBackPressedCallback.isEnabled = selecting - if (paused) { - scrollFab.show() - } else { - scrollFab.hide() - scrollLogToBottom() - } + adapter.selectedItems = selectedItems + setupToolbarForSelection(selecting, selectedItems.size) + } - changingState = false - } + private fun FragmentLogsBinding.processPaused(paused: Boolean) { + toolbar.menu.findItem(R.id.pause_item) + .setIcon(if (paused) Icons.ic_play else Icons.ic_pause) + .setTitle(if (paused) Strings.resume else Strings.pause) - requireActivity().onBackPressedDispatcher.apply { - addCallback(viewLifecycleOwner, clearSelectionOnBackPressedCallback) + if (paused) { + scrollFab.show() + } else { + scrollFab.hide() + scrollLogToBottom() } } @@ -244,14 +243,13 @@ class LogsFragment: BaseViewModelFragment() setupCloseButton() setNavigationOnClickListener { - viewModel.selectedItems.update { - emptySet() - } + viewModel.clearSelection() } - } else if (viewModel.viewingFile) + } else if (viewModel.viewingFile) { setupBackButtonForNavController() - - else invalidateNavigationButton() + } else { + invalidateNavigationButton() + } } private fun FragmentLogsBinding.updateLogsList(items: List?) { diff --git a/feature/logging/src/main/kotlin/com/f0x1d/feature/logging/ui/viewholder/LogViewHolder.kt b/feature/logging/list/src/main/kotlin/com/f0x1d/logfox/feature/logging/list/presentation/ui/viewholder/LogViewHolder.kt similarity index 71% rename from feature/logging/src/main/kotlin/com/f0x1d/feature/logging/ui/viewholder/LogViewHolder.kt rename to feature/logging/list/src/main/kotlin/com/f0x1d/logfox/feature/logging/list/presentation/ui/viewholder/LogViewHolder.kt index 0e5e3fbd..f70d3049 100644 --- a/feature/logging/src/main/kotlin/com/f0x1d/feature/logging/ui/viewholder/LogViewHolder.kt +++ b/feature/logging/list/src/main/kotlin/com/f0x1d/logfox/feature/logging/list/presentation/ui/viewholder/LogViewHolder.kt @@ -1,12 +1,11 @@ -package com.f0x1d.feature.logging.ui.viewholder +package com.f0x1d.logfox.feature.logging.list.presentation.ui.viewholder import android.view.Gravity import androidx.appcompat.widget.PopupMenu -import com.f0x1d.feature.logging.adapter.LogsAdapter -import com.f0x1d.logfox.arch.ui.viewholder.BaseViewHolder +import com.f0x1d.logfox.arch.presentation.ui.viewholder.BaseViewHolder import com.f0x1d.logfox.datetime.dateTimeFormatter -import com.f0x1d.logfox.feature.logging.R -import com.f0x1d.logfox.feature.logging.databinding.ItemLogBinding +import com.f0x1d.logfox.feature.logging.list.R +import com.f0x1d.logfox.feature.logging.list.databinding.ItemLogBinding import com.f0x1d.logfox.model.logline.LogLine class LogViewHolder( @@ -40,7 +39,7 @@ class LogViewHolder( init { binding.apply { root.setOnClickListener { - val adapter = adapter() ?: return@setOnClickListener + val adapter = adapter() ?: return@setOnClickListener if (adapter.selectedItems.isNotEmpty()) selectItem() @@ -48,7 +47,7 @@ class LogViewHolder( expandOrCollapseItem() } root.setOnLongClickListener { - val adapter = adapter() ?: return@setOnLongClickListener true + val adapter = adapter() ?: return@setOnLongClickListener true if (adapter.selectedItems.isNotEmpty()) expandOrCollapseItem() @@ -61,12 +60,12 @@ class LogViewHolder( } override fun ItemLogBinding.bindTo(data: LogLine) { - adapter()?.textSize?.also { + adapter()?.textSize?.also { logText.textSize = it levelView.textSize = it } - adapter()?.logsFormat?.let { values -> + adapter()?.logsFormat?.let { values -> logText.text = data.formatOriginal( values = values, formatDate = dateTimeFormatter::formatDate, @@ -83,14 +82,14 @@ class LogViewHolder( popupMenu.dismiss() } - private fun selectItem() = adapter()?.selectedItems?.apply { + private fun selectItem() = adapter()?.selectedItems?.apply { currentItem?.also { val newValue = any { logLine -> it.id == logLine.id }.not() selectedItem(it, newValue) } } - private fun ItemLogBinding.expandOrCollapseItem() = adapter()?.apply { + private fun ItemLogBinding.expandOrCollapseItem() = adapter()?.apply { expandedStates.apply { currentItem?.also { val newValue = getOrElse(it.id) { logsExpanded }.not() @@ -101,7 +100,7 @@ class LogViewHolder( } } - private fun ItemLogBinding.changeExpandedAndSelected(logLine: LogLine) = adapter()?.apply { + private fun ItemLogBinding.changeExpandedAndSelected(logLine: LogLine) = adapter()?.apply { val expanded = expandedStates.getOrElse(logLine.id) { logsExpanded } logText.maxLines = if (expanded) Int.MAX_VALUE else 1 diff --git a/feature/logging/src/main/res/layout/fragment_logs.xml b/feature/logging/list/src/main/res/layout/fragment_logs.xml similarity index 100% rename from feature/logging/src/main/res/layout/fragment_logs.xml rename to feature/logging/list/src/main/res/layout/fragment_logs.xml diff --git a/feature/logging/src/main/res/layout/item_log.xml b/feature/logging/list/src/main/res/layout/item_log.xml similarity index 100% rename from feature/logging/src/main/res/layout/item_log.xml rename to feature/logging/list/src/main/res/layout/item_log.xml diff --git a/feature/logging/src/main/res/layout/placeholder_logs.xml b/feature/logging/list/src/main/res/layout/placeholder_logs.xml similarity index 100% rename from feature/logging/src/main/res/layout/placeholder_logs.xml rename to feature/logging/list/src/main/res/layout/placeholder_logs.xml diff --git a/feature/logging/src/main/res/menu/log_menu.xml b/feature/logging/list/src/main/res/menu/log_menu.xml similarity index 100% rename from feature/logging/src/main/res/menu/log_menu.xml rename to feature/logging/list/src/main/res/menu/log_menu.xml diff --git a/feature/logging/src/main/res/menu/logs_menu.xml b/feature/logging/list/src/main/res/menu/logs_menu.xml similarity index 100% rename from feature/logging/src/main/res/menu/logs_menu.xml rename to feature/logging/list/src/main/res/menu/logs_menu.xml diff --git a/feature/logging/search/.gitignore b/feature/logging/search/.gitignore new file mode 100644 index 00000000..567609b1 --- /dev/null +++ b/feature/logging/search/.gitignore @@ -0,0 +1 @@ +build/ diff --git a/feature/logging/search/build.gradle.kts b/feature/logging/search/build.gradle.kts new file mode 100644 index 00000000..4e841a7d --- /dev/null +++ b/feature/logging/search/build.gradle.kts @@ -0,0 +1,9 @@ +plugins { + id("logfox.android.feature") +} + +android.namespace = "com.f0x1d.logfox.feature.logging.search" + +dependencies { + implementation(projects.feature.logging.api) +} diff --git a/feature/logging/search/src/main/kotlin/com/f0x1d/logfox/feature/logging/search/presentation/SearchLogsAction.kt b/feature/logging/search/src/main/kotlin/com/f0x1d/logfox/feature/logging/search/presentation/SearchLogsAction.kt new file mode 100644 index 00000000..a63c8f46 --- /dev/null +++ b/feature/logging/search/src/main/kotlin/com/f0x1d/logfox/feature/logging/search/presentation/SearchLogsAction.kt @@ -0,0 +1,5 @@ +package com.f0x1d.logfox.feature.logging.search.presentation + +sealed interface SearchLogsAction { + data object Dismiss : SearchLogsAction +} diff --git a/feature/logging/search/src/main/kotlin/com/f0x1d/logfox/feature/logging/search/presentation/SearchLogsState.kt b/feature/logging/search/src/main/kotlin/com/f0x1d/logfox/feature/logging/search/presentation/SearchLogsState.kt new file mode 100644 index 00000000..0f5949eb --- /dev/null +++ b/feature/logging/search/src/main/kotlin/com/f0x1d/logfox/feature/logging/search/presentation/SearchLogsState.kt @@ -0,0 +1,5 @@ +package com.f0x1d.logfox.feature.logging.search.presentation + +data class SearchLogsState( + val query: String? = null, +) diff --git a/feature/logging/search/src/main/kotlin/com/f0x1d/logfox/feature/logging/search/presentation/SearchLogsViewModel.kt b/feature/logging/search/src/main/kotlin/com/f0x1d/logfox/feature/logging/search/presentation/SearchLogsViewModel.kt new file mode 100644 index 00000000..9a32a19d --- /dev/null +++ b/feature/logging/search/src/main/kotlin/com/f0x1d/logfox/feature/logging/search/presentation/SearchLogsViewModel.kt @@ -0,0 +1,37 @@ +package com.f0x1d.logfox.feature.logging.search.presentation + +import android.app.Application +import androidx.lifecycle.viewModelScope +import com.f0x1d.logfox.arch.viewmodel.BaseViewModel +import com.f0x1d.logfox.feature.logging.api.data.QueryDataSource +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +class SearchLogsViewModel @Inject constructor( + private val queryDataSource: QueryDataSource, + application: Application, +) : BaseViewModel( + initialStateProvider = { SearchLogsState() }, + application = application, +) { + init { + load() + } + + private fun load() { + viewModelScope.launch { + queryDataSource.query.collect { query -> + reduce { copy(query = query) } + } + } + } + + fun updateQuery(query: String?) { + viewModelScope.launch { + queryDataSource.updateQuery(query) + sendAction(SearchLogsAction.Dismiss) + } + } +} diff --git a/feature/logging/src/main/kotlin/com/f0x1d/feature/logging/ui/dialog/SearchBottomSheet.kt b/feature/logging/search/src/main/kotlin/com/f0x1d/logfox/feature/logging/search/presentation/ui/SearchLogsBottomSheetFragment.kt similarity index 50% rename from feature/logging/src/main/kotlin/com/f0x1d/feature/logging/ui/dialog/SearchBottomSheet.kt rename to feature/logging/search/src/main/kotlin/com/f0x1d/logfox/feature/logging/search/presentation/ui/SearchLogsBottomSheetFragment.kt index f02ed602..3d3284bf 100644 --- a/feature/logging/src/main/kotlin/com/f0x1d/feature/logging/ui/dialog/SearchBottomSheet.kt +++ b/feature/logging/search/src/main/kotlin/com/f0x1d/logfox/feature/logging/search/presentation/ui/SearchLogsBottomSheetFragment.kt @@ -1,4 +1,4 @@ -package com.f0x1d.feature.logging.ui.dialog +package com.f0x1d.logfox.feature.logging.search.presentation.ui import android.os.Bundle import android.view.LayoutInflater @@ -6,15 +6,17 @@ import android.view.View import android.view.ViewGroup import android.view.inputmethod.EditorInfo import androidx.core.view.isVisible -import androidx.hilt.navigation.fragment.hiltNavGraphViewModels -import com.f0x1d.feature.logging.viewmodel.LogsViewModel -import com.f0x1d.logfox.arch.ui.dialog.BaseBottomSheet -import com.f0x1d.logfox.feature.logging.databinding.SheetSearchBinding -import com.f0x1d.logfox.navigation.Directions +import androidx.fragment.app.viewModels +import com.f0x1d.logfox.arch.presentation.ui.dialog.BaseBottomSheetFragment +import com.f0x1d.logfox.feature.logging.search.databinding.SheetSearchBinding +import com.f0x1d.logfox.feature.logging.search.presentation.SearchLogsAction +import com.f0x1d.logfox.feature.logging.search.presentation.SearchLogsViewModel +import dagger.hilt.android.AndroidEntryPoint -class SearchBottomSheet: BaseBottomSheet() { +@AndroidEntryPoint +class SearchLogsBottomSheetFragment : BaseBottomSheetFragment() { - private val logsViewModel by hiltNavGraphViewModels(Directions.logsFragment) + private val viewModel by viewModels() override fun inflateBinding( inflater: LayoutInflater, @@ -22,11 +24,6 @@ class SearchBottomSheet: BaseBottomSheet() { ) = SheetSearchBinding.inflate(inflater, container, false) override fun SheetSearchBinding.onViewCreated(view: View, savedInstanceState: Bundle?) { - val query = logsViewModel.query.value - - queryText.setText(query) - - clearSearchButton.isVisible = query != null clearSearchButton.setOnClickListener { search(null) } @@ -43,12 +40,23 @@ class SearchBottomSheet: BaseBottomSheet() { } queryText.requestFocus() + + viewModel.state.collectWithLifecycle { state -> + queryText.setText(state.query) + + clearSearchButton.isVisible = state.query != null + } + + viewModel.actions.collectWithLifecycle { action -> + when (action) { + is SearchLogsAction.Dismiss -> dismiss() + } + } } private fun search(text: String?) { if (text?.isEmpty() == true) return - logsViewModel.query(text) - dismiss() + viewModel.updateQuery(text) } } diff --git a/feature/logging/src/main/res/layout/sheet_search.xml b/feature/logging/search/src/main/res/layout/sheet_search.xml similarity index 100% rename from feature/logging/src/main/res/layout/sheet_search.xml rename to feature/logging/search/src/main/res/layout/sheet_search.xml diff --git a/feature/logging/service/.gitignore b/feature/logging/service/.gitignore new file mode 100644 index 00000000..567609b1 --- /dev/null +++ b/feature/logging/service/.gitignore @@ -0,0 +1 @@ +build/ diff --git a/feature/logging/service/build.gradle.kts b/feature/logging/service/build.gradle.kts new file mode 100644 index 00000000..1ca94a83 --- /dev/null +++ b/feature/logging/service/build.gradle.kts @@ -0,0 +1,12 @@ +plugins { + id("logfox.android.feature") +} + +android.namespace = "com.f0x1d.logfox.feature.logging.service" + +dependencies { + implementation(projects.feature.crashes.api) + implementation(projects.feature.filters.api) + implementation(projects.feature.logging.api) + implementation(projects.feature.recordings.api) +} diff --git a/feature/logging/src/main/AndroidManifest.xml b/feature/logging/service/src/main/AndroidManifest.xml similarity index 85% rename from feature/logging/src/main/AndroidManifest.xml rename to feature/logging/service/src/main/AndroidManifest.xml index 5a395514..fe396558 100644 --- a/feature/logging/src/main/AndroidManifest.xml +++ b/feature/logging/service/src/main/AndroidManifest.xml @@ -6,7 +6,7 @@ diff --git a/feature/logging/service/src/main/kotlin/com/f0x1d/logfox/feature/logging/service/di/LoggingServiceDelegateModule.kt b/feature/logging/service/src/main/kotlin/com/f0x1d/logfox/feature/logging/service/di/LoggingServiceDelegateModule.kt new file mode 100644 index 00000000..ce82eb9e --- /dev/null +++ b/feature/logging/service/src/main/kotlin/com/f0x1d/logfox/feature/logging/service/di/LoggingServiceDelegateModule.kt @@ -0,0 +1,18 @@ +package com.f0x1d.logfox.feature.logging.service.di + +import com.f0x1d.logfox.feature.logging.api.presentation.LoggingServiceDelegate +import com.f0x1d.logfox.feature.logging.service.presentation.LoggingServiceDelegateImpl +import dagger.Binds +import dagger.Module +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent + +@Module +@InstallIn(SingletonComponent::class) +internal interface LoggingServiceDelegateModule { + + @Binds + fun bindLoggingServiceDelegate( + loggingServiceDelegateImpl: LoggingServiceDelegateImpl, + ): LoggingServiceDelegate +} diff --git a/feature/logging/src/main/kotlin/com/f0x1d/feature/logging/service/LoggingService.kt b/feature/logging/service/src/main/kotlin/com/f0x1d/logfox/feature/logging/service/presentation/LoggingService.kt similarity index 84% rename from feature/logging/src/main/kotlin/com/f0x1d/feature/logging/service/LoggingService.kt rename to feature/logging/service/src/main/kotlin/com/f0x1d/logfox/feature/logging/service/presentation/LoggingService.kt index fb0ef88f..f30bef78 100644 --- a/feature/logging/src/main/kotlin/com/f0x1d/feature/logging/service/LoggingService.kt +++ b/feature/logging/service/src/main/kotlin/com/f0x1d/logfox/feature/logging/service/presentation/LoggingService.kt @@ -1,4 +1,4 @@ -package com.f0x1d.feature.logging.service +package com.f0x1d.logfox.feature.logging.service.presentation import android.content.Intent import android.os.Binder @@ -15,12 +15,12 @@ import com.f0x1d.logfox.arch.di.DefaultDispatcher import com.f0x1d.logfox.arch.makeServicePendingIntent import com.f0x1d.logfox.arch.toast import com.f0x1d.logfox.database.entity.UserFilter -import com.f0x1d.logfox.feature.crashes.core.controller.CrashesController -import com.f0x1d.logfox.feature.filters.core.repository.FiltersRepository -import com.f0x1d.logfox.feature.logging.core.model.suits -import com.f0x1d.logfox.feature.logging.core.repository.LoggingRepository -import com.f0x1d.logfox.feature.logging.core.store.LoggingStore -import com.f0x1d.logfox.feature.recordings.core.controller.RecordingController +import com.f0x1d.logfox.feature.crashes.api.data.CrashesController +import com.f0x1d.logfox.feature.filters.api.data.FiltersRepository +import com.f0x1d.logfox.feature.logging.api.data.LoggingRepository +import com.f0x1d.logfox.feature.logging.api.data.LogsDataSource +import com.f0x1d.logfox.feature.logging.api.model.suits +import com.f0x1d.logfox.feature.recordings.api.data.RecordingController import com.f0x1d.logfox.model.exception.TerminalNotSupportedException import com.f0x1d.logfox.model.logline.LogLine import com.f0x1d.logfox.preferences.shared.AppPreferences @@ -29,6 +29,7 @@ import com.f0x1d.logfox.terminals.DefaultTerminal import com.f0x1d.logfox.terminals.base.Terminal import com.f0x1d.logfox.ui.Icons import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.Job import kotlinx.coroutines.NonCancellable @@ -42,6 +43,7 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.withContext +import timber.log.Timber import java.util.LinkedList import javax.inject.Inject @@ -70,7 +72,7 @@ class LoggingService : LifecycleService() { lateinit var filtersRepository: FiltersRepository @Inject - lateinit var loggingStore: LoggingStore + lateinit var logsDataSource: LogsDataSource @Inject lateinit var appPreferences: AppPreferences @@ -109,6 +111,7 @@ class LoggingService : LifecycleService() { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { super.onStartCommand(intent, flags, startId) + Timber.d("got command ${intent?.action}") when (intent?.action) { ACTION_RESTART_LOGGING -> restartLogging() ACTION_CLEAR_LOGS -> clearLogs() @@ -120,10 +123,13 @@ class LoggingService : LifecycleService() { } private fun startLogging() { + Timber.d("startLogging") if (loggingJob?.isActive == true) return var loggingTerminal = terminals[appPreferences.selectedTerminalIndex] + Timber.d("selected terminal $loggingTerminal") + loggingJob = lifecycleScope.launch { try { launch { @@ -131,16 +137,21 @@ class LoggingService : LifecycleService() { delay(appPreferences.logsUpdateInterval) logsMutex.withLock { - loggingStore.updateLogs(logs) + Timber.d("sending update logs to store") + logsDataSource.updateLogs(logs) } } } while (true) { + Timber.d("in loop starting") + loggingRepository.startLogging( terminal = loggingTerminal, startingId = logs.lastOrNull()?.id ?: 0, ).catch { throwable -> + Timber.e(throwable) + if (throwable is TerminalNotSupportedException) { if (appPreferences.fallbackToDefaultTerminal) { toast(Strings.terminal_unavailable_falling_back) @@ -150,7 +161,7 @@ class LoggingService : LifecycleService() { } else { delay(10000) // waiting for 10sec before new attempt } - } else { + } else if (throwable !is CancellationException) { toast(getString(Strings.error, throwable.localizedMessage)) throwable.printStackTrace() @@ -176,6 +187,7 @@ class LoggingService : LifecycleService() { } } } finally { + Timber.d("finally block") withContext(NonCancellable) { recordingController.loggingStopped() clearLogs().join() @@ -187,16 +199,21 @@ class LoggingService : LifecycleService() { } private fun restartLogging() = lifecycleScope.launch { + Timber.d("restaring logs") + loggingJob?.cancelAndJoin() + Timber.d("cancelled loggingJob") + startLogging() } private fun clearLogs() = lifecycleScope.launch { + Timber.d("clearing logs") logsMutex.withLock { logs.clear() } - loggingStore.updateLogs(emptyList()) + logsDataSource.updateLogs(emptyList()) } private fun notification() = NotificationCompat.Builder(this, LOGGING_STATUS_CHANNEL_ID) @@ -214,7 +231,10 @@ class LoggingService : LifecycleService() { .build() private fun killApp() = lifecycleScope.launch { + Timber.d("killing app") + loggingJob?.cancelAndJoin() + Timber.d("cancelled loggingJob and now can stop app") activityManager.appTasks.forEach { it.finishAndRemoveTask() diff --git a/feature/logging/service/src/main/kotlin/com/f0x1d/logfox/feature/logging/service/presentation/LoggingServiceDelegateImpl.kt b/feature/logging/service/src/main/kotlin/com/f0x1d/logfox/feature/logging/service/presentation/LoggingServiceDelegateImpl.kt new file mode 100644 index 00000000..85674f6c --- /dev/null +++ b/feature/logging/service/src/main/kotlin/com/f0x1d/logfox/feature/logging/service/presentation/LoggingServiceDelegateImpl.kt @@ -0,0 +1,23 @@ +package com.f0x1d.logfox.feature.logging.service.presentation + +import android.content.Context +import com.f0x1d.logfox.arch.sendService +import com.f0x1d.logfox.feature.logging.api.presentation.LoggingServiceDelegate +import dagger.hilt.android.qualifiers.ApplicationContext +import javax.inject.Inject + +internal class LoggingServiceDelegateImpl @Inject constructor( + @ApplicationContext private val context: Context, +) : LoggingServiceDelegate { + override fun clearLogs() { + context.sendService(LoggingService.ACTION_CLEAR_LOGS) + } + + override fun restartLogging() { + context.sendService(LoggingService.ACTION_RESTART_LOGGING) + } + + override fun killService() { + context.sendService(LoggingService.ACTION_KILL_SERVICE) + } +} diff --git a/feature/logging/src/main/kotlin/com/f0x1d/feature/logging/service/MainActivityPendingIntentProvider.kt b/feature/logging/service/src/main/kotlin/com/f0x1d/logfox/feature/logging/service/presentation/MainActivityPendingIntentProvider.kt similarity index 66% rename from feature/logging/src/main/kotlin/com/f0x1d/feature/logging/service/MainActivityPendingIntentProvider.kt rename to feature/logging/service/src/main/kotlin/com/f0x1d/logfox/feature/logging/service/presentation/MainActivityPendingIntentProvider.kt index ed9d04f6..705a014c 100644 --- a/feature/logging/src/main/kotlin/com/f0x1d/feature/logging/service/MainActivityPendingIntentProvider.kt +++ b/feature/logging/service/src/main/kotlin/com/f0x1d/logfox/feature/logging/service/presentation/MainActivityPendingIntentProvider.kt @@ -1,4 +1,4 @@ -package com.f0x1d.feature.logging.service +package com.f0x1d.logfox.feature.logging.service.presentation import android.app.PendingIntent diff --git a/feature/logging/src/main/kotlin/com/f0x1d/feature/logging/viewmodel/LogsViewModel.kt b/feature/logging/src/main/kotlin/com/f0x1d/feature/logging/viewmodel/LogsViewModel.kt deleted file mode 100644 index ee39a5ee..00000000 --- a/feature/logging/src/main/kotlin/com/f0x1d/feature/logging/viewmodel/LogsViewModel.kt +++ /dev/null @@ -1,178 +0,0 @@ -package com.f0x1d.feature.logging.viewmodel - -import android.app.Application -import android.net.Uri -import androidx.lifecycle.viewModelScope -import com.f0x1d.feature.logging.di.FileUri -import com.f0x1d.logfox.arch.di.DefaultDispatcher -import com.f0x1d.logfox.arch.di.IODispatcher -import com.f0x1d.logfox.arch.viewmodel.BaseViewModel -import com.f0x1d.logfox.database.entity.UserFilter -import com.f0x1d.logfox.datetime.DateTimeFormatter -import com.f0x1d.logfox.feature.filters.core.repository.FiltersRepository -import com.f0x1d.logfox.feature.logging.core.model.filterAndSearch -import com.f0x1d.logfox.feature.logging.core.store.LoggingStore -import com.f0x1d.logfox.feature.recordings.core.repository.RecordingsRepository -import com.f0x1d.logfox.model.logline.LogLine -import com.f0x1d.logfox.preferences.shared.AppPreferences -import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.SharingStarted -import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.filter -import kotlinx.coroutines.flow.flowOf -import kotlinx.coroutines.flow.flowOn -import kotlinx.coroutines.flow.mapNotNull -import kotlinx.coroutines.flow.scan -import kotlinx.coroutines.flow.stateIn -import kotlinx.coroutines.flow.update -import kotlinx.coroutines.withContext -import javax.inject.Inject - -@HiltViewModel -class LogsViewModel @Inject constructor( - @FileUri val fileUri: Uri?, - private val loggingStore: LoggingStore, - private val filtersRepository: FiltersRepository, - private val recordingsRepository: RecordingsRepository, - private val appPreferences: AppPreferences, - @DefaultDispatcher private val defaultDispatcher: CoroutineDispatcher, - @IODispatcher private val ioDispatcher: CoroutineDispatcher, - dateTimeFormatter: DateTimeFormatter, - application: Application, -): BaseViewModel(application), DateTimeFormatter by dateTimeFormatter { - - val query = MutableStateFlow(null) - val queryAndFilters = query.combine( - filtersRepository.getAllEnabledAsFlow(), - ) { query, filters -> query to filters } - - val paused = MutableStateFlow(false) - - val viewingFile = fileUri != null - val viewingFileName = fileUri?.readFileName(ctx) - - val selectedItems = MutableStateFlow(emptySet()) - - val selectedItemsContent get() = selectedItems.value.joinToString("\n") { line -> - appPreferences.originalOf( - logLine = line, - formatDate = ::formatDate, - formatTime = ::formatTime, - ) - } - - val logs = combine( - fileUri?.readFileContentsAsFlow( - context = ctx, - logsDisplayLimit = appPreferences.logsDisplayLimit, - ) ?: loggingStore.logs, - filtersRepository.getAllEnabledAsFlow(), - query, - if (!viewingFile) paused else flowOf(false) - ) { logs, filters, query, paused -> - LogsData(logs, filters, query, paused) - }.scan(LogsData()) { accumulator, data -> - when { - !data.paused - // In case they were cleared - || data.logs.isEmpty() -> data - - data.query != accumulator.query - || data.filters != accumulator.filters - -> data.copy( - logs = accumulator.logs, - ) - - else -> data.copy( - logs = accumulator.logs, - passing = false, - ) - } - }.filter { data -> - data.passing - }.mapNotNull { data -> - data.logs.filterAndSearch( - filters = data.filters, - query = data.query, - ) - }.flowOn( - defaultDispatcher, - ).stateIn( - scope = viewModelScope, - started = SharingStarted.Eagerly, - initialValue = emptyList(), - ) - - val resumeLoggingWithBottomTouch get() = appPreferences.resumeLoggingWithBottomTouch - val logsTextSize get() = appPreferences.logsTextSize.toFloat() - val logsExpanded get() = appPreferences.logsExpanded - val logsFormat get() = appPreferences.showLogValues - - fun selectLine(logLine: LogLine, selected: Boolean) = selectedItems.updateSet { - if (selected) add( - logLine - ) else remove( - logLine - ) - } - - fun selectAll() { - if (selectedItems.value.containsAll(logs.value)) selectedItems.update { - emptySet() - } else selectedItems.update { - logs.value.toSet() - } - } - - fun selectedToRecording() = launchCatching { - recordingsRepository.createRecordingFrom( - lines = withContext(defaultDispatcher) { - selectedItems.value.sortedBy { it.dateAndTime } - }, - ) - } - - fun exportSelectedLogsTo(uri: Uri) = launchCatching(ioDispatcher) { - ctx.contentResolver.openOutputStream(uri)?.use { - it.write( - selectedItems.value.joinToString("\n") { line -> - appPreferences.originalOf( - logLine = line, - formatDate = ::formatDate, - formatTime = ::formatTime, - ) - }.encodeToByteArray() - ) - } - } - - fun query(query: String?) = this.query.update { query } - - fun switchState() = if (!paused.value) - pause() - else - resume() - - fun pause() = paused.update { true } - fun resume() = paused.update { false } - - fun originalOf(logLine: LogLine): String = appPreferences.originalOf( - logLine = logLine, - formatDate = ::formatDate, - formatTime = ::formatTime, - ) - - private fun MutableStateFlow>.updateSet(block: MutableSet.() -> Unit) = update { - it.toMutableSet().apply(block).toSet() - } - - private data class LogsData( - val logs: List = emptyList(), - val filters: List = emptyList(), - val query: String? = null, - val paused: Boolean = false, - val passing: Boolean = true, - ) -} diff --git a/feature/recordings-core/build.gradle.kts b/feature/recordings-core/build.gradle.kts deleted file mode 100644 index 3812f347..00000000 --- a/feature/recordings-core/build.gradle.kts +++ /dev/null @@ -1,9 +0,0 @@ -plugins { - id("logfox.android.feature") -} - -android.namespace = "com.f0x1d.logfox.feature.recordings.core" - -dependencies { - implementation(projects.feature.loggingCore) -} diff --git a/feature/recordings/api/.gitignore b/feature/recordings/api/.gitignore new file mode 100644 index 00000000..567609b1 --- /dev/null +++ b/feature/recordings/api/.gitignore @@ -0,0 +1 @@ +build/ diff --git a/feature/recordings/api/build.gradle.kts b/feature/recordings/api/build.gradle.kts new file mode 100644 index 00000000..69801a3a --- /dev/null +++ b/feature/recordings/api/build.gradle.kts @@ -0,0 +1,9 @@ +plugins { + id("logfox.android.feature") +} + +android.namespace = "com.f0x1d.logfox.feature.recordings.api" + +dependencies { + +} diff --git a/feature/recordings/api/src/main/kotlin/com/f0x1d/logfox/feature/recordings/api/data/RecordingController.kt b/feature/recordings/api/src/main/kotlin/com/f0x1d/logfox/feature/recordings/api/data/RecordingController.kt new file mode 100644 index 00000000..072e2f56 --- /dev/null +++ b/feature/recordings/api/src/main/kotlin/com/f0x1d/logfox/feature/recordings/api/data/RecordingController.kt @@ -0,0 +1,21 @@ +package com.f0x1d.logfox.feature.recordings.api.data + +import com.f0x1d.logfox.database.entity.LogRecording +import com.f0x1d.logfox.model.logline.LogLine +import kotlinx.coroutines.flow.StateFlow + +interface RecordingController { + val recordingState: StateFlow + val reader: suspend (LogLine) -> Unit + + suspend fun record() + suspend fun pause() + suspend fun resume() + suspend fun end(): LogRecording? + + suspend fun loggingStopped() +} + +enum class RecordingState { + IDLE, RECORDING, PAUSED, SAVING +} diff --git a/feature/recordings/api/src/main/kotlin/com/f0x1d/logfox/feature/recordings/api/data/RecordingNotificationController.kt b/feature/recordings/api/src/main/kotlin/com/f0x1d/logfox/feature/recordings/api/data/RecordingNotificationController.kt new file mode 100644 index 00000000..52d00b1b --- /dev/null +++ b/feature/recordings/api/src/main/kotlin/com/f0x1d/logfox/feature/recordings/api/data/RecordingNotificationController.kt @@ -0,0 +1,13 @@ +package com.f0x1d.logfox.feature.recordings.api.data + +interface RecordingNotificationController { + + companion object { + const val RECORDING_NOTIFICATIONS_TAG = "recording" + const val RECORDING_NOTIFICATIONS_ID = 0 + } + + fun sendRecordingNotification() + fun sendRecordingPausedNotification() + fun cancelRecordingNotification() +} diff --git a/feature/recordings/api/src/main/kotlin/com/f0x1d/logfox/feature/recordings/api/data/RecordingsRepository.kt b/feature/recordings/api/src/main/kotlin/com/f0x1d/logfox/feature/recordings/api/data/RecordingsRepository.kt new file mode 100644 index 00000000..7d83104d --- /dev/null +++ b/feature/recordings/api/src/main/kotlin/com/f0x1d/logfox/feature/recordings/api/data/RecordingsRepository.kt @@ -0,0 +1,12 @@ +package com.f0x1d.logfox.feature.recordings.api.data + +import com.f0x1d.logfox.arch.repository.DatabaseProxyRepository +import com.f0x1d.logfox.database.entity.LogRecording +import com.f0x1d.logfox.model.logline.LogLine + +interface RecordingsRepository : DatabaseProxyRepository { + suspend fun saveAll(): LogRecording + suspend fun createRecordingFrom(lines: List) + + suspend fun updateTitle(logRecording: LogRecording, newTitle: String) +} diff --git a/feature/recordings-core/src/main/kotlin/com/f0x1d/logfox/feature/recordings/core/controller/reader/RecordingReader.kt b/feature/recordings/api/src/main/kotlin/com/f0x1d/logfox/feature/recordings/api/data/reader/RecordingReader.kt similarity index 97% rename from feature/recordings-core/src/main/kotlin/com/f0x1d/logfox/feature/recordings/core/controller/reader/RecordingReader.kt rename to feature/recordings/api/src/main/kotlin/com/f0x1d/logfox/feature/recordings/api/data/reader/RecordingReader.kt index 02eb4e4c..e2cc655f 100644 --- a/feature/recordings-core/src/main/kotlin/com/f0x1d/logfox/feature/recordings/core/controller/reader/RecordingReader.kt +++ b/feature/recordings/api/src/main/kotlin/com/f0x1d/logfox/feature/recordings/api/data/reader/RecordingReader.kt @@ -1,4 +1,4 @@ -package com.f0x1d.logfox.feature.recordings.core.controller.reader +package com.f0x1d.logfox.feature.recordings.api.data.reader import com.f0x1d.logfox.datetime.DateTimeFormatter import com.f0x1d.logfox.model.logline.LogLine diff --git a/feature/recordings/build.gradle.kts b/feature/recordings/build.gradle.kts deleted file mode 100644 index 307d674f..00000000 --- a/feature/recordings/build.gradle.kts +++ /dev/null @@ -1,9 +0,0 @@ -plugins { - id("logfox.android.feature") -} - -android.namespace = "com.f0x1d.logfox.feature.recordings" - -dependencies { - implementation(projects.feature.recordingsCore) -} diff --git a/feature/recordings/details/.gitignore b/feature/recordings/details/.gitignore new file mode 100644 index 00000000..42afabfd --- /dev/null +++ b/feature/recordings/details/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/feature/recordings/details/build.gradle.kts b/feature/recordings/details/build.gradle.kts new file mode 100644 index 00000000..ede4b50e --- /dev/null +++ b/feature/recordings/details/build.gradle.kts @@ -0,0 +1,10 @@ +plugins { + id("logfox.android.feature") +} + +android.namespace = "com.f0x1d.logfox.feature.recordings.details" + +dependencies { + implementation(projects.feature.recordings.api) + implementation(projects.feature.logging.api) +} diff --git a/feature/recordings/src/main/kotlin/com/f0x1d/logfox/feature/recordings/di/RecordingViewModelModule.kt b/feature/recordings/details/src/main/kotlin/com/f0x1d/logfox/feature/recordings/details/di/RecordingDetailsViewModelModule.kt similarity index 91% rename from feature/recordings/src/main/kotlin/com/f0x1d/logfox/feature/recordings/di/RecordingViewModelModule.kt rename to feature/recordings/details/src/main/kotlin/com/f0x1d/logfox/feature/recordings/details/di/RecordingDetailsViewModelModule.kt index e37cfe0e..a4c80b0a 100644 --- a/feature/recordings/src/main/kotlin/com/f0x1d/logfox/feature/recordings/di/RecordingViewModelModule.kt +++ b/feature/recordings/details/src/main/kotlin/com/f0x1d/logfox/feature/recordings/details/di/RecordingDetailsViewModelModule.kt @@ -1,4 +1,4 @@ -package com.f0x1d.logfox.feature.recordings.di +package com.f0x1d.logfox.feature.recordings.details.di import androidx.lifecycle.SavedStateHandle import dagger.Module diff --git a/feature/recordings/details/src/main/kotlin/com/f0x1d/logfox/feature/recordings/details/presentation/RecordingDetailsAction.kt b/feature/recordings/details/src/main/kotlin/com/f0x1d/logfox/feature/recordings/details/presentation/RecordingDetailsAction.kt new file mode 100644 index 00000000..6fd3ba86 --- /dev/null +++ b/feature/recordings/details/src/main/kotlin/com/f0x1d/logfox/feature/recordings/details/presentation/RecordingDetailsAction.kt @@ -0,0 +1,3 @@ +package com.f0x1d.logfox.feature.recordings.details.presentation + +sealed interface RecordingDetailsAction diff --git a/feature/recordings/details/src/main/kotlin/com/f0x1d/logfox/feature/recordings/details/presentation/RecordingDetailsState.kt b/feature/recordings/details/src/main/kotlin/com/f0x1d/logfox/feature/recordings/details/presentation/RecordingDetailsState.kt new file mode 100644 index 00000000..c4a9209f --- /dev/null +++ b/feature/recordings/details/src/main/kotlin/com/f0x1d/logfox/feature/recordings/details/presentation/RecordingDetailsState.kt @@ -0,0 +1,7 @@ +package com.f0x1d.logfox.feature.recordings.details.presentation + +import com.f0x1d.logfox.database.entity.LogRecording + +data class RecordingDetailsState( + val recording: LogRecording? = null, +) diff --git a/feature/recordings/src/main/kotlin/com/f0x1d/logfox/feature/recordings/viewmodel/RecordingViewModel.kt b/feature/recordings/details/src/main/kotlin/com/f0x1d/logfox/feature/recordings/details/presentation/RecordingDetailsViewModel.kt similarity index 63% rename from feature/recordings/src/main/kotlin/com/f0x1d/logfox/feature/recordings/viewmodel/RecordingViewModel.kt rename to feature/recordings/details/src/main/kotlin/com/f0x1d/logfox/feature/recordings/details/presentation/RecordingDetailsViewModel.kt index a7ad50c1..fa7713e3 100644 --- a/feature/recordings/src/main/kotlin/com/f0x1d/logfox/feature/recordings/viewmodel/RecordingViewModel.kt +++ b/feature/recordings/details/src/main/kotlin/com/f0x1d/logfox/feature/recordings/details/presentation/RecordingDetailsViewModel.kt @@ -1,4 +1,4 @@ -package com.f0x1d.logfox.feature.recordings.viewmodel +package com.f0x1d.logfox.feature.recordings.details.presentation import android.app.Application import android.net.Uri @@ -8,49 +8,53 @@ import com.f0x1d.logfox.arch.io.exportToZip import com.f0x1d.logfox.arch.io.putZipEntry import com.f0x1d.logfox.arch.viewmodel.BaseViewModel import com.f0x1d.logfox.datetime.DateTimeFormatter -import com.f0x1d.logfox.feature.recordings.core.repository.RecordingsRepository -import com.f0x1d.logfox.feature.recordings.di.RecordingId +import com.f0x1d.logfox.feature.recordings.api.data.RecordingsRepository +import com.f0x1d.logfox.feature.recordings.details.di.RecordingId import com.f0x1d.logfox.model.deviceData import com.f0x1d.logfox.preferences.shared.AppPreferences import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.flow.stateIn -import kotlinx.coroutines.flow.update +import kotlinx.coroutines.flow.take +import kotlinx.coroutines.launch import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import javax.inject.Inject @HiltViewModel -class RecordingViewModel @Inject constructor( +class RecordingDetailsViewModel @Inject constructor( @RecordingId val recordingId: Long, private val recordingsRepository: RecordingsRepository, private val appPreferences: AppPreferences, @IODispatcher private val ioDispatcher: CoroutineDispatcher, dateTimeFormatter: DateTimeFormatter, application: Application -): BaseViewModel(application), DateTimeFormatter by dateTimeFormatter { +): BaseViewModel( + initialStateProvider = { RecordingDetailsState() }, + application = application, +), DateTimeFormatter by dateTimeFormatter { + var currentTitle: String? = null - val recording = recordingsRepository.getByIdAsFlow(recordingId) - .distinctUntilChanged() - .onEach { recording -> - currentTitle.update { recording?.title } - } - .stateIn( - scope = viewModelScope, - started = SharingStarted.Eagerly, - initialValue = null, - ) + private val titleUpdateMutex = Mutex() - val currentTitle = MutableStateFlow(null) + init { + load() + } - private val titleUpdateMutex = Mutex() + private fun load() { + viewModelScope.launch { + recordingsRepository.getByIdAsFlow(recordingId) + .distinctUntilChanged() + .take(1) + .collect { recording -> + currentTitle = recording?.title + reduce { copy(recording = recording) } + } + } + } fun exportFile(uri: Uri) = launchCatching(ioDispatcher) { - val recording = recording.value ?: return@launchCatching + val recording = currentState.recording ?: return@launchCatching ctx.contentResolver.openOutputStream(uri)?.use { outputStream -> recording.file.inputStream().use { inputStream -> @@ -60,7 +64,7 @@ class RecordingViewModel @Inject constructor( } fun exportZipFile(uri: Uri) = launchCatching(ioDispatcher) { - val recording = recording.value ?: return@launchCatching + val recording = currentState.recording ?: return@launchCatching ctx.contentResolver.openOutputStream(uri)?.use { it.exportToZip { @@ -79,7 +83,7 @@ class RecordingViewModel @Inject constructor( fun updateTitle(title: String) = launchCatching { titleUpdateMutex.withLock { - recording.value?.let { + currentState.recording?.let { recordingsRepository.updateTitle(it, title) } } diff --git a/feature/recordings/src/main/kotlin/com/f0x1d/logfox/feature/recordings/ui/dialog/RecordingBottomSheet.kt b/feature/recordings/details/src/main/kotlin/com/f0x1d/logfox/feature/recordings/details/presentation/ui/RecordingDetailsBottomSheetFragment.kt similarity index 56% rename from feature/recordings/src/main/kotlin/com/f0x1d/logfox/feature/recordings/ui/dialog/RecordingBottomSheet.kt rename to feature/recordings/details/src/main/kotlin/com/f0x1d/logfox/feature/recordings/details/presentation/ui/RecordingDetailsBottomSheetFragment.kt index 6528933f..417dc4c7 100644 --- a/feature/recordings/src/main/kotlin/com/f0x1d/logfox/feature/recordings/ui/dialog/RecordingBottomSheet.kt +++ b/feature/recordings/details/src/main/kotlin/com/f0x1d/logfox/feature/recordings/details/presentation/ui/RecordingDetailsBottomSheetFragment.kt @@ -1,4 +1,4 @@ -package com.f0x1d.logfox.feature.recordings.ui.dialog +package com.f0x1d.logfox.feature.recordings.details.presentation.ui import android.os.Bundle import android.view.LayoutInflater @@ -10,20 +10,18 @@ import androidx.core.widget.doAfterTextChanged import androidx.fragment.app.viewModels import androidx.navigation.fragment.findNavController import com.f0x1d.logfox.arch.asUri +import com.f0x1d.logfox.arch.presentation.ui.dialog.BaseBottomSheetFragment import com.f0x1d.logfox.arch.shareFileIntent -import com.f0x1d.logfox.arch.ui.dialog.BaseViewModelBottomSheet -import com.f0x1d.logfox.feature.recordings.databinding.SheetRecordingBinding -import com.f0x1d.logfox.feature.recordings.viewmodel.RecordingViewModel +import com.f0x1d.logfox.feature.recordings.details.databinding.SheetRecordingDetailsBinding +import com.f0x1d.logfox.feature.recordings.details.presentation.RecordingDetailsViewModel import com.f0x1d.logfox.navigation.Directions import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.flow.filterNotNull -import kotlinx.coroutines.flow.take import java.util.Date @AndroidEntryPoint -class RecordingBottomSheet: BaseViewModelBottomSheet() { +class RecordingDetailsBottomSheetFragment: BaseBottomSheetFragment() { - override val viewModel by viewModels() + private val viewModel by viewModels() private val zipLogLauncher = registerForActivityResult( ActivityResultContracts.CreateDocument("application/zip") @@ -40,15 +38,11 @@ class RecordingBottomSheet: BaseViewModelBottomSheet - if (logRecording == null) return@collectWithLifecycle - - timeText.text = Date(logRecording.dateAndTime).toLocaleString() - - viewButton.setOnClickListener { + override fun SheetRecordingDetailsBinding.onViewCreated(view: View, savedInstanceState: Bundle?) { + viewButton.setOnClickListener { + viewModel.currentState.recording?.let { logRecording -> findNavController().navigate( resId = Directions.action_global_logsFragment_from_recordingBottomSheet, args = bundleOf( @@ -56,22 +50,31 @@ class RecordingBottomSheet: BaseViewModelBottomSheet logExportLauncher.launch("${viewModel.formatForExport(logRecording.dateAndTime)}.log") } - shareButton.setOnClickListener { + } + shareButton.setOnClickListener { + viewModel.currentState.recording?.let { logRecording -> requireContext().shareFileIntent(logRecording.file) } - zipButton.setOnClickListener { + } + zipButton.setOnClickListener { + viewModel.currentState.recording?.let { logRecording -> zipLogLauncher.launch("${viewModel.formatForExport(logRecording.dateAndTime)}.zip") } } - viewModel.currentTitle.filterNotNull().take(1).collectWithLifecycle { - title.apply { - setText(it) - doAfterTextChanged { viewModel.updateTitle(it?.toString() ?: "") } - } + title.doAfterTextChanged { viewModel.updateTitle(it?.toString().orEmpty()) } + + viewModel.state.collectWithLifecycle { state -> + title.setText(viewModel.currentTitle.orEmpty()) + + val logRecording = state.recording ?: return@collectWithLifecycle + + timeText.text = Date(logRecording.dateAndTime).toLocaleString() } } } diff --git a/feature/recordings/src/main/res/layout/sheet_recording.xml b/feature/recordings/details/src/main/res/layout/sheet_recording_details.xml similarity index 100% rename from feature/recordings/src/main/res/layout/sheet_recording.xml rename to feature/recordings/details/src/main/res/layout/sheet_recording_details.xml diff --git a/feature/recordings/impl/.gitignore b/feature/recordings/impl/.gitignore new file mode 100644 index 00000000..567609b1 --- /dev/null +++ b/feature/recordings/impl/.gitignore @@ -0,0 +1 @@ +build/ diff --git a/feature/recordings/impl/build.gradle.kts b/feature/recordings/impl/build.gradle.kts new file mode 100644 index 00000000..d322f123 --- /dev/null +++ b/feature/recordings/impl/build.gradle.kts @@ -0,0 +1,10 @@ +plugins { + id("logfox.android.feature") +} + +android.namespace = "com.f0x1d.logfox.feature.recordings.impl" + +dependencies { + implementation(projects.feature.recordings.api) + implementation(projects.feature.logging.api) +} diff --git a/feature/recordings-core/src/main/AndroidManifest.xml b/feature/recordings/impl/src/main/AndroidManifest.xml similarity index 67% rename from feature/recordings-core/src/main/AndroidManifest.xml rename to feature/recordings/impl/src/main/AndroidManifest.xml index 39a15abf..4f7220e0 100644 --- a/feature/recordings-core/src/main/AndroidManifest.xml +++ b/feature/recordings/impl/src/main/AndroidManifest.xml @@ -2,7 +2,7 @@ - + diff --git a/feature/recordings-core/src/main/kotlin/com/f0x1d/logfox/feature/recordings/core/controller/RecordingController.kt b/feature/recordings/impl/src/main/kotlin/com/f0x1d/logfox/feature/recordings/impl/data/RecordingControllerImpl.kt similarity index 85% rename from feature/recordings-core/src/main/kotlin/com/f0x1d/logfox/feature/recordings/core/controller/RecordingController.kt rename to feature/recordings/impl/src/main/kotlin/com/f0x1d/logfox/feature/recordings/impl/data/RecordingControllerImpl.kt index e1f57ba3..0bb28565 100644 --- a/feature/recordings-core/src/main/kotlin/com/f0x1d/logfox/feature/recordings/core/controller/RecordingController.kt +++ b/feature/recordings/impl/src/main/kotlin/com/f0x1d/logfox/feature/recordings/impl/data/RecordingControllerImpl.kt @@ -1,12 +1,14 @@ -package com.f0x1d.logfox.feature.recordings.core.controller +package com.f0x1d.logfox.feature.recordings.impl.data import android.content.Context import com.f0x1d.logfox.arch.di.IODispatcher import com.f0x1d.logfox.database.AppDatabase import com.f0x1d.logfox.database.entity.LogRecording import com.f0x1d.logfox.datetime.DateTimeFormatter -import com.f0x1d.logfox.feature.recordings.core.controller.reader.RecordingReader -import com.f0x1d.logfox.model.logline.LogLine +import com.f0x1d.logfox.feature.recordings.api.data.RecordingController +import com.f0x1d.logfox.feature.recordings.api.data.RecordingNotificationController +import com.f0x1d.logfox.feature.recordings.api.data.RecordingState +import com.f0x1d.logfox.feature.recordings.api.data.reader.RecordingReader import com.f0x1d.logfox.strings.Strings import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.CoroutineDispatcher @@ -18,22 +20,6 @@ import java.io.File import javax.inject.Inject import javax.inject.Singleton -interface RecordingController { - val recordingState: StateFlow - val reader: suspend (LogLine) -> Unit - - suspend fun record() - suspend fun pause() - suspend fun resume() - suspend fun end(): LogRecording? - - suspend fun loggingStopped() -} - -enum class RecordingState { - IDLE, RECORDING, PAUSED, SAVING -} - @Singleton internal class RecordingControllerImpl @Inject constructor( @ApplicationContext private val context: Context, @@ -106,3 +92,4 @@ internal class RecordingControllerImpl @Inject constructor( } } } + diff --git a/feature/recordings-core/src/main/kotlin/com/f0x1d/logfox/feature/recordings/core/controller/RecordingNotificationController.kt b/feature/recordings/impl/src/main/kotlin/com/f0x1d/logfox/feature/recordings/impl/data/RecordingNotificationControllerImpl.kt similarity index 89% rename from feature/recordings-core/src/main/kotlin/com/f0x1d/logfox/feature/recordings/core/controller/RecordingNotificationController.kt rename to feature/recordings/impl/src/main/kotlin/com/f0x1d/logfox/feature/recordings/impl/data/RecordingNotificationControllerImpl.kt index 349a2a2a..aaded57b 100644 --- a/feature/recordings-core/src/main/kotlin/com/f0x1d/logfox/feature/recordings/core/controller/RecordingNotificationController.kt +++ b/feature/recordings/impl/src/main/kotlin/com/f0x1d/logfox/feature/recordings/impl/data/RecordingNotificationControllerImpl.kt @@ -1,4 +1,4 @@ -package com.f0x1d.logfox.feature.recordings.core.controller +package com.f0x1d.logfox.feature.recordings.impl.data import android.annotation.SuppressLint import android.content.Context @@ -10,24 +10,13 @@ import com.f0x1d.logfox.arch.STOP_RECORDING_INTENT_ID import com.f0x1d.logfox.arch.doIfNotificationsAllowed import com.f0x1d.logfox.arch.makeBroadcastPendingIntent import com.f0x1d.logfox.arch.notificationManagerCompat -import com.f0x1d.logfox.feature.recordings.core.receiver.RecordingReceiver +import com.f0x1d.logfox.feature.recordings.api.data.RecordingNotificationController +import com.f0x1d.logfox.feature.recordings.impl.presentation.receiver.RecordingReceiver import com.f0x1d.logfox.strings.Strings import com.f0x1d.logfox.ui.Icons import dagger.hilt.android.qualifiers.ApplicationContext import javax.inject.Inject -interface RecordingNotificationController { - - companion object { - internal const val RECORDING_NOTIFICATIONS_TAG = "recording" - internal const val RECORDING_NOTIFICATIONS_ID = 0 - } - - fun sendRecordingNotification() - fun sendRecordingPausedNotification() - fun cancelRecordingNotification() -} - @SuppressLint("MissingPermission") internal class RecordingNotificationControllerImpl @Inject constructor( @ApplicationContext private val context: Context, diff --git a/feature/recordings-core/src/main/kotlin/com/f0x1d/logfox/feature/recordings/core/repository/RecordingsRepository.kt b/feature/recordings/impl/src/main/kotlin/com/f0x1d/logfox/feature/recordings/impl/data/RecordingsRepositoryImpl.kt similarity index 91% rename from feature/recordings-core/src/main/kotlin/com/f0x1d/logfox/feature/recordings/core/repository/RecordingsRepository.kt rename to feature/recordings/impl/src/main/kotlin/com/f0x1d/logfox/feature/recordings/impl/data/RecordingsRepositoryImpl.kt index 9f1a24b3..a5bce391 100644 --- a/feature/recordings-core/src/main/kotlin/com/f0x1d/logfox/feature/recordings/core/repository/RecordingsRepository.kt +++ b/feature/recordings/impl/src/main/kotlin/com/f0x1d/logfox/feature/recordings/impl/data/RecordingsRepositoryImpl.kt @@ -1,14 +1,14 @@ -package com.f0x1d.logfox.feature.recordings.core.repository +package com.f0x1d.logfox.feature.recordings.impl.data import android.content.Context import com.f0x1d.logfox.arch.di.IODispatcher import com.f0x1d.logfox.arch.di.MainDispatcher -import com.f0x1d.logfox.arch.repository.DatabaseProxyRepository import com.f0x1d.logfox.arch.toast import com.f0x1d.logfox.database.AppDatabase import com.f0x1d.logfox.database.entity.LogRecording import com.f0x1d.logfox.datetime.DateTimeFormatter -import com.f0x1d.logfox.feature.logging.core.repository.LoggingRepository +import com.f0x1d.logfox.feature.logging.api.data.LoggingRepository +import com.f0x1d.logfox.feature.recordings.api.data.RecordingsRepository import com.f0x1d.logfox.model.logline.LogLine import com.f0x1d.logfox.preferences.shared.AppPreferences import com.f0x1d.logfox.strings.Strings @@ -24,13 +24,6 @@ import java.io.FileOutputStream import java.io.IOException import javax.inject.Inject -interface RecordingsRepository : DatabaseProxyRepository { - suspend fun saveAll(): LogRecording - suspend fun createRecordingFrom(lines: List) - - suspend fun updateTitle(logRecording: LogRecording, newTitle: String) -} - internal class RecordingsRepositoryImpl @Inject constructor( @ApplicationContext private val context: Context, private val database: AppDatabase, diff --git a/feature/recordings-core/src/main/kotlin/com/f0x1d/logfox/feature/recordings/core/di/ControllersModule.kt b/feature/recordings/impl/src/main/kotlin/com/f0x1d/logfox/feature/recordings/impl/di/ControllersModule.kt similarity index 56% rename from feature/recordings-core/src/main/kotlin/com/f0x1d/logfox/feature/recordings/core/di/ControllersModule.kt rename to feature/recordings/impl/src/main/kotlin/com/f0x1d/logfox/feature/recordings/impl/di/ControllersModule.kt index 1ddd982d..0e16b60d 100644 --- a/feature/recordings-core/src/main/kotlin/com/f0x1d/logfox/feature/recordings/core/di/ControllersModule.kt +++ b/feature/recordings/impl/src/main/kotlin/com/f0x1d/logfox/feature/recordings/impl/di/ControllersModule.kt @@ -1,9 +1,9 @@ -package com.f0x1d.logfox.feature.recordings.core.di +package com.f0x1d.logfox.feature.recordings.impl.di -import com.f0x1d.logfox.feature.recordings.core.controller.RecordingController -import com.f0x1d.logfox.feature.recordings.core.controller.RecordingControllerImpl -import com.f0x1d.logfox.feature.recordings.core.controller.RecordingNotificationController -import com.f0x1d.logfox.feature.recordings.core.controller.RecordingNotificationControllerImpl +import com.f0x1d.logfox.feature.recordings.api.data.RecordingController +import com.f0x1d.logfox.feature.recordings.api.data.RecordingNotificationController +import com.f0x1d.logfox.feature.recordings.impl.data.RecordingControllerImpl +import com.f0x1d.logfox.feature.recordings.impl.data.RecordingNotificationControllerImpl import dagger.Binds import dagger.Module import dagger.hilt.InstallIn diff --git a/feature/recordings-core/src/main/kotlin/com/f0x1d/logfox/feature/recordings/core/di/RepositoriesModule.kt b/feature/recordings/impl/src/main/kotlin/com/f0x1d/logfox/feature/recordings/impl/di/RepositoriesModule.kt similarity index 61% rename from feature/recordings-core/src/main/kotlin/com/f0x1d/logfox/feature/recordings/core/di/RepositoriesModule.kt rename to feature/recordings/impl/src/main/kotlin/com/f0x1d/logfox/feature/recordings/impl/di/RepositoriesModule.kt index 21658f0e..2caeca14 100644 --- a/feature/recordings-core/src/main/kotlin/com/f0x1d/logfox/feature/recordings/core/di/RepositoriesModule.kt +++ b/feature/recordings/impl/src/main/kotlin/com/f0x1d/logfox/feature/recordings/impl/di/RepositoriesModule.kt @@ -1,7 +1,7 @@ -package com.f0x1d.logfox.feature.recordings.core.di +package com.f0x1d.logfox.feature.recordings.impl.di -import com.f0x1d.logfox.feature.recordings.core.repository.RecordingsRepository -import com.f0x1d.logfox.feature.recordings.core.repository.RecordingsRepositoryImpl +import com.f0x1d.logfox.feature.recordings.api.data.RecordingsRepository +import com.f0x1d.logfox.feature.recordings.impl.data.RecordingsRepositoryImpl import dagger.Binds import dagger.Module import dagger.hilt.InstallIn diff --git a/feature/recordings-core/src/main/kotlin/com/f0x1d/logfox/feature/recordings/core/receiver/RecordingReceiver.kt b/feature/recordings/impl/src/main/kotlin/com/f0x1d/logfox/feature/recordings/impl/presentation/receiver/RecordingReceiver.kt similarity index 89% rename from feature/recordings-core/src/main/kotlin/com/f0x1d/logfox/feature/recordings/core/receiver/RecordingReceiver.kt rename to feature/recordings/impl/src/main/kotlin/com/f0x1d/logfox/feature/recordings/impl/presentation/receiver/RecordingReceiver.kt index c585a0e9..1876e288 100644 --- a/feature/recordings-core/src/main/kotlin/com/f0x1d/logfox/feature/recordings/core/receiver/RecordingReceiver.kt +++ b/feature/recordings/impl/src/main/kotlin/com/f0x1d/logfox/feature/recordings/impl/presentation/receiver/RecordingReceiver.kt @@ -1,10 +1,10 @@ -package com.f0x1d.logfox.feature.recordings.core.receiver +package com.f0x1d.logfox.feature.recordings.impl.presentation.receiver import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import com.f0x1d.logfox.arch.di.MainDispatcher -import com.f0x1d.logfox.feature.recordings.core.controller.RecordingController +import com.f0x1d.logfox.feature.recordings.api.data.RecordingController import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope diff --git a/feature/recordings/list/.gitignore b/feature/recordings/list/.gitignore new file mode 100644 index 00000000..42afabfd --- /dev/null +++ b/feature/recordings/list/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/feature/recordings/list/build.gradle.kts b/feature/recordings/list/build.gradle.kts new file mode 100644 index 00000000..df914d1a --- /dev/null +++ b/feature/recordings/list/build.gradle.kts @@ -0,0 +1,10 @@ +plugins { + id("logfox.android.feature") +} + +android.namespace = "com.f0x1d.logfox.feature.recordings.list" + +dependencies { + implementation(projects.feature.recordings.api) + implementation(projects.feature.logging.api) +} diff --git a/feature/recordings/list/src/main/kotlin/com/f0x1d/logfox/feature/recordings/list/presentation/RecordingsAction.kt b/feature/recordings/list/src/main/kotlin/com/f0x1d/logfox/feature/recordings/list/presentation/RecordingsAction.kt new file mode 100644 index 00000000..30807173 --- /dev/null +++ b/feature/recordings/list/src/main/kotlin/com/f0x1d/logfox/feature/recordings/list/presentation/RecordingsAction.kt @@ -0,0 +1,8 @@ +package com.f0x1d.logfox.feature.recordings.list.presentation + +import com.f0x1d.logfox.database.entity.LogRecording + +sealed interface RecordingsAction { + data class ShowSnackbar(val text: String) : RecordingsAction + data class OpenRecording(val recording: LogRecording) : RecordingsAction +} diff --git a/feature/recordings/list/src/main/kotlin/com/f0x1d/logfox/feature/recordings/list/presentation/RecordingsState.kt b/feature/recordings/list/src/main/kotlin/com/f0x1d/logfox/feature/recordings/list/presentation/RecordingsState.kt new file mode 100644 index 00000000..b097019f --- /dev/null +++ b/feature/recordings/list/src/main/kotlin/com/f0x1d/logfox/feature/recordings/list/presentation/RecordingsState.kt @@ -0,0 +1,9 @@ +package com.f0x1d.logfox.feature.recordings.list.presentation + +import com.f0x1d.logfox.database.entity.LogRecording +import com.f0x1d.logfox.feature.recordings.api.data.RecordingState + +data class RecordingsState( + val recordings: List = emptyList(), + val recordingState: RecordingState = RecordingState.IDLE, +) diff --git a/feature/recordings/list/src/main/kotlin/com/f0x1d/logfox/feature/recordings/list/presentation/RecordingsViewModel.kt b/feature/recordings/list/src/main/kotlin/com/f0x1d/logfox/feature/recordings/list/presentation/RecordingsViewModel.kt new file mode 100644 index 00000000..6999803a --- /dev/null +++ b/feature/recordings/list/src/main/kotlin/com/f0x1d/logfox/feature/recordings/list/presentation/RecordingsViewModel.kt @@ -0,0 +1,78 @@ +package com.f0x1d.logfox.feature.recordings.list.presentation + +import android.app.Application +import androidx.lifecycle.viewModelScope +import com.f0x1d.logfox.arch.viewmodel.BaseViewModel +import com.f0x1d.logfox.database.entity.LogRecording +import com.f0x1d.logfox.feature.recordings.api.data.RecordingController +import com.f0x1d.logfox.feature.recordings.api.data.RecordingState +import com.f0x1d.logfox.feature.recordings.api.data.RecordingsRepository +import com.f0x1d.logfox.strings.Strings +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +class RecordingsViewModel @Inject constructor( + private val recordingsRepository: RecordingsRepository, + private val recordingController: RecordingController, + application: Application, +): BaseViewModel( + initialStateProvider = { RecordingsState() }, + application = application, +) { + private val recordingState = recordingController.recordingState + + init { + load() + } + + private fun load() { + viewModelScope.launch { + combine( + recordingsRepository.getAllAsFlow().distinctUntilChanged(), + recordingState, + ) { recordings, recordingState -> + RecordingsState( + recordings = recordings, + recordingState = recordingState, + ) + }.collect { + reduce { it } + } + } + } + + fun toggleStartStop() = launchCatching { + if (recordingState.value == RecordingState.IDLE) + recordingController.record() + else + recordingController.end()?.also { + sendAction(RecordingsAction.OpenRecording(it)) + } + } + + fun togglePauseResume() = launchCatching { + if (recordingState.value == RecordingState.PAUSED) + recordingController.resume() + else + recordingController.pause() + } + + fun clearRecordings() = launchCatching { + recordingsRepository.clear() + } + + fun saveAll() = launchCatching { + sendAction(RecordingsAction.ShowSnackbar(ctx.getString(Strings.saving_logs))) + recordingsRepository.saveAll().also { + sendAction(RecordingsAction.OpenRecording(it)) + } + } + + fun delete(logRecording: LogRecording) = launchCatching { + recordingsRepository.delete(logRecording) + } +} diff --git a/feature/recordings/list/src/main/kotlin/com/f0x1d/logfox/feature/recordings/list/presentation/adapter/RecordingsAdapter.kt b/feature/recordings/list/src/main/kotlin/com/f0x1d/logfox/feature/recordings/list/presentation/adapter/RecordingsAdapter.kt new file mode 100644 index 00000000..e6ce5c6f --- /dev/null +++ b/feature/recordings/list/src/main/kotlin/com/f0x1d/logfox/feature/recordings/list/presentation/adapter/RecordingsAdapter.kt @@ -0,0 +1,22 @@ +package com.f0x1d.logfox.feature.recordings.list.presentation.adapter + +import android.view.LayoutInflater +import android.view.ViewGroup +import com.f0x1d.logfox.arch.presentation.adapter.BaseListAdapter +import com.f0x1d.logfox.database.entity.LogRecording +import com.f0x1d.logfox.feature.recordings.list.databinding.ItemRecordingBinding +import com.f0x1d.logfox.feature.recordings.list.presentation.ui.viewholder.RecordingViewHolder +import com.f0x1d.logfox.model.diffCallback + +class RecordingsAdapter( + private val click: (LogRecording) -> Unit, + private val delete: (LogRecording) -> Unit +): BaseListAdapter(diffCallback()) { + + override fun createHolder(layoutInflater: LayoutInflater, parent: ViewGroup) = + RecordingViewHolder( + binding = ItemRecordingBinding.inflate(layoutInflater, parent, false), + click = click, + delete = delete, + ) +} diff --git a/feature/recordings/src/main/kotlin/com/f0x1d/logfox/feature/recordings/ui/fragment/RecordingsFragment.kt b/feature/recordings/list/src/main/kotlin/com/f0x1d/logfox/feature/recordings/list/presentation/ui/fragment/RecordingsFragment.kt similarity index 77% rename from feature/recordings/src/main/kotlin/com/f0x1d/logfox/feature/recordings/ui/fragment/RecordingsFragment.kt rename to feature/recordings/list/src/main/kotlin/com/f0x1d/logfox/feature/recordings/list/presentation/ui/fragment/RecordingsFragment.kt index c04fab79..31973933 100644 --- a/feature/recordings/src/main/kotlin/com/f0x1d/logfox/feature/recordings/ui/fragment/RecordingsFragment.kt +++ b/feature/recordings/list/src/main/kotlin/com/f0x1d/logfox/feature/recordings/list/presentation/ui/fragment/RecordingsFragment.kt @@ -1,4 +1,4 @@ -package com.f0x1d.logfox.feature.recordings.ui.fragment +package com.f0x1d.logfox.feature.recordings.list.presentation.ui.fragment import android.os.Bundle import android.view.LayoutInflater @@ -10,15 +10,14 @@ import androidx.fragment.app.viewModels import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.LinearLayoutManager import com.f0x1d.logfox.arch.isHorizontalOrientation -import com.f0x1d.logfox.arch.ui.fragment.BaseViewModelFragment -import com.f0x1d.logfox.arch.viewmodel.Event +import com.f0x1d.logfox.arch.presentation.ui.fragment.BaseFragment import com.f0x1d.logfox.database.entity.LogRecording -import com.f0x1d.logfox.feature.recordings.R -import com.f0x1d.logfox.feature.recordings.adapter.RecordingsAdapter -import com.f0x1d.logfox.feature.recordings.core.controller.RecordingState -import com.f0x1d.logfox.feature.recordings.databinding.FragmentRecordingsBinding -import com.f0x1d.logfox.feature.recordings.viewmodel.OpenRecording -import com.f0x1d.logfox.feature.recordings.viewmodel.RecordingsViewModel +import com.f0x1d.logfox.feature.recordings.api.data.RecordingState +import com.f0x1d.logfox.feature.recordings.list.R +import com.f0x1d.logfox.feature.recordings.list.databinding.FragmentRecordingsBinding +import com.f0x1d.logfox.feature.recordings.list.presentation.RecordingsAction +import com.f0x1d.logfox.feature.recordings.list.presentation.RecordingsViewModel +import com.f0x1d.logfox.feature.recordings.list.presentation.adapter.RecordingsAdapter import com.f0x1d.logfox.navigation.Directions import com.f0x1d.logfox.strings.Strings import com.f0x1d.logfox.ui.Icons @@ -32,9 +31,9 @@ import dagger.hilt.android.AndroidEntryPoint import dev.chrisbanes.insetter.applyInsetter @AndroidEntryPoint -class RecordingsFragment: BaseViewModelFragment() { +class RecordingsFragment: BaseFragment() { - override val viewModel by viewModels() + private val viewModel by viewModels() private val adapter = RecordingsAdapter( click = { @@ -101,19 +100,17 @@ class RecordingsFragment: BaseViewModelFragment + placeholderLayout.root.isVisible = state.recordings.isEmpty() - adapter.submitList(it) - } + adapter.submitList(state.recordings) - viewModel.recordingState.collectWithLifecycle { state -> recordFab.apply { - when (state) { + when (val recordingState = state.recordingState) { RecordingState.IDLE, RecordingState.SAVING -> { setImageResource(Icons.ic_recording) setDescription(Strings.record) - isEnabled = state == RecordingState.IDLE + isEnabled = recordingState == RecordingState.IDLE } RecordingState.RECORDING, RecordingState.PAUSED -> { @@ -127,7 +124,7 @@ class RecordingsFragment: BaseViewModelFragment { hide() } @@ -146,13 +143,12 @@ class RecordingsFragment: BaseViewModelFragment openDetails(event.recording) + viewModel.actions.collectWithLifecycle { action -> + when (action) { + is RecordingsAction.ShowSnackbar -> snackbar(action.text) + is RecordingsAction.OpenRecording -> openDetails(action.recording) + } } } diff --git a/feature/recordings/src/main/kotlin/com/f0x1d/logfox/feature/recordings/ui/viewholder/RecordingViewHolder.kt b/feature/recordings/list/src/main/kotlin/com/f0x1d/logfox/feature/recordings/list/presentation/ui/viewholder/RecordingViewHolder.kt similarity index 76% rename from feature/recordings/src/main/kotlin/com/f0x1d/logfox/feature/recordings/ui/viewholder/RecordingViewHolder.kt rename to feature/recordings/list/src/main/kotlin/com/f0x1d/logfox/feature/recordings/list/presentation/ui/viewholder/RecordingViewHolder.kt index 6e7df19a..f710457c 100644 --- a/feature/recordings/src/main/kotlin/com/f0x1d/logfox/feature/recordings/ui/viewholder/RecordingViewHolder.kt +++ b/feature/recordings/list/src/main/kotlin/com/f0x1d/logfox/feature/recordings/list/presentation/ui/viewholder/RecordingViewHolder.kt @@ -1,8 +1,8 @@ -package com.f0x1d.logfox.feature.recordings.ui.viewholder +package com.f0x1d.logfox.feature.recordings.list.presentation.ui.viewholder -import com.f0x1d.logfox.arch.ui.viewholder.BaseViewHolder +import com.f0x1d.logfox.arch.presentation.ui.viewholder.BaseViewHolder import com.f0x1d.logfox.database.entity.LogRecording -import com.f0x1d.logfox.feature.recordings.databinding.ItemRecordingBinding +import com.f0x1d.logfox.feature.recordings.list.databinding.ItemRecordingBinding import java.util.Date class RecordingViewHolder( diff --git a/feature/recordings/src/main/res/layout/fragment_recordings.xml b/feature/recordings/list/src/main/res/layout/fragment_recordings.xml similarity index 100% rename from feature/recordings/src/main/res/layout/fragment_recordings.xml rename to feature/recordings/list/src/main/res/layout/fragment_recordings.xml diff --git a/feature/recordings/src/main/res/layout/item_recording.xml b/feature/recordings/list/src/main/res/layout/item_recording.xml similarity index 100% rename from feature/recordings/src/main/res/layout/item_recording.xml rename to feature/recordings/list/src/main/res/layout/item_recording.xml diff --git a/feature/recordings/src/main/res/layout/placeholder_recordings.xml b/feature/recordings/list/src/main/res/layout/placeholder_recordings.xml similarity index 100% rename from feature/recordings/src/main/res/layout/placeholder_recordings.xml rename to feature/recordings/list/src/main/res/layout/placeholder_recordings.xml diff --git a/feature/recordings/src/main/res/menu/recordings_menu.xml b/feature/recordings/list/src/main/res/menu/recordings_menu.xml similarity index 100% rename from feature/recordings/src/main/res/menu/recordings_menu.xml rename to feature/recordings/list/src/main/res/menu/recordings_menu.xml diff --git a/feature/recordings/src/main/kotlin/com/f0x1d/logfox/feature/recordings/adapter/RecordingsAdapter.kt b/feature/recordings/src/main/kotlin/com/f0x1d/logfox/feature/recordings/adapter/RecordingsAdapter.kt deleted file mode 100644 index f58e1e64..00000000 --- a/feature/recordings/src/main/kotlin/com/f0x1d/logfox/feature/recordings/adapter/RecordingsAdapter.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.f0x1d.logfox.feature.recordings.adapter - -import android.view.LayoutInflater -import android.view.ViewGroup -import com.f0x1d.logfox.arch.adapter.BaseListAdapter -import com.f0x1d.logfox.database.entity.LogRecording -import com.f0x1d.logfox.feature.recordings.databinding.ItemRecordingBinding -import com.f0x1d.logfox.feature.recordings.ui.viewholder.RecordingViewHolder -import com.f0x1d.logfox.model.diffCallback - -class RecordingsAdapter( - private val click: (LogRecording) -> Unit, - private val delete: (LogRecording) -> Unit -): BaseListAdapter(diffCallback()) { - - override fun createHolder(layoutInflater: LayoutInflater, parent: ViewGroup) = RecordingViewHolder( - binding = ItemRecordingBinding.inflate(layoutInflater, parent, false), - click = click, - delete = delete, - ) -} diff --git a/feature/recordings/src/main/kotlin/com/f0x1d/logfox/feature/recordings/viewmodel/RecordingsViewModel.kt b/feature/recordings/src/main/kotlin/com/f0x1d/logfox/feature/recordings/viewmodel/RecordingsViewModel.kt deleted file mode 100644 index 1a40ded8..00000000 --- a/feature/recordings/src/main/kotlin/com/f0x1d/logfox/feature/recordings/viewmodel/RecordingsViewModel.kt +++ /dev/null @@ -1,61 +0,0 @@ -package com.f0x1d.logfox.feature.recordings.viewmodel - -import android.app.Application -import com.f0x1d.logfox.arch.viewmodel.BaseViewModel -import com.f0x1d.logfox.arch.viewmodel.Event -import com.f0x1d.logfox.database.entity.LogRecording -import com.f0x1d.logfox.feature.recordings.core.controller.RecordingController -import com.f0x1d.logfox.feature.recordings.core.controller.RecordingState -import com.f0x1d.logfox.feature.recordings.core.repository.RecordingsRepository -import com.f0x1d.logfox.strings.Strings -import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.flow.distinctUntilChanged -import javax.inject.Inject - -@HiltViewModel -class RecordingsViewModel @Inject constructor( - private val recordingsRepository: RecordingsRepository, - private val recordingController: RecordingController, - application: Application, -): BaseViewModel(application) { - - val recordings = recordingsRepository.getAllAsFlow() - .distinctUntilChanged() - - val recordingState = recordingController.recordingState - - fun toggleStartStop() = launchCatching { - if (recordingState.value == RecordingState.IDLE) - recordingController.record() - else - recordingController.end().also { - sendEvent(OpenRecording(it)) - } - } - - fun togglePauseResume() = launchCatching { - if (recordingState.value == RecordingState.PAUSED) - recordingController.resume() - else - recordingController.pause() - } - - fun clearRecordings() = launchCatching { - recordingsRepository.clear() - } - - fun saveAll() = launchCatching { - snackbar(Strings.saving_logs) - recordingsRepository.saveAll().also { - sendEvent(OpenRecording(it)) - } - } - - fun delete(logRecording: LogRecording) = launchCatching { - recordingsRepository.delete(logRecording) - } -} - -data class OpenRecording( - val recording: LogRecording?, -) : Event diff --git a/feature/settings/build.gradle.kts b/feature/settings/build.gradle.kts index f82706de..8673afbf 100644 --- a/feature/settings/build.gradle.kts +++ b/feature/settings/build.gradle.kts @@ -5,5 +5,5 @@ plugins { android.namespace = "com.f0x1d.logfox.feature.settings" dependencies { - + implementation(projects.feature.logging.api) } diff --git a/feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/LoggingServiceDelegate.kt b/feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/LoggingServiceDelegate.kt deleted file mode 100644 index 98dc57b8..00000000 --- a/feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/LoggingServiceDelegate.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.f0x1d.logfox.feature.settings - -interface LoggingServiceDelegate { - fun restartLogging() -} diff --git a/feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/IntArrayExt.kt b/feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/presentation/IntArrayExt.kt similarity index 68% rename from feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/IntArrayExt.kt rename to feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/presentation/IntArrayExt.kt index 7cf54287..2b4fc9cb 100644 --- a/feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/IntArrayExt.kt +++ b/feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/presentation/IntArrayExt.kt @@ -1,4 +1,4 @@ -package com.f0x1d.logfox.feature.settings +package com.f0x1d.logfox.feature.settings.presentation import android.content.Context diff --git a/feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/ui/fragment/SettingsCrashesFragment.kt b/feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/presentation/ui/fragment/SettingsCrashesFragment.kt similarity index 74% rename from feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/ui/fragment/SettingsCrashesFragment.kt rename to feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/presentation/ui/fragment/SettingsCrashesFragment.kt index 5973dac2..1db81364 100644 --- a/feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/ui/fragment/SettingsCrashesFragment.kt +++ b/feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/presentation/ui/fragment/SettingsCrashesFragment.kt @@ -1,8 +1,8 @@ -package com.f0x1d.logfox.feature.settings.ui.fragment +package com.f0x1d.logfox.feature.settings.presentation.ui.fragment import android.os.Bundle import com.f0x1d.logfox.feature.settings.R -import com.f0x1d.logfox.feature.settings.ui.fragment.base.BasePreferenceFragment +import com.f0x1d.logfox.feature.settings.presentation.ui.fragment.base.BasePreferenceFragment import com.f0x1d.logfox.strings.Strings import dagger.hilt.android.AndroidEntryPoint diff --git a/feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/ui/fragment/SettingsLinksFragment.kt b/feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/presentation/ui/fragment/SettingsLinksFragment.kt similarity index 74% rename from feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/ui/fragment/SettingsLinksFragment.kt rename to feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/presentation/ui/fragment/SettingsLinksFragment.kt index 527e569b..1a2a9c2f 100644 --- a/feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/ui/fragment/SettingsLinksFragment.kt +++ b/feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/presentation/ui/fragment/SettingsLinksFragment.kt @@ -1,8 +1,8 @@ -package com.f0x1d.logfox.feature.settings.ui.fragment +package com.f0x1d.logfox.feature.settings.presentation.ui.fragment import android.os.Bundle import com.f0x1d.logfox.feature.settings.R -import com.f0x1d.logfox.feature.settings.ui.fragment.base.BasePreferenceFragment +import com.f0x1d.logfox.feature.settings.presentation.ui.fragment.base.BasePreferenceFragment import com.f0x1d.logfox.strings.Strings import dagger.hilt.android.AndroidEntryPoint diff --git a/feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/ui/fragment/SettingsMenuFragment.kt b/feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/presentation/ui/fragment/SettingsMenuFragment.kt similarity index 77% rename from feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/ui/fragment/SettingsMenuFragment.kt rename to feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/presentation/ui/fragment/SettingsMenuFragment.kt index 5aa43389..cd275bb1 100644 --- a/feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/ui/fragment/SettingsMenuFragment.kt +++ b/feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/presentation/ui/fragment/SettingsMenuFragment.kt @@ -1,10 +1,13 @@ -package com.f0x1d.logfox.feature.settings.ui.fragment +package com.f0x1d.logfox.feature.settings.presentation.ui.fragment import android.os.Bundle import androidx.navigation.fragment.findNavController import androidx.preference.Preference +import com.f0x1d.logfox.arch.logs.timberLogFile +import com.f0x1d.logfox.arch.shareFileIntent +import com.f0x1d.logfox.feature.settings.BuildConfig import com.f0x1d.logfox.feature.settings.R -import com.f0x1d.logfox.feature.settings.ui.fragment.base.BasePreferenceFragment +import com.f0x1d.logfox.feature.settings.presentation.ui.fragment.base.BasePreferenceFragment import com.f0x1d.logfox.navigation.Directions import dagger.hilt.android.AndroidEntryPoint @@ -30,15 +33,23 @@ class SettingsMenuFragment: BasePreferenceFragment() { return@setOnPreferenceClickListener true } + findPreference("pref_settings_links")?.setOnPreferenceClickListener { + findNavController().navigate(Directions.action_settingsMenuFragment_to_settingsLinksFragment) + return@setOnPreferenceClickListener true + } findPreference("pref_settings_app_version")?.apply { val packageManager = requireContext().packageManager val packageInfo = packageManager.getPackageInfo(requireContext().packageName, 0) title = "${packageInfo.versionName} (${packageInfo.versionCode})" } - findPreference("pref_settings_links")?.setOnPreferenceClickListener { - findNavController().navigate(Directions.action_settingsMenuFragment_to_settingsLinksFragment) - return@setOnPreferenceClickListener true + findPreference("pref_settings_share_logs")?.apply { + isVisible = BuildConfig.DEBUG + + setOnPreferenceClickListener { + requireContext().shareFileIntent(requireContext().timberLogFile) + return@setOnPreferenceClickListener true + } } } } diff --git a/feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/ui/fragment/SettingsNotificationsFragment.kt b/feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/presentation/ui/fragment/SettingsNotificationsFragment.kt similarity index 93% rename from feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/ui/fragment/SettingsNotificationsFragment.kt rename to feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/presentation/ui/fragment/SettingsNotificationsFragment.kt index b5f0858b..76b4f651 100644 --- a/feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/ui/fragment/SettingsNotificationsFragment.kt +++ b/feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/presentation/ui/fragment/SettingsNotificationsFragment.kt @@ -1,4 +1,4 @@ -package com.f0x1d.logfox.feature.settings.ui.fragment +package com.f0x1d.logfox.feature.settings.presentation.ui.fragment import android.annotation.SuppressLint import android.content.Intent @@ -9,7 +9,7 @@ import com.f0x1d.logfox.arch.LOGGING_STATUS_CHANNEL_ID import com.f0x1d.logfox.arch.hasNotificationsPermission import com.f0x1d.logfox.arch.notificationsChannelsAvailable import com.f0x1d.logfox.feature.settings.R -import com.f0x1d.logfox.feature.settings.ui.fragment.base.BasePreferenceFragment +import com.f0x1d.logfox.feature.settings.presentation.ui.fragment.base.BasePreferenceFragment import com.f0x1d.logfox.strings.Strings import dagger.hilt.android.AndroidEntryPoint diff --git a/feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/ui/fragment/SettingsServiceFragment.kt b/feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/presentation/ui/fragment/SettingsServiceFragment.kt similarity index 90% rename from feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/ui/fragment/SettingsServiceFragment.kt rename to feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/presentation/ui/fragment/SettingsServiceFragment.kt index f1c76cd6..5ac5e318 100644 --- a/feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/ui/fragment/SettingsServiceFragment.kt +++ b/feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/presentation/ui/fragment/SettingsServiceFragment.kt @@ -1,4 +1,4 @@ -package com.f0x1d.logfox.feature.settings.ui.fragment +package com.f0x1d.logfox.feature.settings.presentation.ui.fragment import android.os.Bundle import androidx.lifecycle.lifecycleScope @@ -6,10 +6,10 @@ import androidx.preference.Preference import androidx.preference.SwitchPreferenceCompat import com.f0x1d.logfox.arch.isAtLeastAndroid13 import com.f0x1d.logfox.arch.toast -import com.f0x1d.logfox.feature.settings.LoggingServiceDelegate +import com.f0x1d.logfox.feature.logging.api.presentation.LoggingServiceDelegate import com.f0x1d.logfox.feature.settings.R -import com.f0x1d.logfox.feature.settings.fillWithStrings -import com.f0x1d.logfox.feature.settings.ui.fragment.base.BasePreferenceFragment +import com.f0x1d.logfox.feature.settings.presentation.fillWithStrings +import com.f0x1d.logfox.feature.settings.presentation.ui.fragment.base.BasePreferenceFragment import com.f0x1d.logfox.preferences.shared.AppPreferences import com.f0x1d.logfox.strings.Strings import com.f0x1d.logfox.terminals.base.Terminal @@ -33,7 +33,7 @@ class SettingsServiceFragment: BasePreferenceFragment() { lateinit var terminals: Array @Inject - lateinit var loggingService: LoggingServiceDelegate + lateinit var loggingServiceDelegate: LoggingServiceDelegate override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { addPreferencesFromResource(R.xml.settings_service) @@ -94,7 +94,7 @@ class SettingsServiceFragment: BasePreferenceFragment() { } private fun restartLogging() { - loggingService.restartLogging() + loggingServiceDelegate.restartLogging() } private fun askAboutNewTerminalRestart() { diff --git a/feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/ui/fragment/SettingsUIFragment.kt b/feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/presentation/ui/fragment/SettingsUIFragment.kt similarity index 97% rename from feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/ui/fragment/SettingsUIFragment.kt rename to feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/presentation/ui/fragment/SettingsUIFragment.kt index 045ec88a..d232ef1f 100644 --- a/feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/ui/fragment/SettingsUIFragment.kt +++ b/feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/presentation/ui/fragment/SettingsUIFragment.kt @@ -1,4 +1,4 @@ -package com.f0x1d.logfox.feature.settings.ui.fragment +package com.f0x1d.logfox.feature.settings.presentation.ui.fragment import android.os.Bundle import android.text.InputType @@ -7,8 +7,8 @@ import androidx.preference.Preference import com.f0x1d.logfox.arch.catchingNotNumber import com.f0x1d.logfox.arch.monetAvailable import com.f0x1d.logfox.feature.settings.R -import com.f0x1d.logfox.feature.settings.fillWithStrings -import com.f0x1d.logfox.feature.settings.ui.fragment.base.BasePreferenceFragment +import com.f0x1d.logfox.feature.settings.presentation.fillWithStrings +import com.f0x1d.logfox.feature.settings.presentation.ui.fragment.base.BasePreferenceFragment import com.f0x1d.logfox.preferences.shared.AppPreferences import com.f0x1d.logfox.strings.Strings import com.f0x1d.logfox.ui.Icons diff --git a/feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/ui/fragment/base/BasePreferenceFragment.kt b/feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/presentation/ui/fragment/base/BasePreferenceFragment.kt similarity index 88% rename from feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/ui/fragment/base/BasePreferenceFragment.kt rename to feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/presentation/ui/fragment/base/BasePreferenceFragment.kt index c6446c30..993dd47d 100644 --- a/feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/ui/fragment/base/BasePreferenceFragment.kt +++ b/feature/settings/src/main/kotlin/com/f0x1d/logfox/feature/settings/presentation/ui/fragment/base/BasePreferenceFragment.kt @@ -1,10 +1,10 @@ -package com.f0x1d.logfox.feature.settings.ui.fragment.base +package com.f0x1d.logfox.feature.settings.presentation.ui.fragment.base import android.os.Bundle import android.view.View import androidx.preference.PreferenceFragmentCompat import com.f0x1d.logfox.arch.isHorizontalOrientation -import com.f0x1d.logfox.arch.ui.base.SimpleFragmentLifecycleOwner +import com.f0x1d.logfox.arch.presentation.ui.base.SimpleFragmentLifecycleOwner import com.f0x1d.logfox.feature.settings.R import com.f0x1d.logfox.strings.Strings import com.f0x1d.logfox.ui.view.setupBackButtonForNavController diff --git a/feature/settings/src/main/res/xml/settings_menu.xml b/feature/settings/src/main/res/xml/settings_menu.xml index 59d02d49..6be97bf8 100644 --- a/feature/settings/src/main/res/xml/settings_menu.xml +++ b/feature/settings/src/main/res/xml/settings_menu.xml @@ -34,6 +34,9 @@ android:key="pref_settings_app_version" android:icon="@drawable/ic_settings_info" android:selectable="false" /> + diff --git a/feature/setup/src/main/kotlin/com/f0x1d/logfox/feature/setup/presentation/SetupAction.kt b/feature/setup/src/main/kotlin/com/f0x1d/logfox/feature/setup/presentation/SetupAction.kt new file mode 100644 index 00000000..f9a44129 --- /dev/null +++ b/feature/setup/src/main/kotlin/com/f0x1d/logfox/feature/setup/presentation/SetupAction.kt @@ -0,0 +1,7 @@ +package com.f0x1d.logfox.feature.setup.presentation + +import androidx.annotation.StringRes + +sealed interface SetupAction { + data class ShowSnackbar(@StringRes val textResId: Int) : SetupAction +} diff --git a/feature/setup/src/main/kotlin/com/f0x1d/logfox/feature/setup/presentation/SetupState.kt b/feature/setup/src/main/kotlin/com/f0x1d/logfox/feature/setup/presentation/SetupState.kt new file mode 100644 index 00000000..b681c489 --- /dev/null +++ b/feature/setup/src/main/kotlin/com/f0x1d/logfox/feature/setup/presentation/SetupState.kt @@ -0,0 +1,6 @@ +package com.f0x1d.logfox.feature.setup.presentation + +data class SetupState( + val showAdbDialog: Boolean = false, + val adbCommand: String = "", +) diff --git a/feature/setup/src/main/kotlin/com/f0x1d/logfox/feature/setup/viewmodel/SetupViewModel.kt b/feature/setup/src/main/kotlin/com/f0x1d/logfox/feature/setup/presentation/SetupViewModel.kt similarity index 79% rename from feature/setup/src/main/kotlin/com/f0x1d/logfox/feature/setup/viewmodel/SetupViewModel.kt rename to feature/setup/src/main/kotlin/com/f0x1d/logfox/feature/setup/presentation/SetupViewModel.kt index bd4d9ace..23d5d382 100644 --- a/feature/setup/src/main/kotlin/com/f0x1d/logfox/feature/setup/viewmodel/SetupViewModel.kt +++ b/feature/setup/src/main/kotlin/com/f0x1d/logfox/feature/setup/presentation/SetupViewModel.kt @@ -1,12 +1,11 @@ -package com.f0x1d.logfox.feature.setup.viewmodel +package com.f0x1d.logfox.feature.setup.presentation import android.Manifest import android.app.Application import com.f0x1d.logfox.arch.copyText import com.f0x1d.logfox.arch.hardRestartApp import com.f0x1d.logfox.arch.hasPermissionToReadLogs -import com.f0x1d.logfox.arch.viewmodel.BaseStateViewModel -import com.f0x1d.logfox.feature.setup.ui.fragment.setup.compose.SetupScreenState +import com.f0x1d.logfox.arch.viewmodel.BaseViewModel import com.f0x1d.logfox.preferences.shared.AppPreferences import com.f0x1d.logfox.strings.Strings import com.f0x1d.logfox.terminals.DefaultTerminal @@ -21,11 +20,10 @@ class SetupViewModel @Inject constructor( private val rootTerminal: RootTerminal, private val shizukuTerminal: ShizukuTerminal, application: Application, -): BaseStateViewModel( - initialStateProvider = { SetupScreenState() }, +): BaseViewModel( + initialStateProvider = { SetupState() }, application = application, ) { - private val adbCommand get() = "adb shell ${command.joinToString(" ")}" private val command get() = arrayOf("pm", "grant", ctx.packageName, Manifest.permission.READ_LOGS) @@ -36,14 +34,14 @@ class SetupViewModel @Inject constructor( rootTerminal.executeNow(*command) checkPermission() } else - snackbar(Strings.no_root) + sendAction(SetupAction.ShowSnackbar(Strings.no_root)) } fun adb() = launchCatching { if (ctx.hasPermissionToReadLogs) gotPermission() else { - state { + reduce { copy( showAdbDialog = true, adbCommand = this@SetupViewModel.adbCommand, @@ -60,20 +58,20 @@ class SetupViewModel @Inject constructor( if (shizukuTerminal.isSupported() && shizukuTerminal.executeNow(*command).isSuccessful) gotPermission() else - snackbar(Strings.shizuku_error) + sendAction(SetupAction.ShowSnackbar(Strings.shizuku_error)) } fun checkPermission() = if (ctx.hasPermissionToReadLogs) gotPermission() else - snackbar(Strings.no_permission_detected) + sendAction(SetupAction.ShowSnackbar(Strings.no_permission_detected)) fun copyCommand() { ctx.copyText(adbCommand) - snackbar(Strings.text_copied) + sendAction(SetupAction.ShowSnackbar(Strings.text_copied)) } - fun closeAdbDialog() = state { + fun closeAdbDialog() = reduce { copy(showAdbDialog = false) } diff --git a/feature/setup/src/main/kotlin/com/f0x1d/logfox/feature/setup/presentation/ui/SetupFragment.kt b/feature/setup/src/main/kotlin/com/f0x1d/logfox/feature/setup/presentation/ui/SetupFragment.kt new file mode 100644 index 00000000..0f64b24a --- /dev/null +++ b/feature/setup/src/main/kotlin/com/f0x1d/logfox/feature/setup/presentation/ui/SetupFragment.kt @@ -0,0 +1,58 @@ +package com.f0x1d.logfox.feature.setup.presentation.ui + +import android.os.Bundle +import android.view.View +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.fragment.app.viewModels +import com.f0x1d.logfox.arch.presentation.ui.fragment.compose.BaseComposeFragment +import com.f0x1d.logfox.feature.setup.presentation.SetupAction +import com.f0x1d.logfox.feature.setup.presentation.SetupViewModel +import com.f0x1d.logfox.feature.setup.presentation.ui.compose.SetupScreenContent +import com.f0x1d.logfox.ui.compose.theme.LogFoxTheme +import dagger.hilt.android.AndroidEntryPoint +import dev.chrisbanes.insetter.applyInsetter + +@AndroidEntryPoint +class SetupFragment : BaseComposeFragment() { + + private val viewModel by viewModels() + + private val listener: SetupScreenListener by lazy { + SetupScreenListener( + onRootClick = viewModel::root, + onAdbClick = viewModel::adb, + onShizukuClick = viewModel::shizuku, + closeAdbDialog = viewModel::closeAdbDialog, + checkPermission = viewModel::checkPermission, + copyCommand = viewModel::copyCommand, + ) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + viewModel.actions.collectWithLifecycle { action -> + when (action) { + is SetupAction.ShowSnackbar -> snackbar(action.textResId).apply { + this.view.applyInsetter { + type(navigationBars = true) { margin() } + } + } + } + } + } + + @Composable + override fun Content() { + LogFoxTheme { + val state by viewModel.state.collectAsState() + + SetupScreenContent( + state = state, + listener = listener, + ) + } + } +} diff --git a/feature/setup/src/main/kotlin/com/f0x1d/logfox/feature/setup/ui/fragment/setup/compose/SetupScreenState.kt b/feature/setup/src/main/kotlin/com/f0x1d/logfox/feature/setup/presentation/ui/SetupScreenListener.kt similarity index 74% rename from feature/setup/src/main/kotlin/com/f0x1d/logfox/feature/setup/ui/fragment/setup/compose/SetupScreenState.kt rename to feature/setup/src/main/kotlin/com/f0x1d/logfox/feature/setup/presentation/ui/SetupScreenListener.kt index 25ecf71e..61b313cf 100644 --- a/feature/setup/src/main/kotlin/com/f0x1d/logfox/feature/setup/ui/fragment/setup/compose/SetupScreenState.kt +++ b/feature/setup/src/main/kotlin/com/f0x1d/logfox/feature/setup/presentation/ui/SetupScreenListener.kt @@ -1,12 +1,7 @@ -package com.f0x1d.logfox.feature.setup.ui.fragment.setup.compose +package com.f0x1d.logfox.feature.setup.presentation.ui import androidx.compose.runtime.Immutable -data class SetupScreenState( - val showAdbDialog: Boolean = false, - val adbCommand: String = "", -) - @Immutable data class SetupScreenListener( val onRootClick: () -> Unit, diff --git a/feature/setup/src/main/kotlin/com/f0x1d/logfox/feature/setup/ui/fragment/setup/compose/SetupScreenContent.kt b/feature/setup/src/main/kotlin/com/f0x1d/logfox/feature/setup/presentation/ui/compose/SetupScreenContent.kt similarity index 93% rename from feature/setup/src/main/kotlin/com/f0x1d/logfox/feature/setup/ui/fragment/setup/compose/SetupScreenContent.kt rename to feature/setup/src/main/kotlin/com/f0x1d/logfox/feature/setup/presentation/ui/compose/SetupScreenContent.kt index ac731ac0..34107fbc 100644 --- a/feature/setup/src/main/kotlin/com/f0x1d/logfox/feature/setup/ui/fragment/setup/compose/SetupScreenContent.kt +++ b/feature/setup/src/main/kotlin/com/f0x1d/logfox/feature/setup/presentation/ui/compose/SetupScreenContent.kt @@ -1,4 +1,4 @@ -package com.f0x1d.logfox.feature.setup.ui.fragment.setup.compose +package com.f0x1d.logfox.feature.setup.presentation.ui.compose import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -21,6 +21,9 @@ import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp +import com.f0x1d.logfox.feature.setup.presentation.SetupState +import com.f0x1d.logfox.feature.setup.presentation.ui.MockSetupScreenListener +import com.f0x1d.logfox.feature.setup.presentation.ui.SetupScreenListener import com.f0x1d.logfox.strings.Strings import com.f0x1d.logfox.ui.Icons import com.f0x1d.logfox.ui.compose.component.button.RichButton @@ -30,7 +33,7 @@ import com.f0x1d.logfox.ui.compose.theme.LogFoxTheme @OptIn(ExperimentalMaterial3Api::class) @Composable internal fun SetupScreenContent( - state: SetupScreenState = SetupScreenState(), + state: SetupState = SetupState(), listener: SetupScreenListener = MockSetupScreenListener, ) { Scaffold( @@ -158,7 +161,7 @@ private fun SetupScreenContentPreview() { private fun SetupScreenContentWithDialogPreview() { LogFoxTheme { SetupScreenContent( - state = SetupScreenState( + state = SetupState( showAdbDialog = true, adbCommand = "HESOYAM", ) diff --git a/feature/setup/src/main/kotlin/com/f0x1d/logfox/feature/setup/ui/fragment/setup/SetupFragment.kt b/feature/setup/src/main/kotlin/com/f0x1d/logfox/feature/setup/ui/fragment/setup/SetupFragment.kt deleted file mode 100644 index 342bc1e8..00000000 --- a/feature/setup/src/main/kotlin/com/f0x1d/logfox/feature/setup/ui/fragment/setup/SetupFragment.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.f0x1d.logfox.feature.setup.ui.fragment.setup - -import androidx.compose.runtime.Composable -import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.getValue -import androidx.fragment.app.viewModels -import com.f0x1d.logfox.arch.ui.fragment.compose.BaseComposeViewModelFragment -import com.f0x1d.logfox.feature.setup.ui.fragment.setup.compose.SetupScreenContent -import com.f0x1d.logfox.feature.setup.ui.fragment.setup.compose.SetupScreenListener -import com.f0x1d.logfox.feature.setup.viewmodel.SetupViewModel -import com.f0x1d.logfox.ui.compose.theme.LogFoxTheme -import dagger.hilt.android.AndroidEntryPoint - -@AndroidEntryPoint -class SetupFragment: BaseComposeViewModelFragment() { - - override val viewModel by viewModels() - - private val listener by lazy { - SetupScreenListener( - onRootClick = viewModel::root, - onAdbClick = viewModel::adb, - onShizukuClick = viewModel::shizuku, - closeAdbDialog = viewModel::closeAdbDialog, - checkPermission = viewModel::checkPermission, - copyCommand = viewModel::copyCommand, - ) - } - - @Composable - override fun Content() { - LogFoxTheme { - val state by viewModel.uiState.collectAsState() - - SetupScreenContent( - state = state, - listener = listener, - ) - } - } -} diff --git a/feature/setup/src/test/kotlin/com/f0x1d/logfox/setup/compose/SetupScreenContentTest.kt b/feature/setup/src/test/kotlin/com/f0x1d/logfox/feature/setup/presentation/ui/compose/SetupScreenContentTest.kt similarity index 90% rename from feature/setup/src/test/kotlin/com/f0x1d/logfox/setup/compose/SetupScreenContentTest.kt rename to feature/setup/src/test/kotlin/com/f0x1d/logfox/feature/setup/presentation/ui/compose/SetupScreenContentTest.kt index fbbaceaf..b4172894 100644 --- a/feature/setup/src/test/kotlin/com/f0x1d/logfox/setup/compose/SetupScreenContentTest.kt +++ b/feature/setup/src/test/kotlin/com/f0x1d/logfox/feature/setup/presentation/ui/compose/SetupScreenContentTest.kt @@ -1,4 +1,4 @@ -package com.f0x1d.logfox.setup.compose +package com.f0x1d.logfox.feature.setup.presentation.ui.compose import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -6,11 +6,8 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import com.f0x1d.logfox.core.tests.ScreenshotTest import com.f0x1d.logfox.core.tests.compose.clickOn -import com.f0x1d.logfox.feature.setup.ui.fragment.setup.compose.MockSetupScreenListener -import com.f0x1d.logfox.feature.setup.ui.fragment.setup.compose.SetupAdbButtonTestTag -import com.f0x1d.logfox.feature.setup.ui.fragment.setup.compose.SetupAdbDialogTestTag -import com.f0x1d.logfox.feature.setup.ui.fragment.setup.compose.SetupScreenContent -import com.f0x1d.logfox.feature.setup.ui.fragment.setup.compose.SetupScreenState +import com.f0x1d.logfox.feature.setup.presentation.SetupState +import com.f0x1d.logfox.feature.setup.presentation.ui.MockSetupScreenListener import com.f0x1d.logfox.ui.compose.theme.LogFoxTheme import org.junit.Test @@ -36,7 +33,7 @@ class SetupScreenContentTest : ScreenshotTest() { ) { LogFoxTheme { SetupScreenContent( - state = SetupScreenState( + state = SetupState( showAdbDialog = true, adbCommand = OG_BUDA_ISKS, ), @@ -50,7 +47,7 @@ class SetupScreenContentTest : ScreenshotTest() { whatToCapture = { SetupAdbDialogTestTag.node() }, ) { var state by remember { - mutableStateOf(SetupScreenState()) + mutableStateOf(SetupState()) } LogFoxTheme { diff --git a/feature/setup/src/test/screenshots/com.f0x1d.logfox.feature.setup.presentation.ui.compose.SetupScreenContentTest.shouldOpenAdbDialogOnSetupScreenContent.png b/feature/setup/src/test/screenshots/com.f0x1d.logfox.feature.setup.presentation.ui.compose.SetupScreenContentTest.shouldOpenAdbDialogOnSetupScreenContent.png new file mode 100644 index 0000000000000000000000000000000000000000..9f0923be02189ec4f4eb21fb398ecc80249883d0 GIT binary patch literal 48367 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 literal 0 HcmV?d00001 diff --git a/feature/setup/src/test/screenshots/com.f0x1d.logfox.feature.setup.presentation.ui.compose.SetupScreenContentTest.shouldShowAdbDialogOnSetupScreenContent.png b/feature/setup/src/test/screenshots/com.f0x1d.logfox.feature.setup.presentation.ui.compose.SetupScreenContentTest.shouldShowAdbDialogOnSetupScreenContent.png new file mode 100644 index 0000000000000000000000000000000000000000..ab173ceefcc7fc093fb61514b61a4b87c4db5f65 GIT binary patch literal 206094 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

X}KOfwdNDMfiUg2KLtkdZ@{s6 zW0@HmmEP}hHRs=va3i#$~3^TwhtjvHr<-iAE8uCnO*YRiQm#*5BKI#^0p|Vxr#(p3NM%{;kSINy$9Fh{n=2ZGPqX**!5N}WAb6n6ZEcJSqu(j` z{7U7=>^!Peu`g)zsy8aX;g1UkzYWChZrZj$;rkH|8F%(=M9G!)4m2H+olY|fj=TB| zvn`zhV(0rGjHTDM0UL92m9|ARXmYu??;`Xru!gTmmTKmC=``Z>`ujkbx2o?yV7`Yb zNnB3P_b66CkMR|~{w8#PfI29(e3Mr@T{;mH?FNejd6(Yy4~*K&9QQzG-MNvOrvpHh zTUJ!a`3zSMa&&ssXG;@C`#$qxOBZ_&>LQ5%ks=gI3rwrsC>#9+#m2Q97NG?$^i}Z2 z!-g+~nPJ%**xj;KbHL6*+j2)j0p>V*D`>NCJLLRd*jW65W$o`y@l9_P`>%TFPSF;6 z%Lw~$wZCstC?Cs##VJ-z>~0+v*ypxAr<&axd@BpqW^kvql$Gq7$c682#HRiZikFU#6)0{342Y z03GLUi~`95)2sW^<307qj|aHaxp@}*O7#A}iP6EptO=l_M30k$>i@E~m8b(XV(FD22Q9A=FS@Fq3nCbSls3`vgL|J}>u0qqS_S+t$%$VdP7tw5enK6y^g zrqE3;p5rI0YnNgNVb5bii!DF052>uwcIX4{=n?Ot1we6n&W17dPE zqrvlEd=3OSMJQd47cDW>K%+F5ugNTk(n8G-M`kp%!zkOaCg7=nfF3Rp_tfimEz@F1 z+c{;|lkIK?Kv&vw3@nnu9QxgK);A6ZZ+Y25X2re}%?Wam0Pn5(Gmxx}&;=JzT+_BO-`)tuCIsa^956Im|Up_ouA2OC_|F zT-K%eNO!|Lsts`k8yLu9NuC5?y#~IBR#yawn#ps-`Mx4VL;iFR5*?LWbWp`EN_Izx z^o=Zabd@9LxgZ>oS0R6v4j1Y$=PjNuMLI2QM3lWieg`}6eD=S`kq|iaxcCHb-!dmbZy-AU#kF?o(0u^;6F)Af3j})?XdNiOq$gl? zVAll}ur2junJ;Z)E>t;ii!uLD+%#DS#Kt;+nGrH9Y0^k=>s|rB!Y?VHLSUaz@w;KK z=oPm;g7(LW551edNvh zMS_~4nU!$W$8@DHh2b(Jjck&H#=fq%()h~#Kz0p4gj?*{pamK@zU`}H1xLF)#C&ON(v;mFaBBvB8!@hE*S_ec6$N|Hg$jie zw&=pF4m`HIKNcNwwcN9(`TDGXrwJTI{~Knu0c0|5s3*>53NkuwD%_MTJZX zlTR;EM`|*i105nJT^D|5)wUzS&vH=x3P#pP+gD4~?VVC+hF#6uf6bM1X1YwA{@Uj& zr3F=v@_JVb-ta!+o-7Oh8&0>qYnXIWprGKvlfdN$QHo#@rbO(SX&2P_`ZYqzrP5qz zwW2JW?k)>4gvY1^HYayU3FCzBJnronZwjaeW^m&5Xs4@fg0&0<>cl z_g2C3M{G_6%)xl?r~Qp4n;FA7!h=r~l)T0Rc@#ht~<694vb?o3VGArdJgSWtha#_egK&7s};bKQG*g+jT_~ zDBQU}yzfI$vpJPlf~qo$_?i1)Y>EA_q2n;l+`bRExR};@vkyI!{anQ5tVKW=O8JK-}{Q#wHvvE9?h2!4Rte_ zu=0dsJWmGVxS=Nn3($=C)}JB4i{ebtgM4LMev{X9ym8y%gzcD$WpV3^vQZEB^sjfT zB=$U62Z~?;N{$if**7lrZSbC$X;^vN5GK5n=lB_cr*rl{V7)NPvLI=Xr`NrI-w_DB z!>PrgX}a1Z+^B!m%?6r&gy)I0UXj8|Go&I!2hMw|7Rq);#}j& zJ(mtN{djZPyh&3$yMrd%%75v+{au><+!myhgI)LYtO$e31D|m0JZ= zMu%&>q=MFd?$N9SY3g>YFKWNuj`}NfiowBCr3+h}shqL867NsvsW>#%`}>jex6+!n zTQe^H2wnS{ed-%rI%|TD6x*J5c}TF}|i}(}6mRFpQHXb-PqMt~3zkoZC_J;|Ld5udufcv|AT>bz6j1KqXKNa6KIO+KpAskMRIoff+o&)kWSd-r|&e(2^$H{aie8lQ*|K1@t!KvT6fvTy&{9>SHhy zNQPD;Q`LJC6C)>7#~~y3+7PzZYyMWp1P);S&v1;AXj-cBbZ7#Ns85~>fuO)mzt^?D zTw@uP&%edXxupYB{OBHkneDC$T=O#O6o*_eZ%_HpcZhr^@^O_lFK(ikZx4Z&Bs@?) zx(~3#E;F#7k8yFNZ{-m6CDuYWdb);|8VU%0BJS9x!q$T=1`|3lRKM`Tqw>`Ac)LE8 zaDWNrGqiZ}7D{=j+rSw|U%06G{@(|UB#L}I=ZBy}55J@jNc0sP1$G_qoWe7~mxp*> zFA=lUR~NVpZ0(UP!g0JR#|ZlSbH?##b_wc0;vFZ2JM4fnW{3BB1`zP|RTFm~vL(|W z6k-L3w|_C{0RA(hPl1f#^yetfHbCd)I!ZG%8A5aRsNm9yP<$ceNC$bi ztbSutB#YXS`It7mP$LsGz3IE1Gt`+DSMxqP`!cd&td5+%)$E*~vb-HeCzm2No7x*P zc8aHYTg;p5RHE!bFzaOuMJ{bqyH{daH8#JuSM3uy(LT&O?J-Q}Bk})GLf4BdQt<%e zmolM<6|@@J&v3ox)XPe~k z0a^|~`Xh9!%1q#?8-id=m)O^29vX2B_9~1##rL9~&Rvi1c@J7S$06~r8=9|kZ;Y|;{_YQ&F=Rr45ENMQq5CF9a6$FcfXe|>`MiLo7yiN1kS)g- zNQ>Go>Ylyl*ZdU*liIM!0fM8-1~^ONXX5OsiT)>CSC4o$1nQvTu#~R z$u7zg`M41=1lqv+CQaeB8TZQB(+&l;$qprUO;&j*{=|*XJDYCUL?b49&*Z1%=BLd4 z)Y*f!I@s)uirdK>2m)48V~X$j5a`fR0*V2*Hz|>BQH{0WZS26sqS#Ru)-BrfHU8eD zM01;!A-eOPf=Xo5()0(u6j{r(U>uTa?LYc@=O@-%G<2Y0wmFq;ZQ1ONFZ}EmFSV%x z*(zxwuQeVk=&DoGWckB+-RcnJLcJ;Aj0#cF%SAgWnK4kS6m^N} zo<`Rpb~|^Y0RJvy&tBwFM9rC!0+Z@dzCnDwjmsGMEU%_l8W9F;tV$Umz^#LIXXzy$ z-elS7Ii>IB={~bl96_1kl?Cvk?We-9hQMIT)hPIhl9MyoTSAU2Th!U90XZ7D(B7bL zPMBD?U5-cn;%by{idon7XswFv?Y2OyoY`u}w#PTErM3I$Z1j9FnSXL?#1$@3J!%(u zHGIFOI~t=56gT}pPkc-12J^=ut)YnG4)ht*tfi3sVNQCH4|Sz%KG=V2^|l_cGUOFS zY^hwx&5&&CRk>X&^_8>P{h1o}Noaa4(vHv|i(A*43(^32n33X(Z_U5V23hR5lx`t* zxOodv_{CQ-n_+K_8xzF-JsV$`jp|vVHc%1TOqdG@VvS3rX|Xmxx|)!l6opI=!;LuG zdSLaB8ssPrdV{L@Dm&l};|t|;+J%go%(GlFy-|IQ^QK)DxC%g1C6KmNAOv5Ut4Eq&!UGIg`bpu7-gO z+r3f&e*@Vx(>58!w$X7NJ_b4MaMGNfvTf3OMpIoPIOB-D0cvdDg2svPi}*Y*I85w_SL5FVE$R zp!NDdb3Et(lYESj=8`>^$ZRK{!tT**L^Z(*HaHAuQVeiq|_8 zDTuhz#uy*HbDK;UPy*l+bn_!$^qu67axo1L-5j_YW?F_>(5Bd(x*pT<{N5Cf zIkw289AbPkn_RFjKX{R&$RQP^T9_`&>T^DOrTyf>SL8y9_m}LeFq`;j zxv<5Je;$U+Gls`@eD*<{Q;D%(F0|Hh%UU3`Hhl4o?%6Dfab9{339o| zq)K(q08x!g)mdB4iQ7C1Q;c+6O<*4EfBG(d6S9oa58~&0g9`%% zEAoz^fyY6J#$B#;2uPJ+1L_)laM3S|&z(yxq1KqaWr>NzGJo~WvP+h|`!|%6UttAn z9!bcqaovBtbDq0hvf1fXi!^BEqB?N>i#os`t+EW!@nWZYy}uF${7+A67{eEo?u}0+ z@4mUl(Esd{-l{7o0uFV_^Z~vlHTi=R65A>0`7!bxZ3s!NB&-4D5_EzzG*v%5s8(yz zaiskbXi6gyp`h<3sXc>k>Tss!zXo6-gkd%bZ=V<8xh@76a2n(TCFes*Q+~=TSqIAV zS*+F?y~+ED>~BM2LP~4b;M%*!=6I#xL{FE!xd+kb7r}=FBmD=96f0)uBQYbIBtCu8 zLuFq^x)_M8P`d{Grh8gfd zF_^+K&@<&7&o>#HKWjggcd^gVRTQ|@dF7A=Ke@pBoZmh$PCc1i>kzqWPKY8e8htiI zkGcJ(6hcZLNiE1cb%J0_agJ94Mh$jcMCcBX`U+NX(3=+q6>628-s&M@bp-Gk*82qYWmw3~+>u(xtF7=k+sg-pLlF5o(_tTtYepZ`dPBlG&hZ|n$Wjtm@6s;ED{T@d{qqRW zzLxTB?qvJ&vN>g>tI94&Y~$#LY~0Riu10ZagA3;`RrbY5uSM4s!8_BI%{@M;l!Cb> z={!HlcHI=QCk~|i^V<9a#m!R6)&td5)*jE^!Hh#de^d>E{X>Cpf!L{@#gZp^=kFUW z@DD3K0iuZ%+-0DZr2#G=;~4#PcM!e-n+Q}i=xU4o$K@|kh%)%A1y2^P@rolHpc5Jc zz0FbF5HWUVfqHFtB*HcscyxybbDKB)DWP!Yz^lD#H|pfG)Nw2P$w0Vzg76sht&d`N zIqoh3-OmB;n>b6VhgK#jm<3><*E-fSE|P5=}4!i$aFh*>Zmd$%5e`+htXQ! z{-KB>hZ{y53QNlwg&>nJbR?r@-Ftu0e#CQ+#{xvLxw~HLN_LUykPw^5uA;&OZH8(? zY?00_?@i$nJ#$!ps6Y0zREv$2_dM2uSli$(Qz0bzA= zP5z3bXPP;?h#XKlGWAvRmgo|hG53CWSUyA@*ro`I=lZNutmR33I3)lM4&Wp_y3+hy zdh8a?$4*oGJg(@W9j&CS56>t)kV+4YTWc^+ySy%{lyukB*|i=z`0cv_;gcXYZ2c=@ zX6-PMxYCR4TVE3%hh$cC-i=s4v7-WsKM2PrExsTbGkGE+xSaGX);(aQIaZm10 z)18$7=b1>Vt=lTIA19-@Nc(x<{C)>Oj;yl3TL%*f{me|K(FAHml@n8lV|hR`cV?#v2g zK9@?&qH~rVMCpf#vq@NhtFZM2d5)bC035fUGt*S}AxQ0jac9%%CS>p&6if*~|1ZoG zV(lEX$)F7V0J@Vh%_dB5x4kBc_@Q<_exQfa$qHI-7bCrecnr-)!l9hz8i}zv7R%5=~ z+v-5sO6+j&&3&F9d7lE#1bw6Z;`5Bi{C=S}%s-FV0c;(T9V!tYQ=0}Sfd2$e{}ETA z)t!T(6oo}zXNB(=-N$tat;YX($o&qtmTbcUwi8rm-QNwWqygMOOYo~dtDDFK6|$8 zCu9#_+vwD`a^hQc!BCg7?M4HF5=%RU+xd_Z2<%}QGrfmLH~lNIqZ6WQEZ!$?fYE@g zd*Bc50E%xeoi0(0UHwvAZJ=RBa!GL@@g4np^Xifr5*hhNoL@?P>`@L3tcN0Z zi8m;)Wge(Zm6|z2>#?WlO3(XJuExTC)a1+94~|GblP%(w&v|^rF8&{%{bpE^ zW}1VA^^=k0gE>Jj8ZOlb@WqWPE3x)@j_Fc+?@2;)t2(Sx)CWi%@{sLj1iupdDUIv8 zGgd%)@y@40y$_4De=K%i3p7iEYW*LJy}-Z56fQAUJlKVF>W>CXD42nE5NX(&0pW{( z^!OmLtY7#Td;PhISXRRk=G>rif5E<=wSQS+!_Z?Dr!up&d;@tdL*pMIuwh>&KX6xM ze>6Y~%+ZAvj{oo;6&lcyZ||fp?6y_^NMWaV4$?{?_JP~nU~voBbQ|wXaucNE)Sp4- z?1HXn3cIRlFzg?b_9x3DFjb8)&L;3<&W!S+8KX960*mO}g6S|wvfN^zZ8z3J8S(O` zA(|_@#6up?-KSAk-XcO}6^Y749TMESdlNo&)iW!Ui6>bpHGY!0S^h=9!UhyR73SSa z1dcnv0X$Cok32v=h{c31{S~Bm8@=8IP^NWoxwgprjH=mQ%}Xy@No8)KVm$--8Cot6+)@R) z2W&sW(-L|uAZiA=`-7bB0&tM6=q{@~G8M-M+nxe2k^?q$WhW>E0yWKvdwU-Duf=Tx z%^NS}C7$!uWAkF14`d_ty)_x#VPzGKDch|qRZ_^LL}lL_MR?~09aSLhQg3c01$*@_ zsD8;G8yRsUO9}1a;xk$kZ#p;V*H%yt4xLN#{P}At$?iCC0cxOY5IJ8dWkYGu2G9=i z_O0A|AwpoID19Qt*LWRUcK06;7)tLeOZHI zEM@*N0Fn}G?Csm4;U}I8HS5DS&Faa4BxQHZz;9fgo=s^iF1yydW*pCP2A!ydGks?c-vGB<42<3mU z_nvW0ZQI)@>K3;sq9CFmU;`8cwn~#~qxas6AkqRzC$y+2N(m?uP^$D^LJKWKl%gQL z6FO1@gcbq>$ej!KIp_brXW#qn{_gwX^2whp)|z$9XFOw!XU4gN(nglfn&f*w9g)CA zsV&5=H!WKgI+(cc3!QqUoVmTjh>N1!R!AxE&_Lr)XO)nBFs%ZfzUfXSyd!*(v=S&y;Ko! zK4q(_ZAQ$EfH+*rhKF`gZbM|%u}b%nW&h8Sa=>SIH=(Po7HT%vt#A}yTAwm0|B510o>Rj&_hQ@A&$fE@MYZCO_7aP_w|5=OV20=Sq8}JMYFDtr9I6gwA`7`^x!p zqXCq$?S2tNj#8(^TTh7;C+P*Y#Y|n!Xa1%-)+YB~&fl?#iO!W-h6>ior~h8bP>5rX zY)&<779~AIY`t&TmdZX1u3lJ?BK0&kZ(5Sk{ld#x@1z@Z9x8U@vRCTp)Ew=(5ngB7FEu{biymyLR*X`Ra(SdbevE;)?LaTf4JW zM!E}wL=#Y0(Iv)Tizik{KovizrCv>odgAgWy2v~OG&jS?8qXQ2RIh58)`}|i!9!eo zK-Z?MwCzQrJS+79KazVyJb%MjJjki!N!m@fw~29^CcL=e%ATe_s3Wtv5Zw0^U^gAx zKd&FKQ+1A?5zLg?ztFBJ&XfCmz7^uc-~1L&(PewqIhg@-DedtxJ2eg&Q(g_Pl*4P0 z={7bd*?dm`*n4Zd2a{@vgv2u(UbMA{}SsI-E zg_{A|hF+(4l2;lQIPyI*4$1ug_^svKRs(cJHH!kl|a{og-9gMl60kb zoVmx*MUB`8oecK*cimJMh^n00AU&yk)Iv%IRg7CxUXWbRYb1vBp z$;S{czuvl^bvrp=Z^0_=O42Fz-5X;;+zJs7 z<9=E_xo~{er6Td_)ro<)G{N!Zt&MQaFOpB1SJh4>!Oz{GDJYzzo9RVlS3MBue~} zdcMwn5dH7zQeky2L=+M}YJ|(Ywi_8Re*19r$UU)xKgmi*i|ZH$%uUFG^10qy^*~s4 z3Uj`rLSBS^@*SDxboduq5EkbJxe_TtvIVqwKPXe8f{rIVp{;4Z!+<|_Xt>b8;oj=N zr>7cn;H@A-2t1#aexGZP&Qq`-nH0so|MYf%AXQaIls?#hITbFAm=5E)N9mp`ZUhiQ)er zg8%ndf!GweoB9E&M9qid329B=4}<~W?og>c4b8o3sDQO)hM|N?jtRBLt~DE@HqH+^ z)mj@(ONu|l?KyKvLC<~0f}%i>N$B{ya{kM9ASlBWF1khDe{+H}pr|C0<0^h_nlE%+ z6yB_IupMar3IWgO(26X&Isl>^N{E=P-Q6WLubG|VkTl5?gt7t@1BDhVxu7jZLz8*} zs&||27r;Qdp4lF6Oh=KlSF!tzKhno26CLlB#M2(P^Z(8cI&TV^qsxc$tQ1zTn1Y-a z9Jo`%aC4XuT;l-tYv*gwys|Zi7~?%!kxdZ0thV^c^@m8?WnZV`2l@bC<{kjSD5LGN zmi&OjY&jYf0vHF;e`pKvu4+KRpwc~XBjEZ!{2mnBzCmnpL3g8vdhG9zUA@j8W@|;y zMju!qnlJ%y4|5L6ym}Z23l2+A>a;Yzow{ViG60D#EP~>3W~ka<(F$9$iM+Dc#7Vrt zFR``6kiJCvrm9StFAxmDISv*}QR5EN#)yeH7Y4t+ZYc&S zCb^3af{=w1fel2B0B;c1mEXO#WLN#KDDt47yqZp5w$*@WWBA)%v(U8GFwWWNlUQq?XV z3)r*LIVw_cLFN{l@4RrjJ5Dd;dkh(F&lKYX_<*ovg1+z^l1r{=4*{lhPIQfyKR07 zq!apFza<*~z1pjQAV7{@z>+H;M6q)1ItrNXsGwos%o?dLusOm8#W&DgL5*L}d-Wn^ zjp$R1`njf|69d#S3v{U_Nas$8FvowCnq92mLQtBl4+`(Qf~7FO)8H)JfkuH&{_fDU zUg4J@+QFL5s<=?0oB;}IyYuXT2Klr{CECu9h%=Cu=A$u=%Hq{rZI-pZ6j zt52%VkX-#$f)cX)?=} zm>xC#H&Nfm;c@?juM+`eID(%cs3!Yhw~ZWTgYumzMBILfLBYKG($1{0#lv%g@G1iv z5cZFbw$sp}8ekkL6~zJUNW;lOGO3oxYxfWPO8lsZj$NV<+y|{v5_s{hYhH1H%nM}u zrXT7UO;zRcj&aDwt=yq@m3hS)5S@4BG1yC>nlu=wROrxV^TnqIe$_$vi%(=@2DQZIn{ z?-iVL0%ofhev4XBvqb@Zn^JewPFvHLAbPWSz=!;$D^X#qvN8e6?D_kA9Y^q}>CNFr z7=$)x{#t{KBeYy{1&UnyrO3<(HW2wL4m`%7-{%IJWUHi0pEHOY^SONO-b8%pmmtJX zsz+Tz`sauQR`M3woR8p@azSUH47->cY#+V6XNj=h6K4(mX6`)OCWR9E2m2XdF|{eN+}3F3qq<6kZZx3mZBTXk zRudwC0Hth8g4dY7QHI60hM3)4g95bD;*Q7e^GKr?J!Kn3|2aM$ zGPRgmaNv2$qrR)BXlzq@RHO&_#P`j3BS;rgwj%82;p}j5ophn2Pw%EOxE66jYQGM3(;hOoUlH)XpCg z8VSqz(g;)^W}ApahlE=!W{FEXzt)?}^RCLUw?L;hn9u&Oq>t=?s%sYU`^O2j0!8{y zKpQj_yIXDPV74nAkOhTxXD}2)DF8z@+hF_NsrK3oESs`-PZ|H_Q0RPpDMo!H0Ai08 z`#<3H`^x@%%gTSEhi$d=@IL{$1nYH@G9x5e_l_oU_mxZ-(05r|S{kn8Vb~fF8X0g? z{tbcUSU_@qZ*!q(c(Kz9KxGGp$R(+&i*Z+rm`KC?g6oSk^6q4T}Rm33k^)~ zMx6Q&rnoeu!0=l?sEzXvk<*TlRtPxyTpjvr4Gm90uliE?;Qw&^UJ3=8zya0P2302& zU$kKd*7G~xAeB_7#0qu6mJf*9r0bi(`6viP<#o~J95%idmp&jBbQaEakatS^#SnM# z?t91K3NB+%2D&&Qf6fL<8}kilSb%|&!Qunm9|#x*f%sD?;|t_7kaGVQ*iX^?#+xRa z7=(#lm5razsNYImcykqa?!5FLA{|PO$6^1L4w~2+0?S}dmAn9iaQI$?sf~ghduzxz zp6B@c*~Ou4!|dB>%^y^|g$}dba|TDKPL(&Oz`_p^IMmPB)hGu2oT1Dsv0s)LF#$XT4__)jmE^$N}O zhdHeTtGOv4ua4I)o-!k)m8P3}s`}!8JzC&*x7ukpZTM=0K=w^Cc4uMGCZZ|>67HfA zBmW7DN6&T(mSiRwq9F6XJr=M(?`<}Kbp(1WcOw}*v3o`Q630i znY}G#E+p|AgXcLr+};eO*>!AL9e2H}c6W`?FeY(S1Tv208^JbfyZ!L$$6p<{S@cv# z&PzO-{hv94`rf5jV60}fWfsnhC+L$}yeN{8n9%*BOL4~K`%6NB3<1UKC9pax^h>DIqU*4(ALavrG)yS?Nui? z_RUi}u#qaPLgBn9b!(5xYj>@8-x;VGt@;xB@rOy&I0E5CGXD2^*^VbwV7=o zK_5L741{=>sc!99gS=Eip8!TL-zQz6Fr>_sqnXGG;fv|}9cFhtArItAQMQdiA>kR2 zBMN*O8z?!Icb~}Lgrk;8jZp3F9%H6XV5z>V?W-u8wFZG>kj0Y+u9As@-fIPBYvb$t z5Vk8$9J@AnpqxY3I#y#5m}U8Fj&c>{xMjYfdkfvdk8@2u$CX`v>w4MwXLvuroA9-; z<9+U#BOF=B!0E+ehk@;9ZB--MqGos22+riMh;Y8WG0mfSc$U7vu|0$A`gxO_$SlEq zt9=)^-C#qE3Ch0&XOc|NO?C&Bb6Hn1^&WY~LA59~UCY!~2608qm&Q=Rg#6OG2;AJ- z;sSxYZ)QF+U0vUZu3p2U)lr$*yL#Ab1<$F3!@|4EL6H$fhVd|)4+j$D6i!khXoYfH zoHP8acVgcoXHWuMcv6}&E{B;?Uk!898a586mm`SndJx*mHmaz;omH&*-yGHR&0&y1 zjRzNr1U0{YB7fA$|Bz0JhwyBGuYV=;%Ua8wd7II@qIe7uZ@E3M{csRR#g^$LXXRF8 zS3fr{pi{sUT#Gg8psMO_XgOMGG+)K2>iUW6Mw=lV{pZQk_#GaExzwfk8j9+GI*^>9(jPr-QZ;|) zX-s))bA*+RrUnZSqH^SoMr>K#*fOMQV|=f|uV47Hf1yKV2LSwE-X}SM1bO%e1jwuE z%9|o}zb^Hgdoq2(A#`c(q8A}NML=3$>Ej8(_CN_xK)#8%_J>HkAzAuel9kuUT!4ls zijV5?@J7O#95v@_A)!58KVZJnW2$~_Zv|xY=>(W-Nlk&@g z?Fx9ErhR9v>gk+AUpzawMCEg&a;gCHesS|%P%^hKJK*%NXLx^7d0#h8m%tb&w;O`4 z4avQWQ=PKi{ewzINN#{Ym(VTmte2WYGGN@jB}@@Rg80MP0!7J6YX?4=iqwa(gr`9r z&aH{-7Vq`$-$UXpyI*(QT_@)oi)MhJL$v}KNaQHB#12v4GY)8o=BdqYQ3Bua<@30= zNgNf6*h{Gq#~=QMZptM;Y_^F{tHs1tP<=H||Dd*l0DMjwpgq2tKC|3CyHCx>HB88vZo&|IG${#G8RY{x9BFj)gc~X-68D8@4lqpH68`<4x_d+ohFnnxxj!YLwcg1%GMOR>x_; z)Jtw}u;%F=vDl$#unepmF&lb{5jdLSFzUPvCJ&?&zTg<~6!%}%S7wpoVr-h5J}Pvt9mYEjfenGmhRn4;pj z53{kx)H|vN<_=9qv-hV76is-k|H&?DaUeHi&)+#88XyS8SO?k=RjE3Bo%>R0ewh4Q zzdQHmV7SbsqL**VdfF=tu*>;waB6OKu*|)Z#@BaUw`{rCL9c=s0P3%J zP<)tHApg}yzg~$0BH^lhGs=6FFE>`LL!e)%)Cq3daj92?7Ls_WrG=Gt^Vtu{@^{C0 zsbaGA&I@4kYiv92VZf%YkH51TVLIZuxE7G5j>FGD?u(%S$ZXniB{~-_OB!PjvkigW zTdRh5>_L~rx-SIugdV;SAj<8_|CYAFqlHC)SHCoFm|6}HFY%aZp#b*fpZmobi7vN% zMvT!-c;a3mO%P6yE@UpC_+UzEz?3vFN0I~3IGyMH{S&|SUBKS+*gdp$5g~GnWP@oD zZhU22JC9v}orVlK$-@hW_9c%_679?LE#B-GtTJqfA}(nonI@c@s3GS4F;X+}!RBa9 z*#-ejkL4p~bNX{)fE`@#x2`<8J+53-2TuzoG#fVl?XXP!X%+sw^rKaM~lJyo>8%L?(Rju)@nYoel z2khcncC+&)k)&3zSes>`13uJTsC}Sf_X;9 zyCX@J4V;Lnj9|ORbR)-QWz+;84GB+4iYk2j;n$)t1(wY&xwBH0s@# zw(tbu+Mo?O*w(C^W#g%pO!i)jLQnX0#4|;p2g6T0e4F0Zt~yKzG}#Ks^MEa1g|Unf zo!R$VJgF7C(+BiWX})~FXJK`{;9Z_lIlp&Pv3Yy~5F)(MWy>l{CS%6-y;jLpFSfOu ztxgAUX;UWm_qV?CgyM3)j_((YzoAsKt!S9Lo31+_wOwdD@%F9_qY-))!$(JJ_xTG@ z$G2{mp=z1Acr@-#$?$8W{T^)3oq?*=>v?7`=%=f3!?dTWR-5i?a^R)hleXqaiH)-~$D^>S zkgBb^V~81=*0U4)1tIySf+P{z2`{#-_DeyT>)-<2dukQin_4@2=1EIN6SV#t)IPiD zu#axsmzmk{=@WoiA`V?i=@+Ak6fc@!VB|~4xIrS(!3O*ng^#>Zf5C$>!`KBq+^Q>- zAjZZ~Rr|wbkh$Sw1^vJFlOljFR-#KbF@Io+zLLt1xYze?3^ek~3Si03>MN96U34cX zb0~LTtP0T^6`tCf?>d|9(Ylg<7Oa7hk{RahlBrZvc*FNSaN~yj*VD&%bB>w{@gXL@-8V`i*H1yYaZr}`DQPWM=0&5dU#o_ z>YP%;8;e)^*@P@I?4n1?f&R*opF7)`gVz_uyZ*bi^bc|iJW^Ie7hOS_?sM-*qSH1cH znoUWy`Xh9fMoK-M0dpo*jya^x59-qTyHr4?^ARdYu|o)4Zd67TAjmsU57`1!&=TWwVyR*C{0u))F+mhF|#E+#F+T#*7o#_wys_AIB4)`nUz#RVShi7cxqQ; z=os6;X%G5mEs)sBTx{Q>h!Z~veMaSM2G^vpUj9*0a z?J;NEzNXG1skg`fZm-H=5l0@-gDgS;Zkk%+HS4dXjc08d80O2R2 zL_{S=>hStnGoY=mncv(Q3T4v$`Aw9x{P{&Fi{QHD!`{S_o6Kw&uKGL%8B+7ZoUGRE zC-)ai?0k&acw*Q3kPeleEuq=b?87eo1xeWRF>!ysPpc2g7<0FZ0tjr(J@aGpN?hx`&kn{SZaVrNA@#c*AIpD`MYtRcF<5ty948pB#@ zbR%W36fQp>@KMN?A1qzgW5LMH1t2+*t)X0ZS_^$|w&9t%0pg7(Fsl&gr9K;pr z#|;ZyIg9W7`Ic6^)MZ+y`V=`oz^Em}e!xzV)F_gzb=LJ*c$BpNF%++gh=9)0-4-ph zow$F2kZpQ3C#(Mbk}|)YL6-E8#74_!Ef4LiVs`KBKkUcb`wMWf)$aS~+Jz{yC84U$ zl3aL)Q^!7w{h0jqN4?h_oe^ArPjKX{lmNKXrz}adg*>Kp zo8Lrk%s9jMC?J6Tp6XL}8gf$c_+zWre75wbM+&Y6k3O-def!L?^@@cRZ?-49lVz$2 z%e%auizEJg9BR|Ca>r>fFNGX;n#{s-huoseEK}*?@}F~cUV5)|4ct}s@efba%U(1} z{U7^z+lw{Z>W;`;<{$4`9H`CIxpjh?5DhkSrh@&g_mBGZ*SA|n#eI}0<9e>B_@Y~O zK2}uWl8!mFGrYyPs^HwsMf)2lXgbd@vO)c5Kj;U6JZ5byVV&Rz+)|n{dCOGn&YLGO zjU^p7FR>PNNPiCHB`38S>-bRYV)$p{P^PE}rNE{1?5FIkS+~MkyB1|m(3`LpxQ*5R zx^>cIeTF}L65}*7jjGO(vgy@<2}$Kk6s0*#rjeDW?p}Awz7wZxXFt+M8LfJx$VMMx z_u(|FL2siTVYgDbu3Fm$D0z{b%hbd?CRJ`YeLqq7$anI_u+#~)?h@ldha`x)PJXS9BW%%gS+77fEbGP^3 z^sHTjF{kU@U5K@`0zK_GuK@d{;4Dh|EAPdh!dr%=@OGSt4m${0yc&B3dZby~Z2tQeK;ugHGTjfS&JT`-NXuY3%|GQbfmYk34Ma49tACb{{A(T;c9?wn80 z)}?ZYJfi^%kHaN4|I)>z`*$7<*Lw7a9>el|t(t9s9(o>H-*{Cma4owb zi1xIke~2bk6Xe6B8OjSu1k=89&ula;hn2Aai%vsxE|@;**WGtq?@&+2k275;hzW`~ zK4fH<4>jcTZALblg{Q4Us%BabyW>R6D<&HN-$Qec5&C~Q?VxZDiDV%xp<-40WpA$N zUj+~o_&n#`Z_1eFHRuQU4;q@Y;3EhB&@i|ra`2CPkKg}){}58GDLmoSCQ(Mmb?wmy zeY3W0oPb~al>UMiK7g3$^olo6uTT8hEF&^4kO!dh#f3~&a zB6vV*)BK94m&;tfCbC>E^=D&P+ngOO^6jBI4$K6~hgX}&&h z7XfY_6 zOL+8?c!{MfqCL^vvIRC=F%o(_L9+8~=$?0*pCC7%2hydV)IS(%rlMdK80P2UcNUKs z8y{c%G^1sR-IU2St=^<w2OJ%PMs&~BWgiqs}9 z5-Y?0*3o%*>qi}soVE-;QFiH**!-S>iB=2JS> z^j8E=6721|x_>>8!W@_qsr#0xAB@r6AL)r|3A(p;r~55Yqq3pV@Rp~fQHm+^qP`sN z46;3$uDE(h3Dta)mrDek{>OJ@D3&_=J6kvEuo6q7J|<`_Zr*&Fr^-4TJWYk*(bnl4&> za~&>%jm>=jnV0uqUcm9EJr*~u8Osz+ycz2)ksb0+LpQ8<=Si;6n7r#PdU7pX zB2g#*q!z3`h*e8kFaMMwK}q64A|?U^Bs%O^B`Cq{S7n34sFIyBykq4f#PG>-gHPmb z#=;sNArS>mn~N-EO6Xg9My|<21g^gqMLziWFK!W`@ifLmDN2(7e8^fC`!%qFC14wC z;N^eYqNAv%?@~?;-rJ!!hlI9L^WVo?K*&c;IuJ(A3)^S~IUe-rvY&VOdaGY%|igt%oDGgL;5b}M~3z()$OY57y ze~%pKuqoiabvnnBx}J7Ra(GGagGI-ej0x8`5vTR$-kfi$0Tm;f!^;xT;UC@FQtl|@ zGkfENXk|wNfvfPhnS#a~n5oNb;=JFSUOUx)cS%=DL*_mi-Q_Zy)*xs#3^jVjsKRVv z?;@lV^bD;k+A^4duJO|;J!Zd&Ps_D z-7Sfdoxk{Fc=FA)2ZpRn)Xe^4pMKkEdd(|ez)e7L($zv+DM)22zL{9ltGfu{JHV1cqg(dL zsV)zP+jl2dG)He^>r^?ijlTm|0zSN~3Fl^6sC0zRv8;2@ImX1cP_;Tl_>f|No?=e3 zbHK8&xoeKF3B9%60`dWUf*1jIyI}gxdmmF9YcAlI0d%hMfOeRWz0`!--8kVJspnXi z12W1sI(9~!L>3a!ww=XuV^Zv5BB9zmZIAFwT#T@=jYgWpzmFw%;O9VJO}TKDR(wkM z`wMdfc`|SNM6}$h{rt1Np{1^|Ue#;6zGkN4&0He&r{3n&-RoujTF|81vL`tEEkc?w zG|D%18(A{pS?KNdwc4ywIWQ*({UK9@A?TE^@DAqb5A-U$%jUuzC(BYP(-=GcmuqSQ zJ#KiY%N?fIM8tJJfQtc})Q?4w=2=Vb=l>ZiXtFx_Kt3Wq%+i|BXR0}vKI3qo(}uTG zvdUdY3HG+ibays*U-M^CjNCENLJZtRi?AmspZ{Rke|w*jU>4TmsCz|G8(Za`H@wxs zmpZm$xn2%m54ZKTH(Z-dnyvY$G5Vj$h7Kcp(EA$?M?#3-HK&wEBw_LU8R!dNEBc$% zSB);@8J67A%U+zPK>>(S4Da4F7*6}q{qh)jpDpx<8`Z{t%WkD!`-pP%&Fx0McKhf% zYHt};d_9R|%U|PlsdXRJ8A2?3UB4~+Ms`~9)Q5-WEp3H~2t+l_YMnTbiECvEt=+UV z`OhMlJI=_KPz6Q=p44RX=eETRkJ-AvF5@>>dWFFr_fg~ay=p{EmF_E-9qO`518Z~a zz&mvr%9V4~;1D)|CsJhg0tYo!(wp7xg5Gwm+(Pf^eYKv>@koF5fsvny2gk{$PrmF? zhbAZ$KmOJ?Q0$7{&S7C`o^q?yZnih?Zaj2+`qRIyJ`b=r3r@h6`FI%`mUwFG1nkab z8w^fz@zr>|f_X)xo9C}t7UyuIU5Me-3sDy}3`Z$MZkls~W-}=L)ajx8`eTBlUGK0B3*E^2Y%eJFj`xDBLDSP! zo=?)9xZ*^JZ_CcPWFM~G!IMTnZPiG>DjNnqZHMj+5b)U36wP=B_lQB~2SomQ|F7O& zVz?%vp}nk=Lm_jnHTymY{K#>4SKjVf$G0~TF_97?+1a)Z=3$G~$Z0e9 z)$M@`DsD}iQf8I83P~rR7jcMy&oilJw#x>(JpJU6nkXcoP*Lblp+9BhoF2iamDUa% zavBLLLuxyK4VJA&2H2lCi|5i*3(gtHI)4vzpxZ zGAz)aNzy66K4$>fyS}gI9NTbBn7C(z66V%ZpdkDJ^HuTfsLpS>I|SF0tL_cFLB*! zz99MJQ3td`55}8j4p_E}2$?P1_|)BXE5*>Jq>HD2e!R=G1x!?3tv~K)wdWFjv>;XF z{QjB)x+366B7<6j*i=5#K@&DO7}>(<*~%LunVoC4Jv*S;;ISV}e)5Kq^YQM9Z*rad z2dm*ZE7&xOfv==jd%hTGrRI}rS!}YI-^88#gtN$I`RzLSKnDHeDt1W>Ru9EHa;P3e&eoSM&u3R&$rP@lGZ+Xi}jqUXcBRtw#j&ub+x(Tx*5ve zc$5k3UOKaYY0`kS?%Igg>JwG3UN=0-)?&aWiEYMljO0$eT-S)iW3AIW+e&)Yz5Ctp zb_-Z_(s00U%)Pk0%M_&EiTpM#3Ixt28!&NfuVtYF&u)>q|JrT$m^#zoKUCOx{Y&l)bkYY3G~ zLZs15A1B;zyXV6ej6AjAd0P5A?ygIYe&XxVpep9W5^_zVeAT??r~$j5ibu}Y8k7Cc z;xmb#RRTXgbs6s;v!Y}vQD#~tl)8J&fR}t{Ydgj*_u$Kmd-L~TV~xn9ix*{lc%v)C z;3+pg{>wR%6KmIMpE7NC%*-ZB_qtJjV*rg4VCq$3CHZ~cCEax>0Bzu{b()^o_)&s( zRb?YY=SEbU%FiJ&qrsEXiF=j$qo%R*TqeZNm%mByj?7QVzRf6X&3y^{%NRGxOu}bs ziQpr=mL*|-1cw#V-O52_EJAO;`f~Bh}f~- z-p8Y}$~9}tUEXK>6Ilmz9~+XfELN!8@p!53i#N@RQ}T)!QRMRVlvTlDx9F%aB}*Hb z&W%s2q&}jga$-|;?0P)-Z6uh`^^d=C)xA_;79PiUdswvboTyp5*_K#&I{#t#Zot>j zGhSh|s%Hq%b}I@<{OSCu70%H$snxcgPn}g1;59xw@H%u0URoVfR!tdv>SKk6Z%=I{ zq4%(^^HnS#>P3iS)#T4C+U@H%;p{~FcDF=)n|2~ar`<~H_hceN>gB3Ac4gjj{K{aE54m!GzgN@Qd)jbuh~$>H_KbfzKWlWe8fA%zd)esyC$-l5hpY3TBn-c4 z1(PW$W{&SOCM%i#)of>1*~^D-YiXBh%7o{0*R3qNnWAt9;DIFF9@(_I+y-xRz{6V{ zk`~}9zmfZAP2j5(0cbdP-^}W&&iah>Mz4NuiifR|tnqT!Prk>CQJBn_eV~LUv6Ph& zQPwgoOXw>FzOJ^K8FRdk6JCquw3h_Nd4y!yWlM{CRte}GpJ^@PKW-LmaJ}3cz@0R5 z%#@tEGVf~BpVgBfJLUWey^!%NHC~ktt#P<(Ly55&#NpKs@(3alTDnW( zULw-6g+OKCKQ2o5qpR^Y*|Vz!v*q1AzDWy}d%uaAIexH9sPNDNrKeke6<*+jsoX^* z?(-Sxb&Za{DaBrXC=WaY?%D(QqD4P%HTp+)Hj|AdCAT>Y`F`~LqoPE7xjV-Wy?3pH z#D%9}rxV7WeS#dAvUGWD`~RKgP3S8eWA&Yr@m|Sd`S5h|7ddr$qx_Dtesp0>et7gJ zVE6xWAIR;*38$wb+e3NrR*kA*<)p?q=a`IFr7n?PM>7-gYU>m7NwWA0;7m}Nf>pF` zkHxPP=r8B=|Ks)?m9tFMHYQ*Pj$kune`>9|^A&)sKTkpKALbcskLFOFBWyK7xvg*!lLx zr`0|=Taq}kjSt28WpjPJ>)>>jkBJ)_Gmk{rZVVhpPg^g=BF*A|?yPi=2WQeo-!xo9 z>L)gk957a?#@NH8cqxz=eo0@h`{<*n0N^E#*v?{s1@%g$Qzi4qh z(Y~$Z*J`EDl(!AAAE5z~Y5zV~jV_@dFAlCN+dYk1sWXcj@2Fs7^(F$S66i9;)6{JJ z(}C$_T)#1vgerObu!a(90;^qU__4w8)TZELnoH&d_O0Qf9`xl0aJ^@ciMYsA3CHq# z+iiUufP4D`ga~;Y^?k9zY*r)4ukFv~Eki+4R&Tt`k101&<7yi((UE1(Tj77609WfK z9yVD9O6%PQ8IK{T*Vp*_of?eZX5DtQdf+tev^r^R2Im5zq#;Xg>4(&~fF*Wztj=tz zPj`FYQ+y?uHr7!ZF=#9w3;MjV;YR9PZA%d?H~lqr`QImd4;{dDfSZb{I$?YB4~*sM z1wcGP5F~wGVyU>d<9XzSxTxds42q`#MQD8Ys}4(T%t+N`2`PPX#1yXc%*PEcb(dSQ zC;tfmk?HpzeIr$ss^{WNIfos6$N7yF`_^GrxqBv9cn#ltz9S3ifA;T@<<-F480S9@ zsCZxkcRj}yI^1_mZmd3@%1Kv}6H^Wvox?y8mRG~)t{r$FoU&NBih!^=A6LGR*xbao zroa=k#h8wwoV)E^aY?yv#SYMF^JTQAJOHarfURv z^cDXCqj7Ht<7K_7mt(iP)K%0~ZbjiJloSFW@VXP^kZh-B{nNt<@qm-2zdi`K=g*`* zDM7iOC9bfR+o^S_pa1vAzrU=PLuMWK$1nM&4+=rMc!TXPAs;3zY|vg%x~I(hU46T*`o)8I&h)#1toM+!f-+Uj9f06*=;Wm20l)3|ejw|Ns`g!<#aCUW zNmGsL$Mp(FH9TvMo@JW701bov|50wqiy-psJnrQOp4b|kOrGb`5E~TkqDVk3{UUF9 zgx(Rv?*k9qhrNvxg^Q2DSjx-+PWvyw2EUw{$u$E~^)xh>!s}@zm&jC6%a-D(S?k&G zq?ZTr9N<2b>+k?LYntS|!QPZY5jh zPo0i7uXg>$*ZvK#L=5|YWKVajxxIrNpCOeSREAUc_uf=3Eq;3H9EY6T$Sz6OW7}C2 zr048j9W=(Chd%j5Mgf*4=DG1?1!B19{1|nmV*<)}ZL9s;jcdP`!?rK)ggNxX!cb+S zRV*8vTk4@Np@{Z=zzPDul=LUf-Ft7M$~&opEH9N?`)fY(B<*KTj+sLF5ym!Gw)1#BYgniFtJ@m z-yF05f;YPtN&;RPfOQl5yV~>~@@N7~NMFE|VMmhGKD$Wy`R;T2bo6gOE<*fomynmp zT2#FKm03`&r}*KIQ(V$tw^)LZK3P@iw#}XNY?!0n8SSUQD;ZTjZkXAHy`Pd-hoj*Y z2r|)Pu1G(1D*IOm@_1!1Jr^%*`gwT zf9eFrCTq>W@dH8?&RVM*Q|2J*dn*OAv@FJeYE-e6M%+DDSRg3E?Vd@xUt~o|)WV!W zQj?u-ElA(?TK=k)8>v)cKj5F+bNk+iTy&uUQv=9q=?TpaqBW3YP!`J)R{;5s7RxqUfq-_gnhIub(7q0qB7l9{hhju0yhoGK?_ zAIqx|Zj4nPQ))L|JU4$H6+9qEICO#Ym1oqetJuHDH1cWbTmD>bSHgzKC^thFBiqpa zu{$!s4H>PIkB>>B4h06GjE+@U1-<1RiV-OHCMXPHT!ZP$uAvFbc9v6R{XDXSq4>x4 z-EwNMUmj{EAPD2pJ&&~WJc!{y$oScZKb_U$7f?3I^?}BZRasNN9ejpWz7DC(reEiz z%`e-Ne)T5KD^qG~waNcJ?$E>3kC?H9iG2CR+H??EasMQ?y=RcOaSffk=a;A6zj&Kx z-*(M1Pfiu~3$A7oi{uXLC)pna_{TM6EmOY%vNT0$>gUOkOOeoNlG~9eJ+H27|KXTo zFug~pOEo*>M}?kI;DD1h-MrPSvc?_VQXKwMS8fB zfom!^T^Nz1<@3$C|0<#1%fqWDefIyvyUp;yvv-7RkugUpTTnfMZEHk3q?T z5Brii!unD#*cH1Ub!B4f1tM&+&Zh7ml=zBMyF0#TL40W^lUoH^|KpkuL7(61H_DtIczwDG2g4^hCH~vdeWCJW@^t_RC+*#QxB)fK#pYR#v~i_y~Nl zrLcxW_x!pNY6Fy%i|r%Q|N3pYohwG8f(+dC2ZuCgYX=? zpVsgp{tuh2s<6_sQNgmbKU;)G1NRg4EvH)2`BF(??4m#T)Vpl0U>l8hT}-ilSI@-> z1sxEPk|ALIdfO}<(|qj$Zn80hpF>=vmRNH2ax+BwC0xG$`N><;0;8tz#$&mqlo@Uj zP|g%LM`R^my*PFm^bIgtsid0KJ_$20j>-qG&n5)3`R;Dn{k;)oAp#5~XYkn1qlXQ= zzS?u|Vy-tg@`VLhtUbC{9KUqDtEwCT(Dv5~r!|>h1-83ATRA=!A)~z$N1LzH67}p; z4I`V<%qzkT`%vVl7>@v+`SrO2dUS;Wuu4!!Tlc&!yfDf@VNF+lTHK@w979-F^pC)7 zVkI9(B2A%@Ian990frsXuY;av7pBjxgLoT}L`)PO;my?-eO z(#x{tgOHJBs%TrVvXy-WLB9qG?eypJXM&NQ2)|cp7gTvK+_m>B^)vE17bp2AUuNv6 z`%GRXx|rDKPvqwm?>@`fel;7fT((#{KeoJ){>_Y)9iZ9M#@t}U$YaE?zB|C(`p<|# zISR%IK)suRY-+$NLsO#B@`~k+7k&8lD1{S#YkFXiAAlG_!&_C33gFR}2lRXtO)Z8T zKQZs|x0q9!p^-d^tmhk?prnWF=n+xmh0aW8{k2QkagWS`k>+GCk16lnABQ^6b4>r; zH^OWZgN}dL@6`^tq7QiS`=EGlp&<=2Mz)oJKu}p~w)}9cT%s;Lls|p?+gfe=$>VM5 z?sq?~sp*rMJ;vtjWc!!nGUVu~)DM+EOs&?GU~^&>_&%Ltkw*K{`XFdq5&9hG#YL|+ z!Ka}wtz<#*hfll zsUR4Ycz$59%HQ|&|I2wl5>U!G?ComjPM7mrmXn)Yh4n#FFy%^Xeux5A3n z@9+(>-Nc~-yXPJCen25Pgfs-)T9j7|?><0U0+fuA;va$F6z+^l3{1dK(?u!AQR5UZ zs(^>N%duVe8^>1$Yh=^={_q@pH-aJ7;ujkX;M^il)}rP+ceCWA3c75PqVn(+T#aH~hrl#CRqE5uL8@CHW@{@fZDVAT9*c3!S8|g`A}8 zbsDWv)l$iW&co4Xkx`|wI19T{XL#wg15@&b9z1y#>CCA2OFqJ%&qeM%AeJy zV9m#__8AxJcRhY3+k;d(8fiv0Td`OlVHF|UDjnlQ9uGdc%q@s4Pzn6f_tL1)Hg;@9 zY!S-qJ;3Le&@X7+35^L5GF4{wq3`m6a1pnl{n6xeZ2t*w#Q>oYc@UPm13Lf~G*s|+ zK|MY0(sOv{XW5oi5LQpWU_ zV(%@(qWrqIVH5?CQj{D*L=b6_kS=K{>F(}s5K$0GNdf8ZkWLW>5+m^Qbz3Ik-TH;7a zZS4(#9bT+)4U`iK@1Q_{9fekm%Y(GMdnNj0B;uS-{&5%d9sE5=MzsLk*tWtjiQ`FZXJb zlk@xzuEpC}J{p5-P@UC=J5IME-OGKxC(&O3)`wo0u6cFzSmGieFBkxnKW9%msP(tj z?zeKKHWZ7v-kI2qynnWb?mjAE)oh%dZK$@bk3!xsYx~htbXn!jR>S1$&r!>B#kg(M z=c!&&V- z-*HPBmC?$xZVxJ%VMoWnWvqsmBl8x!Kt(pgTPSDq_Uw@2{_o?-r}n-q|MU~pjSh*` zqdjFA!YwvO#~pcZOWnf7Mn@F8c-`gGOGp>mnAP3U`o#1IL}0F;TE8 zeGTXaZM8*?1FqSh#Vxr9K~bIoBfl%u@%;Be0G!wV#ITImIOdLY zNcaZKE@K_o< zwr$KhX%my^=mESWhsY%qdcOZ(V%Dkyh;sDHIkY5{Gbfyq-Y&b)KL5}4ON63!puRY>E9Xy;)Z>NJ^% zYo_(@$gIET`;jkaW3zo?6O2a@dAgJ^D>JR1+aw@BgzW7(w4*orr-8^gD-2=YJMuo| zO37~>?m_hZPUQ~Wds_(91{i7oJOcgTTr>;_c7I3E4%Dr07NEABUAtdPz zGK*wY3!vBovIhMpK6k?czKCg|gnwo>tC5b*?P+ADDF@eEjQg%oTLRHbHF2NKI_be# zo6L-V-E}AU@_oqx;MM0Gsfp=Ye>)oQ=-el?eq%f7cUY|1_~gW9CUXvu$TQ(6Dl`WW zKWrKQ_-7{Iv@$XV)Yd_EKs*1*SSx+&d@@DN6)u|<*l3Gy1XYm{g}W|)gg+m4p{|j4 zZwlKk4+)nE47S>R<*pX*p6fUF{q27@4+v3-s-Ixi=CQ&Hx!8rui@Ka`zqtRysu=9(k7~YYf8GNk=Ww z#LjYd2}B9IzjFRsC5Zm%z0RiJJsSctBrcCD429G|MXeVGx6XTv#6o4=e9C_%0Hq)*Qk zVR7F>6T}_eUWNh6;(GM6-Fic%-|s&zG<^c$7=3(&j0|}HJ9*Po-1P#C%p5y9Q~(w0 zRI`wPK1TzswWAWkD3195-eN-*IQs(DF(d&6rH zac`zUlnZNcr9h3K3x4#F`JOTg`{EK&Mt>Az0 z{z6wHvB2O$>&{ex)>tj3I%rQTl|P-w&UqvOY@t&6mTh~dMjUES@_fv-2$(2=y~#CQ z7<{e*03DtC;u$K#%)eO~%~_H0qCbjQ4=c9?VOYTVqXgpK7s{OHQ|I;7%o_S|3~!b;e)o+g8cuyZ=tMM zK8muX5BN7^FtE?8o(()G{ksSIp_VZO7X}D@%_jh^9judxOqtVt{P*92;NLNDVb{Oq z)B?C*9_)rgE``!pqY>EkknqlGz)=VF;2#mvYgA2^{+Fbu2!`z#uD?0DJ;rUjFa zy`Dc6`M)Gg27kT>?f-KLQ<#v#B_Ws`FP=9`{SP{}TYj}qcx7)LHxC6mgSxj22knE! z{|1#6(*uDKrtcZvZB+3!Fy%AKh)GF@dM@GG>BeD7{xNgmD|(;D){(RxPo*`eiSKI1 z=a35vg0V$`i$VxI+v=T0Y)>1&7eua1XV@X>^6P&gNxci-8V(=71>>QS0pvYN*kT z2H2}qu6=sy96=noi7G59prKfVcT!;GzbE1#dOQO^{7ww**#NR(0I1MoNN+$iFzs-|uqZwrtx>71wneoVX3#$<~v=sz}5(<9hc(KR$hYp)+}{#ig#^-Qhw z?OW}O-X7N(-e`KmOzucyz2v!byrA5sXIUd}+F3$3In=sQ&|jA_t5Pig1PbUG^t2h-Y@AWAZfu+XMN0lc^xf1UhsS~bjV(L);#D& zE7b*!T5j;7lJN{v96l*8yRyHv>vtx^t{_m7peU5mR*Nr6tWqKD-}w5dIh|P%W<(Y* z)(f8+E!GWj{sw(S!8F}^x9#W^hB)PVF_n{VD!F=YNp+L21_;08d3^V63S>hYa&ah* zt(fGE?-o?Q(=|_O+QtI#V&pp8nXlpo9|ZkANCWa<)Gv*rz5Oc9^ysdOJp<@w(9ytZ zeU-AdD#o0Px2}B!)kS3p%1ln#*II8@apwWghrI-IbP(s+`Zlla*`~o1kQ#yM!RH^AoqqYie$Y=icH$t0wtU41^|aIC!R>4fP2wZ z0fd2P75?!FR~X3a$kx(hi{>Y&$-2Uf<)is zlz?I2wi8Z<+1~jGNO+>*PAFNqkyo`)kj){K`WfP;l zmdG>vWf)^B2e{%}X3+>VO0De^5frg7u8|{Ek%VtEXE0Ga-J&?NO+JC3q^on}+X%u; z99eF*MOQ{n&+vzz|9l@AqG7bK7(&O|`D$Mb|2^5q6F@kN#h{`9#8wpPHxM+B-9FB- z&*X?@Xa$e*!54)A`EwNnys6@|`0QXyVLB-7HT{}x&22Ly$ zWub7c62Y0c2sut^atw=PE~TCqVBP*NLt;EbD9E6K-mZV1?HA zIHeTomp9HxY!d6RHpBxZk@YS>pk!8LVGU<^{`|;;p;;7HNjvxS_Y!<>GoordeGPpxan8t^v#R0;HA8mNN(hYeECk|T2b&_NTeJ+ZQ@ zVO1z3$7xrq9}@BL%xmKdzW-_Ut28%GeYJxXfSnh4P$eC7zgexdMd3#Ksq1ULmGrX+ zK&=(u;N6pqQD-^+a@g6-89wcnvtZHMilSa=s{e*->iah{Xf%6?tu^LbYsK+5UNCui z*)}#HUz$aVxo1yzdC4$;;H(L3X+M)ccc%KRc=l50(&xe1%OpdZsf6rVHC=VXQ&d~y zw6QzCpycz)w0>#57rvsA|S81HS7OFTVDna2I`QFaF-npRjTg%NlQcJ> zwtT+NSmq6l2MW#P<|7kV6w=&qg)~=4H0}4JDP`WSWOiS}RLy!Z>05I+kYN&`E2z@z z*SDF^|JIR=b|OBwDx!Gf=Z3S1BTB`^3&nNH=@BDAEO!*>c}hv+x~I6kwe|KnvTwvo zAh5G*8nZVREkyG_UE(HerDA}2MN{%_Uc~XKXE4DED1D}nEo=kZ%6d?Hc(w&wQaW|IetdXb(U7!Mj`QMFuoBPpmPmUmv(Dt9QTrEK)qjIfX27!fQ+RAnBp4M1EGUUzA6^~ePo zR)@L$N{aBykaI8y;dP|qfr4xbpDO8b{0BQ_jvVl z(B82)k)jF!W>vuu=bku%E_!5>C41S=u9)DV9qbw>VirIm#n zHL`{_a?Nr5E|yA@)zIm<4(r=3F=f;07p^HLTGt{28JfM?*IQJ9WZ2hU_Z3)|MEDP+ zvq=t>dh=a;SRN+7cdt}VM-ZjPtj9(Qy#(Q4HkFdMPmIyGBe~DN{g~8-{47SphQpO- z6_B}V_BW@g3@hwOHZN#X7#X3iR#ao&T7yp-oGH3Sec!)Iz!x|S#&f)>3g z{J5)HYSwhDNBD|XNJpX@Q=8I>>d~m&HvyrfQthmc#t>|Qstx3F=TX&CketmbW$9LI z*0!G37#N@dE_{wkJ@!3fK!;8kE4cjzl4o|{rY~A((NN*#Ttqi!SU+~U5Q#JjxhH36 z2fH^zrOKm%z)B92%DRi(Y7q6DeH^;)+yAUWX{(tNyK$>(A>W*wn`JGri!$DOM-KqU zXwol4RQRf`s%Ld66kL^uouei{>&NXl1r9B{UM;HUY}fvr8&!;ZUf+jvc`I+;h;^^I zPU);iTq6vh^& zHP4l%otnk*p)O)&BP)Hr5A49mNt;?Jrp^gJ>NrEj*>Uod)$z0b4vCqxEV8p}Zpruj z&Jxp3%VObhp#O&pUJb$Tdi#I?bKicCUkH&wX1G$xqb7Yvat$*r^@M;gGJS`!7Mb8u zS`2ccuLi5TAJt7VWa!isDXpo|*>9+!EiLHb~g8|^~kkOQ&MtS{PKqJ;BU*_XN~OL^9_|ahX>`fTnqva z)V`!0y|hs|BcIOTUfI@G6EJvd3gp&&C*!&7=L_E{^^syl8+=T|+MKFUh36T}UB?w; zKiTZ+r(2m;7_O54sE}qFG)HN9G)+6sOwQ9BHb`+i0o4Y@!*qt<%sf|Kztm-^bo{~H zN`yLJlp&cmR_#K)i7K=sC_mJsE{wt4E-@*-5t+GnZF4_<+P`{cXtqDC@jkM#L2tq| zrf%BjFr|EHw9qAusRz+Kv~mZjY2|5OJ?R#i#V6cAFbf2vp3uh4ilSJ!L-HVFK)egy zK~v3^K-S}alO>b-zI_wz=Q+5KwkubfZ-wACcR0rASV_ln$k|p;Iks?YL^792ln_8X zr|xYcs;7QN2rHpZ3+bK9I5Sk1#jQ=t#n`Fnh1n>#%Jh~qdIC7yLN^EE_3r3M%}6Y3 zcH>$Gd9@kV!k6FW8}Nc}8D^O>92W9ka+XEGJyDZg+-uhcx6SLRdS_&87Wa4>Hmp~u zU!2do_Km)E|CWu&Y%QY7xuDz5pZZX6xI96rj|f)Ny+5@f=gWPBu=2MMM^~_#!XIyN zReut~z0s~s%?Rwn0>eN>nfVoG*pBvcMztklPi4F|PU`$&Bv0Hlp_F{M zcBQWMey2;dLp%MkwF}D8>skOR^AoajR)GRbiwD)`}hoKqsI!|(&Ww;e&rQ-pHd zw#E(ZTYY?PQ;*7;$QnB1Ov+vaW(QBIxHC0Udi!}Tq^4&_HHK$fh6iM#l0;I6gcOZ; zBlpcoe0XoZOis(^xK-ThMnM6#wV)>BuGFE|w((}&w~P;fD;EvnH%7!T@VnJJMN{6{ z@{30fZiaVA=%r;fj+}S+ruWD&2e9Pw$2M;6x%ykQ{;n+YY&|mwmW~D%r?q^$6P1)# z^u|2qy);t2qzYAg7FoY*@n&g$TCp*#{i!%^E7LizhtYh_xg8MwMpbUbqB+A-#&(24 za&vJLhL233U-H4IRyy-!Wy{OiMqA%i@;O(e97$Z`O1;gJ46_i}y!ORkxePC4`570teTW1 z>d!jH_h;s6f@FAWj(;C^3W&f$8p9X57D^1Rwlt7daUH1!Y;KMVdLXK((&3~`l>k2p z;-mkx%A8_10*?5?Ly2*@;2D#mbpLWwQ0IF3MQjg6#!j*}lf@+|hYGaJ<8P(;r-nAP z<*UBqYu2e2s(Qszk#W?Y(#U3|rDJzl80VHU5qwm&JW7Vy)v`3AO$tG<0hRv1Cn7gZ zbxxq{OgGCRk}Ne(+mJa^TYnRmI|d%bduVKe^VtWp8xGJ08uB`r+i3Thns(sJ1}Lp+ z?0yrf2AGKfRSjb75vT!1ZgR{18lY@sa!GYnP-yJi2LbL*A8B6sXmqM;f7iQf#aSo; zBemvfyugn1EKEWglp#)Cqx9TAJl*R`biF5xXo>)LOng#hgI3$FU%?&~?Quj94-ydU zBhww7sDU4|d2)GlAARHuvsOjkNJ1Xr#)*T$J=8!}i$<%TpaEr;{v zV1cJ6-1o;2f{~wyY_5-GqY%V)&j;_%P*>mbsV6dD4kZ;{ZFB@_&A)@vQ_t0CRT4tL zY2M9+WL7i9u4^JZ$Mrop^qWJQ^xIA~t!^_{yAq=>UPW3??Ka8<<310jzaH`k#HsW`&dLhsf7R3oW8tWYp6(+^KGGLBw--Tut{QM|2j2a;xu-g7?jDq0USC!;K{X*0`|}peyw(0cic;OFC-U4bUy8(NUeWfYJYkSk zwsV&m%jQ-tWm=)hww@B`i(>#M97f4j`>gg&a$Q+1P;e=Qw1T~PbmVoWq31+ZqGr9W z>qrAM{_)`bvUzrCjn12X8yabiVYcEQSE{GA`%Tp1 zH<%PABoSmPZ`wLFj+-9Sa;cSS5yx!^+CfV|{u0_6rwUcaegKKVtPPFUI#69-HuCr8 z&?pIivH}#+l2EI#XWqS`R|S+qqqEuRl<-|t5=iL?@^eUous_t2KaiRvK`_VplE@j^ zo7o9j4Tei9_r6;y?8t3CwOZ^55)5walfiHB`s&oLG=y%%i3Ie4EN($b&MMzt`a7ix zLh@e8bDgoWHmhf^zB4evZ1^lSy}f;=oqu;vEt>Vj`B@xA6UX$@lK6N80)M2nnP0F8Bc0TJx zw$LwyrXcia-PO{wKZN?}e{vLin%0G&4ER~s+wS@|}*Bq(aPocWt9eJR}@V36H z?yWZOBc9PeHSjkU9i?o{-g+$eBzdJe1@TNXnhB;kGeXEXmD`Z0#w&5`Oba9sFK$C! zap6u-+xfv^z_O>U4?HwWtS@QYbk>{jU}Xu%zTe5%{gG3o)Vn^KbiQ&u+SIt?D%y*+ zYjdp6DPUpDm>=GQb7ug^&k@}0y&&ClF{xBH+BMu+#}RHyQuJierhals*j|AnDk>a{ z)5%C|Du9JEC65_@t?T8v_q4A=qt@HP@qPf=MuSc(2pRO^Fz7qV#P6fAw|Qq$c%h-7 z$rbaOllEG801UkK94i<HZPg<@Q_9eDq&@Hb|HOz9tss>U^c0NO^XMZLRC|i%jTp1hmuhSo=I+9wT(n!^h*ho`x1y5*=aNtz)%8^2%`lFpgh^@uOqV; zceE0TKmJCG->_0wLLEURu=HI+X1!7Q)dnCqXiW5VNb3e>F}7t8)pE&iBG_YB1lpQw zI59r{wS932u0SzkBI-yABkp9-a>?0b=6jeXO((w^iVU>#Aln?&&GXBjBEgMcf{ z=4zx=&w9+Y`SfK{r!v0Gw$JR~inN8B-oK|uu4g0T@b+A@Rp|x{MqsAE@Acq}mb+Y? zl(Pe+xokRG4-Lbj38lL<4x^U*W>9DMsM#S{Z3Rl1V3wTt8-?i&=)Y*g z-Sk}C%yN5^f9K9Oq^$|AcNUBng@391jBg!(pzHVVLvL5l9Cr@RSX5-HVq?sW#1KbS zbQjy&%7YMd2u;IE{%8!O5k(2_&;JlOS;A;(19S$yBymMW$w{Jr6(PX%MW%B!(nYNKP)Xq%gO(K0-QU~;|YerH}YXWzj@-vKCM<2Qchyhzh}@Imj> z_&!rr>o#Y`7@qVr;o<3M^Urgg=ver`>tA-<52_txlN`ktQdddgy81vz!}T%Q^k-D6 zQ&~thQjTCUPQ72twl+rlklqly4f0UKr=GO_?^4;Gr^NDOprYh4B0!yx`J7F2eR$`% z-(>;H**%8aCRRYn^+wPm$Vc*$kEyW~EUY93Ue%3mW7My1e-+RqCUK zkrkC3ReW|kiK!gVCeZZyt#5tE#gk(0|HtpjGHg++#wes z>CW^>T@gFvbGJS!)*H?6az9FKHs2O1O=GWaaC3FdskRzr=rEcXukm;%q7&iIMnv~S z7#=WcOD284L)Oz+UFHK)x9iMH-QYl>>*iTo>~fB@5mQa&GL z(wHu^oA|ZqtL_rT=;z58X||KFBqrPhH@c79l1sK4rUA*pyDW69hmSoB?4}zSZM=7f zUe|{Eu!=<+qOZ=Suq|d#JjliC`B0(1a?^^_=BpxusX_YSIcq4gbv%fen5{H%_A{4n zX*G zhsu?1;AFF?TN@5VeK02a#B?ZsLuVoTWok0Dg-bie*EcWlPoxbhBEM&!x(|(O==L#4 zdAq0W%zyhpxW)GhEhanuX&njIYc96c2iXmNhB`m2k)`*T@6*;lfL_1-V!}wZC&!mD zM3!$f)RlP7^Liv%in{qV3Dss~EJoNXFLQ3(gq@E!VjVnb4T$QTxTLQ!e_(Bw*l7tg zlGxxduyLu+SUfHn)A%~Zlzzi(DdZw0_m<^@1a8U`^2fF#JhCg2srI@(< zlS;O4iHBP2cwc`+EnCv=jn_a+yDJ?m%?T{w1GT<{H?MK)E)Tt<`W~)g8H7v!bzeh@ z%wlC9qgV?ULPFy*Bc6Z6pfT=d_}OEh-fuyQ?0rR6^I)YgIfuvfH6M-!{WHpYi+e02 z_O86ty|-~8mvct&*GE)=h{>$SK_5&f@I1-jnj?I-2|hQsr)-_^(BE`o4|Ym2UE|~k zG(?}{ufbW(+vphi;$quX+ESl9lMdCqskyVgA+SH-_@q2v-r4^~X%KF@yFu*-$X%E7 zhN^;x_n6&qh?w=_8sINx+cQ~hB{dRQH?&E0CJLZN6xh<6beR|FO?50El1P~jGe!=n z;DUWp4$0quFur7^(&3cSGMyh@J(~IwBP@8AZcu%36j&GIjJ4BwgwQSBwcha7S3IMS zza1apN@5PJUq7IDGgeQ3%>tTV+j1VPb^2-F7%^7eizNG(tp#e#fUV0Y?`{Zt6}{EF zdr5LfXB|&iTFm=f1?{2c4cf8Rn4o@e0BaHxKFYZzjCfYYZbyuLCHb^??WR3fQ_RIS zu>9+mTCd)`kPQ}jE`O{}fkrg<$>UDP?Y52d{M?)9>oNu~!j(F?l-R^{-srx4N{a8Z=UGcT7mkZ6 z9ueou3a$4ip3)rM3}vhPXbdC7Zi;ZTZXR{w-t=A#q{r{cGvy_)g-2QD^VJz=ZQioc zD6+1;);N{RQZ9=bi1X`?1rPB6{@tP*v!s`DjTG%SBVw|dS|;2i%eohPO+4^Z^cdkc zq88FOjkO&6*lkGWD$v_$jKb4Ddq`lK+nQw)qw~kOG+?teQRC@9ucu}ogvrPL)M+wJzki2UY=wVwM&>|raJFS(S+4% zrve(IV?;!q#-43x?dqq);;_Uvo2y{ ziiMccIJXvK&19flJf~%tGE@AOMtsJ? zZ4*u^8x&<09E2-+i#j_3^}#kf9)2!|VfBd;UR9BH3Eo>~llEV=4Vxd3(Elp4NHjC) zifA50=vA4-#mP&Vzy6O;J{@_cSP&2tZd0n)OzN^T__!FNb2no0b=Avf0S`9m3|3FD zl&x=9%1S*G{*PyJdBkC}7-${ln8Lh{30qu0G`r@==^)NIW4xFj($;AG}2^hm8yQa}oHHrPiO-yt=8>u;|r8{kbxU2xa@fR}NME`Sn+KiOPNV|H@Y- zMR(z+Vc=8!rsVfK9Fd`U3*0UJ?~`y)0Io20>c$x3iT|bF6A$mh7mO)&dz+D$;RBW| zYuN{mhd&AozGbgbJ1;X;4PjZnuz>%VKdX*6KmyhSAnFGKX7r6vqO#j#zLh+H_w{1H z3lTu8Ko%&JcESDJ@t4h$RKZhdPXg+RxrqBN@07-w9QgE&}##l4e3DiH*w zZ|14<-mlS$L&k)%u4PytW^2X1!?lC`!K}PMQ|K5*SrgZT_>~!fU?$IBfK`l{={410 zD#^4p7?>y0uReQgSkJcTp!MRn(1z#GDKH}k4TlZ=+}QJjbI*!y_DITRJ^a3uW`iYh zUc9S?k2-T$fq7S)Is*r+a3P^FIqOuY)%481mesv7*@7d{bRNN}0HIUx6gr$6=qKR5 zlb7v2D`Kc?G>jLNB^DgDQkuUa-gd7Im&qdCXCS=?N-Gx^4G_@McCTphSoz8z_H;dZe@xU|q(#^^G3u8?FJtMdAa+ATx zr|vesdwDm3S{e)1s1@&G_xIT^Ut_(JPjwbN`O(cDZlJMW&)Pa=-yL-(b`^C)pXW&4 zer^xOqk?oU2{&Of%ih|<$Ax5*W*9C|8T??Qs9Rw?4@9;K)R+vBJhc)%WV+DLi}}}w zedfk+$#=d_g%|07_Z)oBqI)|+O2#GiOtf7Bg3zM6d3mAGpO0QPTmC(|`?|~*mCP@t z-+*StSdA%|Uq0=uuSXI%SKRKz7ss6@V#<&;?zxhIANzZmg!81T#O`t=&WHB0Vv!5;>+weN`@{~v^MY`dhgR9o&Krzv-ZXsutO>UJaY4*oeuQ}9lb=MO zTh<0Y{*CA2b6Tg|#98Ea=TG-7c35VlJ^AYpk2G40bUU`ROX9*or37uCyZCyjs*8QYm`cVhg^!sSOIpJv*i% zYdHu8AsviQ)xYU3z3{D{+fLib^8we#pFk0$9RHF)utmMZS9T@l`}r)Trsw_n!?gpo zROyp^e5^Om*DFl|jsYQKmDiy_jQk1PzInf1)exuYSyaEHI3lzdbit;R?CTxBDXt0Z zaUc5oz<8XAf^4yD*S7}mwKEDog>A5#1e}f6A{^k9n9bn4NB^(oyHe;8$CP|-bk4<3 zQKZ78M%^wfb)RC9LW`A_$>F@@3FJ}EPMOx4a4Y6TiRq(HUn=z2_DhZ9u?1K1y+(9L z&wmh`u5gv_}IeB_9E=@C@A!*!+2WquMKs1D4FV=#OKan;8PG{Jn8)GS+rDo z^pZ#rDp8qXm=$i{!b7P1#=qerls4u&cW`5-C znOuEE(f!Ba*KnYj~I9Pdx8Iykp6(yXHxChB*NO-jvgT1sXgc`ueM8N7_$XE9cz zRQ;)Rl;6mJ{D|)}Qp9Cr(2EiHzEAABF`u2(kSFcDaZ~<7R+7!1xFVKw`?qwM=8b;r zX>vt_xbFWYBIf8?B;Su7&qePV#H4^R)t3Qrp|lJNk5BWj=EV-f{REiXoTZ;t-+?xSn{xs*lkurD1`$ygd8+TNcHlVb!+HG`7(dLISL0V?bc@G z3{q`|U{kAyKZ0D)uzN%_3&Q2&SM<;TA-S^kMy=<=8%Hc`mK4_e#!O}|tzwFT&F#3+ zoi~46xFIrVlQG;FT`4_-aMNasUd}p+Gh&H%D--yP1z)p$A(S8~Ny6oGM4h(qVVl@A z?umL&jcGxY;mqo(Od|m%+vWPowXo}&ZG*M;_UdnN>MCyV#eCXXnysL$JCd!Gq{2Cn zz;nK}?Bt;__rAQ3DlD0e^W@@Jq?#bX>|aYSW`5p4{9v~+m`-msp7|6fsp_mEuwGi| zw}`HP#DEJ~h3+~<_tWtx?wB`1L89b?T8O z*DnlQi0w}wf4z}%HtBVjv@ptNJZB|f`+s}So#0li>0&evq?{nBXc!ISmw-3^_u^pq z{MWveD!BZo=hHpV^v9TWl7^Wv2H#MU0S&kD(~4E8+v}?0Ji7V8hUhGn``i-YiT5S& z5(3FvXlKNGa<+2UZ!$)NuDWHMp6|`t4LXEB>z{A5$kBTk_mU*1630<|*AgzAWao`x z*%7dxJB;gObaY;#!{fR?so|$6>b^BWjKMgzbkkSQ|5@~?jHXhJ-S}Ok?V+aU_lIW> zCO%Cie(flkjG!dOQRF(ZrwiD5JxzJ;6K~j#Krjr~>a-zZS_4u{Q}QrEU(%%IJUS`G zN4GnV-gjt>W0?+W6Pt*u1R2}s`2Scw(sGuz<+n<8se+zF%c0+EV*_OyS@6F`WXHB+ z;PGq9@$R=j)hXD_A)Pa?trp2P{)lh?!Zu0@o!fJ@Ntn?3P8Is;q#!Cxt`_fWYc7sz!?^w9~!~BXqsQdVPJ`S6zfQ{mpS^G=zX+azs2AJ}Bkj@Bi?r2$d zn;-93bTTV3_L;TaJ9%McwSHerga^B?1>rwQ8>ug%&%>T5zb1PSony^Z{#yLpD3izY z*JsZ1ylXJ8`oJ538cBqd*z;@8mL)37hv-uJhq2Xo?k)vTJUM0ROSdKsB#(8BmCA#C zP-vGR^2B~2M>yL6S1(?6UH|Z66Zrqr|QHypM&gzJ5n3_EIVA2MTJLl zG;7-jL8E_CtZoYzPV3N8UO{JLY5zifHXVC9z2Y(djCFTZ9W%@22D7}kda-T}H6{c% zK5V7(uDb=?0=@Kou1H&D!LaX}X}SY#O}!hQLE+5WZf~)lN12C-C`yi78bl4Sr^k0+ z3ji-b8N#z8TyhbCaOnipqW2x;%I#vT9lidpnu;XB@Lj73o=eio-F&0!g`T77>*#|P z%147~908Pv5}Y^{t?&DGAMLx$ zr62J5*)8%DI|Y`WdcVkQSNt)Yq4L}B`hWXRd|DEXLuIT!ccJ}v{a&L%xE@&RE3}`6 z!lrNdC}bYa)5JjSg+Ei#gt~@vX`Qe@9D{?x&G){Wf=`j2*j@se zK?8Mvxzc^hxOb3TdCcmUctf|hDp!BD=X_=vv4XSBy~m(?m{KN!5#nU~tVqo^EVWHk z1plomaj`=`SO0}C`FBdG`EElKMVKWYPW6BncMCGveY;*SD4d}s4qM|+4?_0C+p+@H zC&LfcYq~MHC0AW=-HuE(=V=Xw4(rODM$c9+59s_!;Y7w%O}IZ>hjAdPK4q1@(3>TX z>gf4cz&8Pw%$lYGWgngIgb}dgieN4^E_rI8QSd{!Yb_HW))kBR)H=^K3e?lDoC$#Byt+e2 z5k#Hv6#9+`$L%T z*(%T2pS;0eRAz{N`^#ww)Aw<3!is4+3onlp;suki4jqDDr)TXAmkpD44Of#LBi84@ z_EQ}SI3eFXX(B6f^^Z;-deBE1#0I?kUgI|zaY*;W9ELJ&CJx=WkHkX{Fee`x5JWBY zH|Ca6289=*?D^vdrv|?bv>&`MuzaTnZqoYEN{=CLAHQ<-YMMRxeC6ngLI&Q=7eY1Nyr_93+p>O>J zu{?j@J}Mm!ovXyyo9+wPIaYysTeM>=XwP) zLUu*D_t|h(UD6ib^*73bZ>&?7MgdJ@uz%qs1%N+Mg+HnfKjmOfQW zQn9=382jHviC8S2nfGGvNOV?vkWAqY-Q>4TAB#cfM=KYjYdclLaf_J^hg{p8_ztSAJ)BgV{kXSYDl+yObNuq7d~B`#QvKqoeZpEjfLjBQn0bjS#2)Cw+q`q7*S)sip9oH;k2DSmXk zx#~B6z0WAY*4uQ_iTU<8se{numE#XT8ResAxb(kT#YyPn7CCf9t zlb_JndxkwDnomh>h<@4Uhd$~LdsImOH!(13wP~d`o`S_MpA4yU$MXG2E5X5_Gudn|yRUiE3_bw@uPHe93RB z8OH>rOR%83DBbbt`HeyMcBiG;q?^RWKOYE`Mr)mJwvjCD7*}>puRKo+5q2lrbRrpl zD3kbNyE35ZS&iqab4V;HxZjO#=6NZQ6|@P{x)VFY%EyYToU_|n+Ud$jygjKW7fHA`Ce*?HX2 z7BWk4jjJ8zeHyzGxEAXVsnKYK1u^^anHQY@b59#8ukdn3I&yVLvv0g>0$HN)DogZ( zEHQhuK3P7Gswxt0Bwyb(8>_@1-|Cp4T^nbZiMbE*EZ4HnuF}XS2j)-mi0>(rdk0zE z{xWG*x;PNta{T)^FNGB!j+I?9!K>CnZ;{gSp!_%x`-l7dH`By;!`UU546tnGE0xzx z)*dK|nEzd1BS9!z0p+06v!wZ%O0W@v{W5bo!)h`O8GYh_wB^iwc{IEaWeTx;)(yvc;&Z= zl*$fr4kw6(y;j(pL-G;H{K_#xf*T`o{cCbG|6A3~78Fk9-*ne=(lGGXS@m(24a!v; z1XMXCEq%sPP)1GhANM-41yBZXR7R|hvPL)sgiINo~en8_(H!XvfNkddGy|s`XB&O760T7CGpQpCB3I%`MdjPymidU z9OSfY{{4T9dQ`#$jM`qVr0PrJF#Y9Y_Xl&uB13fbDZ}4CMf+$p&+FF(RZMiQS)M-( zH-*AF7h{?}>(EceTPyv@HpdUU?l9gtJKswWbpk^axTi0%!41w<^qaiLc39RQ9;NI2 zSh;f_maSTWQIMH}v{R^V!n_Et{`N!ZURLXx;}iRzP8oX6DrAD|edeHE*!dspVjp6X zGmp2N7ww)T=}j7KW!c{=QXiLM=dj`b0?Cm5N`ZC#WzWhyZ;>h5FK&{=rUO^du`!9t zoq_q&5?&Mwx+|!GuQ{14>VFm+W>*EXn#v$to(dYY%$LKV^f+E;r;q0L>C=X<6{Af0 z{K9bmYbo}&V#4hqNMMj={|N^6D<5x9pjmA;5++1tPF3ay>^0r^TjXu-oR#Oqz`nd_ zX*!EA(XqM*#tomeKbGJ5y6vyx{xDwgPX;KmHw77hNxmwKPC+`qP!O%ti1Y?gs0Oof z{%HC9D@^e-=Q!VdDIQ_9R;lYfRj~@sxR#V^m|>YwZ82^9=n4-G+;8N>nLhDm(Sa$A zDM?^W)cTYj^_|m~eBhKK+?sOtE?g4WwJ-RI2L=gKbus;mptK!vj*$8G@6D_Q7b4h& zo#sh+?fjZGMZF`N&*I6amy&Vezi~lhI7go3k{sl!3pJrGyY;4$&Ygue&9_FNn#N)u z2jVpMol}HYcY$4zIEDOcBA2O(U>0)+%8u*+ku!60H$DB}s@7n`%JT6n0LKC2o&HWs zyly#}qTowWIx3IxVvRlNLwk>3tLBB*B?zY$U!To_nQXcB%FNtGS>!t+I}fIAM9EdE zW$0Owg&FPKzWEaRS__>@X15P6&UX5MC?I~&L|meuj5zx)F2=LpTrIVy5Tdqyckt^} zeOdK=8L_XbFi#m#)uU@wB7$4X_Xlo)r9wto^WbQnKg2y{cD$D$@19|!T`Er9ZcDIC zN*YV{RNq9{ib}l&N~5AZv5b?FdZW~Xv%jhEeka4&1Jx?$*{yg*Gz+Zl8fhu9!=*BVXSM>VG2C`U(CH_SQXm$?@KO_ z5JZJVgS2!=mne;t(p}Oi&7uWVx;rG5F6l;E=@Jl-Mq<$o-nnq^-~V^cd3Elad*AKH zXY;JN#+q}?5ufjvOLgJ0MTKc>ahx_(&_Wn56PM5&$U6yH+%;HpqV2|)=RJnx*c%Pw zWlTr|mX{PA58;*SFoSU#cg9akIuDUsLyFcEd^Tn+8-qdYMN%)nS?M==t(kHCos?*$ zM3uuzA&E!iqE=sXm6%uj;lhCVg50yIkD-;z*|Z=(K(hNH1zAuokQbaOSBVr|QN1gx z-#WapuLvh-RIOnpQtK^mWG%bbQ(C2v=uN^GR#!d5va-*(l6aDidnR(ev)7~$>#}P7 z-#1fbn5FeAMBM5*s6s;NvffAul-kV~yf#R;QI#_+Ga+@qDDp|e_g{7I6;8GOFXchax-Q(xXRQ53J-(A=z zDKG^$YO9*LoLuC34W1GdkX!yYX`OnE^Y>u?vS=38ue6=D+tRwz6tQZ*m6`-g2!9Y5 zjO*WmP2L?;-Hy?t!66{)v0ZE_@SHAqpe$`1T%f#`P;iK+Iy0`Y4WwM$EmJQ9l2JQ-kt&IWiq7pIfgar+6C`tF`zxE=>rHjBExulHA)l z^bR|#nBy9dzS6jj;_~0kUd7Qo`e+-VR>Z5l+44Ej2=(kny_5>8(b;37Ck2rhkQ{NQ zG4Od9MN`wvlJ40Zyd!IicUGmh*Y(>fJksWF6Vd&X5sLUT{gz900&Q6bVB>hS%wzvl z`jrlHDHv8OSFDGLkDLoRz%iHBXN_P@-6)m$m%=o&LeyH4^hEfnt-P!$i z|EcJOyT|m$Q53!!G)bWR?xts_EGzMD@B9sKO1Byl1berJj(r(KOQSC1@FG>*s?_jx(?GuE<{pFOOd`G5|m|e=cCyZ5K{O>d}P?B<>-~$GM=dy5)r5iK;|hi(NIw&0!JNl z8aZHAGeM=(4_!0H{5b(;X%f$S5@#=_2E&Og8>e=Nq|AWK%2%wd3dPeGpqX@|VBP;?@bpJ=5r5~DA?ysSB7tU zO2{sL&{8FuRi8HhlMnx`SVA+@BC~qIRrl~s9JbjOqIT1KbD&bDM$GFsgs9ily~jB$ z@L{_X#^fQb4m?a9U<txD@yMG9H+opgT*^@i&Q%P3`5z8_^ifNczKGgz0aiQ+9h?$c1 zZTMuY`;KghoED+Qkf(-tz)c8q+3_35tx?;S=&TOq(K;>-M4^5_+H6OPa`A=dG-+TmZUjcy0tP=M@f_0N^^b zH}nn+|5$zUK3#F!-I(E}SSs3Y>>c7Q-1I~yv52Pn@uHz8?}l9M_Wmh9vR&tGB&`O( z1s>m7KwO7v6*rG{%G5~yG4L=Yuie$$K@CS1Ydd~?4dLh+3uzz7(#XoAzUBsbjYd)k zJj^f(j-Of;%<>HQDV+99GK;^C^NAIPWrEXWe@Q~)FRx$M!>`L7hPjSW?w2?Ug{(_$ zrC%n5J#Sc~-iua*+whFm7GgjL93~0dyA=K~TYcS?Z%|gCY)_wVyJDVYW|C4CTAUW&$7|zjbhz>rkx-F#chF!9 z#PW5DWyHbH$Ud zMl9{hJ707{_CH768&%u?5m|Th=qn|lK1T2OH>TYo`v84Zm!mTP#eXv2+b}06j%g_h z+R$wU5>hf6T^eFb7oqsAfa#E7Kq?K5q!h)qmk@7b@R-oh_hUzs?u3jB|u&C0oGM}%f`_&^P2bEKXsmsTD0e4Qs0P+3(a8} z^?n%63?4-NGs%@(v7ZN)7{CAXc8PemOPsEBDKHyv`x3$`_Q$G^Kmv0!IdPXO>}^tjG_U#=W5u~D|Ot~#4<zgkjvJ?mPa0o@i*#hh-2_%0(x!tMKTUztT>;a+*w(*an{c(wKW9Wp zAz6^w{iNrQ_AS5xet}YCT+$DKe`z(mdiyzg^evQB8{!P&;}-hMw#0jCtPuzg$!U1aLDeihH?z+$GL|yf)&l-)CL~ zZS=Nso)h7@)~^Vw;1+%Eg+j>9wRzduB- zNtV&Gy&kwP`Zc8KA(J2fK$#iNOnJqd9t!z<6$Bubx4pEM$n?@Yr12_|T`$Ml7v;OM z{dZ-lOfU;h)KlrIRgvK@qUG#kF^#{yu;7E;U%mOJ#96kAg!eAFAR#j!O3qT<_Z$rJ zb&*k=zu(IH&H736qHo65y%zggA_Frjm4Ch(6^{+3sW5oSW>9N0<~5Ja-1V{kN<-w9 zC}2t^j(YC>e#$+r!yQ-gIA1aK{&6R0wrOwv{rIRskWBw^IR5=zMnD1|Z>iXmFaT3y>o zx=J+I9s0&@zfRs0JZV2o(3dIdJs-0V`Y7@pJ*UT7QrD~`*RvGD(-cG)#|2~m?CEq; zkarq^_J6b!kNKbkv))U*PRQIggJR0P%XHd#5?r95O+nS)S@vmtxfNAzlHr_`YR}cL9 z-CKxD3fvw^)1;fjHs8(RQc?Tj$DDv)G+>0)T^te5KUcaC6r zzATiTb$4C{!r5;uR!xTct!C_(FXptWh`yRCrSV($ZC+Kz8MtF+vE{-t4s@7Xw!SYO zUS6=}+z?u}&dMyfp7oxXm}15h{>NHGB)l0$=9gN~#5P8$#Fkd8J}{5ShKjeN{N8eQ zlUK`yRJl3)qvkiX?QZyV1>ekPjQjM8wFg|^GO9S@{JFwU$K+f{W?#1zUMmiTaP;%8r#dH88e*S!|s5ga2ch&RV@D(-*XOCZYe?vHFNE;#7m2WZ|)0 zOJfVK4V7pIqC*S#$NSxP#5ttVXuB$q(-R?_1PUz<6@LH_mJs%oIk9#A;(HA89-6r4 z!p*ZlBK?b5QY4{eKyqQ9z=a6N#C+(l*o~hodMYO~*v*0ttl1OUa}l=_iS2i7U^D?s za`n|{oI#vQKe2Ayg7%)CecS2ju^!k}DZgfS=f1GVz{MPr5Mbu5vuzqKAL#~+9Zepl zhLrKT=72@DQD?lb$R8&t2K9@2RGpe_%nLjyA$aplm{~9242A2DNzb4r*YtG{Tuy+o z-QjYoa#1Sv(X90L#p%Xz!^1rl<|6I$=3{y5;lp^o?4uDA`j8CHi`vlx`NGVFUC}V| zvM7CCwtjn+!cTnQS5#N|yR;0!b6Z+GcA`YTqJQ@l@MyL+3pZ-H51#%Q-;_l(1D&_# zh0fMeooY3p_`dBcp)|OH*MnuJ#;xh=bVv@lPerRd4o@^2)YbD2E>}h}E0Qq4`^0_6 z0VC&hOs#LkbRXn(QgJw+O>ZpxT|upO??sDRoQiMg>$4gSpLbq*zbjiU>>UmcM8YuX+H+ilG$Ja`&7sM}co3lN)tn)y{@>W@` zWmFs2VKwz$c-;S~RgxPv3lP|fg<-y`TPzh{LXaIG0u=z(j+WqY8h_3#a>sVs0hi)K z4%+B;^1$_*{1NbU#N-LWv|c*d6Q4>+iZ!^S4h+vJpO@ zv$kuZ{(w)JT|4;ix<&;MI2IUzC5<&Qz5f!tyaT#3e%~{_?|Gd7eo==DN$AHORdl6? zMHkVcl@e2q34N|3@TAjk_U>|6YHPhPP7jnwNyvQVqfs^wy(Zr$3#0z@=|Cs$@$VN) z%YQdWj77D5Xb!^xAMm-xegE160MpgTbl(}Dt9jY@0ho3TB7LDgs4(futmi^c(Cq8Aa5Me_CtBw5Dv!t zSS{I;h@$qBDf+W-AKH_S^HF!=^X+59hM~j{}l@b-<@9qVf0KQhx`Gm94lI50*+Rvc1-(Y}^wYnLN9} zw4e$eG(R3oxI$Wj*R@T;5_Wa!joX5LrD+Vm+ph6;{iM)o4*1bYBniyYf1ZeP?Ht+~ zXnR;Y`<&GtSwT4*-1jb*#Y~1CsQHAdN;V^BF4TVD`fWdgvp`6}UCV9X&7M&JGQ zM?o9sM4o1lLmos?^A8AW!ZY*$^2nn1xYFx%daBl{@_|7oa~bYC(;Ax}MtKbW*5co} z%W6c}$EqtIyY=3~SM|(YOzPTvxuA7!z8Yc}Uq>)?MOr(sVgBLq|L$PBCitnOc;24BS8K$ttMA+CvTrrMdX+V%O>X zoNy=vAA3TE2AoTZt)_gxIz(Z4oF-ld_fQ_eb5|LBz1llgXz(QCZ~dkk%wWN6d?A~- zWv9lrarTgst6%QlXax9n_mkRe2Dd1{*4p%0fE{05BZ_%(LP{Vql{2+9>5>I*y3o;e z*dCzwkXNPBP_-iT{^%xtt_Lizf*rsf07kf}s=vVXF)DkOt$_*UP4l zZq?imCH+JJoIOI=6zSfzw|C-S9|eZ!g|E1LBl#QA$gBqkhx>{bqvk;Czv41lO}7nR zMt3p<+@J<`Wz4o*Gt0XIW|cGfXCt0w<6a#)%2V<@UHu=R!%7v?`GS<6Aj_<+zKY10 z&v8+JH79<8c9m#*rk;nJioPrOm2w{)tQvB|5vs3`6D^rQQ+mt*BfjK*D)#9v};?>D25h@K`~?Rcp-D zD!W)XgCK^ly$<4Rg7y<@PQQX1TZteluxSw0!t9Csxi^Tf47cmtOb+%`d;9TR;!b9R zg;zC5fXMmks~meknI|`58S#IY5p$nmP^z-dR;J+JUCakUQu-Ge#7r_6cobho=_GMT ze|jC=DT_`QHL-L5ZlW;1_lyU1i zEj()xMcg$sK01A2$&^x+UMDcye=`9=#M)K{*~LA@Zc-Mm@t7}&i+<*6R=P$I~1hIlUi%VA?W@R*+U zx;-+3_Gcwfe{VmwW*u?+>hf8O0xQ=;3)Gs9(!JeR|M>$%#o$5RlMY6?PU#4|vbk}t z+= zIAGQaA5U^1Y7H{4R;NFCG=I9yOHr$ zQWFSrPp$tXYT(WwUhMC;`{@;eHNL?a3#2bH-cNPI*Bg$pE>}R;G%(~e^Dmf>$m`H? zNd>Mzs65;V&obPse4ZXd92u+|}0J)dU%yD%!0i zZQt$~-E?t|H}W6##UX<6jOcANZZq4_n94baRfIk>`H z%LK_0Y&CpO@3QHJKAiMzl&Z63XZIL`FFJ!_+HrrNms0Tp_^Pje0e_0CUOI!%TD*`c zvJeAQOc;O_XZ}3^Lez>;Srf~A%6co%qT{sdl*qT*Cj?)Dgg7kd zzv~IpNi}Xm)bbhlqh#O~7rq*GVsQU#zObir4Dv7sz}V9rcF6mZBI%x=`g#WIQ(m5s z-{m`W_6hF*1Y!;saKis7Jj8&^@6P?F#E9Y)4=Vrc)p-qj;63|RlW>#ZzL)cOBK${H zz<@x3Cf4=_Wu5@Cu)Jj8dt<=i(=ooGL){&mfDBNq7|aS7(FHP&engqHd zE%39%NGF1%iE%#VODY$!u=6XPVPlo7u_yfOpL`MD>rUNc>meLj#5n-L<}dGkMa<72 zLO%P|2t+g8GTzT~Sw>BaMpu&68=jKz0*KkPI3qjszK?G&}wfD}B zC+(ls68&MbM+5_@k%-8)a$__YmuStWjxhzl`$du!@QO0r6}Gdx(-K5f7dJqe@eD5l zh|@-JlcE$+a7leWjh65KTk2R1Pr45p!nmXyhJZG-tI-BAQSmnLVfNFUKC6YtDgyg| z1i_xI1QJ0E#NJB}0+OOG!a7VvjKpU1Cuyi(3HGWm0JqN99!jmm!@;l+_p zEO{UQ2fPB4pg`mBZ=oZhVm7plD~gdi7awT#5aPXDZimw;ujo|vQm3B{E<}+j_@jLv zjXLo_HQF>S=WhuFC~Z0PQ`>S4T~Q6Lgmz-oe=SaDZ`L}MDj3~ z>8y-*>ebhn?w` z=8!;Q?sfFQd6>|Kn4uJEA?)rMXDs3IykqP;D(l-!nDtOpk(1dYevE-p(lckp9MZsppL6M5Kg zACcArcc8rqS&5D>fQv4NK5{W)oPof6|FEpFYm$VUNk^ttj)rD$G1!~q?oMv;*}Pv- z$`qwU=yAvgiU>zbpRnlkK$*YU8>S7!E>x{=$@tg;aZ%M)7rO53yID*8Q#6m?Zi#7s zb}_cjwHf(*x-Y9=|7>{CzV>~#QviZRgYx6Iur4F_{KpIh4+k3j8_0QQNF>IanK;q9 zt(=l35l`cCi;@2FG(o&@AGj2BAO?rjU1@vTm*aGKLqs|v1&R=UEzZ?nIm*9W6QWhA z8In`@u?I#4@bYfV`dUDRaQ&nCd>UBy*X{+94S~>71U+nAMKR?@Zp$PdmFo?6*;{-$Js3aiO>?E2qoxnJmeVj$p^(jAaO^ zR$imSua0=l(1UyhckZ%&s9V9-{ku~ z3vh0d9+g;HC#^N96w@1GPsHKDMwcm&&w8Mc#?$#Y7J|*m_ykZmuyM!e)9#4K=x01{ z((S~7KIvkYyMti(+`&AF7;oHFtE{GeFnPEM75-3WE?E2X^B8IZ|} zllM3hiG|Qa`J85NkiRl;3F~TzTL6L`IumdgOeAdsZImXLqhzl)^qqJ~r~LZZu(LGv)qV zuYbNpGt3gVfuw5?n6(Ce)yRC(=04L1r`qzk6CqNpe`vYX9Y!`(2Yzu4cPAnj# z1od8amsj{)n~zjsJ}w;7`?2XmMhhg2M5ief3W%?1b? zcLy^*r#c!DOGoQzKtWC0qs}$>>5;Qo05OSp!?FAh-+-YCTbTm)(Z&ROntLpv0KZq^ z;fP$SQXb*GzGDgeW54x^F{23V-pcjsmNG%MgLxjC>AGtF$1T1T(-l1DPtSu#16t+} z<8LY!xU%5udU_>W4Dw7t(!q8iz!AWv_P?FZmQlYIa@*3IJqzSiejEn1uCB<#+?yPO zZva3oxNQIBsij7iO}fCF_I{;hlcw1I9{`>Ts+H_r-y6K(LwaEEPPuvIce|liys~#r zJg#3HXOv<5@w_qH5?M&*XSKl-6nh^D-Ua+=9!V)?(o8h}kOJvK2etUvVYTpE4h5jc zpCrLt1#}&?yUVGk+|CpQf5tz)hhFEG&zPcd0))(%c&5KcA0yk}tJ6<8LR9(tcx>eWfHCApE zI|V5`yJ1VRNAE(Go~cHO?mi*+DsIAQ@EPq!4kNx#|DyIFAsClTvh7gT@Rv=7KLH>X zyX&+i$vdN{!^IB?ggISz=19H77}d4A<6knghOeU6Ix>pXRYCvFuj*i}>@8>gF`R}Yv=2WKbBihHA*Bg>NB zy|nRSA;-4YqM(#x6}Lg93AB%%5XI+_Pe68SvL;?|(Oqe_oG$OPMr~(IBMSV_fc}6&+YPlswWpo?k)@TdS7D>&&mDZqM>!hfYe8I540dg3Va+! zA>}%rB%2WS@x$WBx=FRQGCa8~t624JLidyA=W1hT;!87WJ0Y%5@(Kdy(u@1cRm{kjA4}1M`lY|7!AK;kFn#Q<9`|s!?1a6L7cgOe70M~tl>kDx9&ktRTC8*q(W!= z;$@H#sz2WgpFN)!+_Z95oHmF^8i!1n>m*~ZY1FCo)rcFoXWh*e011S}h=ARhC&?66pIQ%4%SF1dnBsmVa~%IeXzXP-;ZEoB0% zOBGM`dL-vlgK)|@SdzH;gwB}NtwNRscCXksv2 zaN@ydlQ}2kXOYn%0R;~!SeB08NcwTgtgSmWM&NZysZ@3kXBje$c5ouQ}#SWiQ4MenV!a|j+U(_Fwe~+hJnr8`j=)|Ya-3KsB z2q0b23OkJT12BK_TVrXoH5E<3NCAprIY2)5B6VhHB%heq*`YO^*c^^LC?oHY_GO%l zgyr!HcWEv6cz`Hn*kKo!9>tL1+TBQdFK$Y23)vL! z6wAzF+MZ;t5yMc^OShy+c^&3wa*Z^IAPG`DHV;Zn>N`VEV}w3#+}CblR7NTHvOaLW zlcr(cDK(F{e=`EuBbnRx62_-sk#3Ul+~ua0m-W71i$^yvnn{gVidIEN_;SoI@WS)X zZ|;7Hnlg7J{ct4`=E2q@TnR9JYLl5onJ`5q2@+l_WWFbs%eYN^nGvWZL3!lE;vN-xbI%lOOBfs-~Bx3r!=uJ&N|6HpWh!o-;l5j z=#!b52qZ_(?D1Yh6>-R;qIeJw2bESMt=oO1T@>{s_Otm>`DOBrwq+;oJW5@R z=r~w7uHA_6iw6f$SZ|uS7itt3_CCAS_n}Mif{<)G$1AgG2kN4sGl{7nIIr@_Wn=d2 zol@5cF4>JFf{P1jJu&bjS8b{O==QL@YMw`^2HX+D2i!2Gi4{ZjlpiFE*^&9F0Ggl+(~>c4LsZ8cCGd6Bd~1mpsXe?eW<|Zp3qhUJ;`~9MZapEVqjKb>CkYo{HQ2kKwRhCPVE4*SArzNZ*< zzDaZU-|aP&cEP4D>LDKvhvQ%BMS2rfSb-@%W__gim*!x~#mj;0&mH9zKnKPsHaDC- z77LUt&{57)tHqBffnx^`w#7_COw~ty;pn+L*by{9@YDFqsCpa= zx&lNWb=o`NpcW(rhSwKE9q4b7D-^=gZf?}ZD}3NAbajAS{UN%Htw$s&3+~01R%Stc zsrlVjWIlu5^&^+}4L)H;%RQ9#&!vA3_pGR80mbwyy&n4E{43nVB9hQ7`z)tC{owFo zLLMeR(7@Kari*9w@nXdZu#aig7(3&XF*2ka1!4l9+7#)Q#iSg!w%jVtvWc zvx4@SyG|EcvJZoCHwAP;dxEX^hJ_95B$R)!^iwSNZwZn7Ox&n=is^_rcwomu6IcyM zW2ffvfkvS^mEJYVL67oL?10zLdwCSTsDUBX%tT4OF{OU7up&a_@|tHKSyASGxU@*N zvmr0}BcbK$)Y`?aN=2kgu<)!RPM*u_Y2-c${nMm;zs;X-&_?>PKExki7kx6ho{t(a z;{sw*quwpDdocMk$?NXmy3hc>wf5g~&6YeRp#oBVL1V-B0~oQQiI zDmRce=zBe5Rvid5mIJ=A(BDyDlrstJvk62R&!x3#>l*GO*5(;U<)3ow)f$VbP=QiOLQA zjqRud1@ET!aVdK#-}t$l;jhF4Epsa&6h<7UDU7MkKIf9^dWAwZEU51Da2(_Kl^45O z3#}gzVL!RqG{P7lqY7@~1zpv~?5!Z$LGS7L2R;Xa)2yQy6v{wc%$;ZFH=B_C18Tbq4y75jk!fq~=EF zBbkdY!FB3{$k|~wGsoWK@0+$L8Y4g_)mAi4o2r$ev~6rN<=@LIg3HFQ_;1$VYmF+} z>U*y|is!ryRlb11pIIL?o#o}C7pZ=jGNf6Nx! z1ZvfGR#UmYb3xVL%9I%~S`yC-0_u5#wd7jAXR}eENx5)1A_{Z^D&T{Q+smA~2y{ZO z_54HP`!IHB%j~m?5AI312hcaU1j zKGEoLC2t>$1#fk)L}PC0b?T7?7FHQE;7LUI^1BkFd2)<8^WYXWwzK4YCJGaXQXd+q za=!wjze?YUXR@AHg8%Sa9D6a#lFS0e-YsdY?az-306Ic?rrX1cHRs3G52BA-F8W`$ zX^%RV=YC)V1oAPHr_*HUcBNd&(}t4endj+tZN~OD0eKZ%y)@4tw+V(&e|hwjIZP#& z4d-u!EV)ow;p=-a*owTVDr#9#w$_@M1s)G$8u7rUl#9-H=2tSt6eFEz>DSxrh>codCDhY$lE;4wwpq@tqZGUfQ!> zPuTZI%m_~kU|%Z-%mU7CTHB z94Z%-6%>O2autHZ{&zD$d37&v+LoY=y@nHo;pz?8lD|8mrVz!o zM+)gDPveLpa(->ROF&k(Sap0NTwn(3HVA}IvohEdDAqoiY!kF{e){Q7RaX9F@m-{B z2(`q*qnBvz0lhR>bu}sjGB7Z3BO+7sg2ztd8Jven~QQe$w$f0)8nA`LDW|KYL4+ zZAVA8o_<#_`kT>n7*RP#Y-Z3%r~f2%^e6KW*X5K?uk8hT8`7TlP^7WT!k(^u&ut73dF4!IWbO8P)g-bC`?ODZP5w_I@7Dc(#$ILfwYp$7)#lo3z6D%|~@Z2@rp?!-b zNVR!p9#Ll(ciY@DyOQW4zoQ&ULs7D5X-Xk>%OKDv6Ls$BA3(|pKVoTb!0<-pL;oeH z%?iirHi%un1^ZsmfEu^iMFiTE<-p0}0qEBvAxhEK(+Z}vb|dqrVWj!avR8^_sp71DlZZlW6D+0P~# zW~BZGAHp`qTr<6BTL|AUt;eVg$@lVKMR1uF6$U5L8K7yN5wYq&JY+mrfKIQFM&U7T_{;bv;^$a#o4x37%~rRE8x2Q4&5>LKzE^4O zaDjldVNSNL29z0FnLi1oxxr_BKON5^nV{J{?<+FV6Jx`2X~rRKlP1r(>#!Um8{&o> zz__&#(+fqCjLf|{KWgQaytk_KCOq+s$HuR6xj;S>!V&zDe5n`J^~{k+d_7+3$G+lY zbBn`I>!5-jqK_fS&e$^jVk(1)B=MAuE8!g4v*MMK)uKt%E539fVss_GFnOMJ$cwXT3}OVI9lE-BZ%K>;6@nzygUFcCgGa^uQbSqt4~?%@%axoyB z7fR;qn+Bc}MS<{#CFa8{+hg>iDX{i@CN{&R;=M5zX54oX7-iwe2YiVb#1O&J&wh_y z6Y5R>?4P+u_tyDEWn7h%-?HWuG6i0zbWIPx|H$(J9s;!!a*tWn5`8()XGY9Tj8g2% zmSoNe8bJ)Obe6#UtSWGb+*47C-bD88ltR=A*6ATBTliZDQ{CE52P^W$m`)(RD*kN) z3-Wx5Z{$$VE|v;>TA}J7tj)35I$+EDMe5h%dckIuPucJ`YcrsiQfX-^9Ro{ZMRX0F zNy<9|(-r3?qg=<3sNcT&n06ijR*6<2bb;&6Y!i!F>~%de1Ug;Hk_(9bd)zvha#svi z2C@!Z37LW%8xB4Rne}|E)o*-cJq;9qAj3f@OlstHHD*26Tj<6{&US?`Rn<;a1&i)TKd=1p8-A857IrI=bc%#9& z0wy)dZG#wpH1B_-^POqyB5J@~!1hry>*DH&Zu5nwQR9f|d|+h5T?!HR+qU7ozaI!D zRrc1r&1MEVhl@HV8Eg$g4*&scA#m?57c`A(%Aa`!Zx)k55g zr|$5KX9@ohK(y)Cmyus5$209ON5KlBco4L1kMxRo!|NS-dHVMSN;g=ZEeBFZx{>YzW@97Zp1D@ir-9 zu4l{`xbhyo#@A|Idnx}9F&Q&dC3eFHByUt#Wr{R!qgX7a&qA&*mv-%iT(`fN@_>#) zNFaRN_$gm}Q^4iILbrN)Ixx$5kuX=F#eR2{bAq;~2F-*90U}95NxAEc)G|lDE z+yKp5P0w=B_cZVrMgbBzo%08Dtlj-!u4|z8LH(!c7 zlpRMOhuI^#WGn_1Y)dC4>he+tpoQKwzq1yuQ*l)IyC}m&t*k~T-?v`%Nbl(M@?hZl z*TPVGGybJeH~n?-+H}QO^wkBfPRFwMStHv^6~#J`6AGXet38m(QTW3;T8hJF5(ak-Tz4T~ zrCyM1Er=Ao16~3r0!>gF&1!cw{*cWh?e?_?Gbf-X*DlP!nEkkL7%A zT`o1(VcGmftV+1G+M7@BwFbUYSz!| zP#9mmD>Djv=-KuJaS^u{0XB05f1{UW#ahzK4~ZqET9*(HE_O%X{j-~JWMqPl6A8|6 z*&X|M+H#JriJA*7B-F6D>rKzfwCCMCKgx}Y;@O^_&yxwxJbp>Yp}Gk>XhTt5e;G$h zhyP)SIlGzG-*w&T>N5_9Y45@nfOh1i0)mp_#JqnuYI;6AR)aSbHtYmcUJt}Sf(Jk) z{ud#FLL)%kG)0v+jt)t*7?f|mEx06qH~^Z2k_EYbz9CE;6AS$o!J*=dR1tF{TD~{x zmzP#i()t;m+qWdWf||I1cC)96J82S2AY}7X6^j{OHy&fwg%)m{4D|Eyq1ooiQqiQn z*)Pv8UO#Sha`lLHyP*p^kfE*9{%0+rK1!6{1aIQv{GaL%Jm`XMAI@C)`F92~i|N*8 z@NHZSEsNRi+?RUaZmHE+o8kCqs0>-jWijoeouV8iCy+swCBKi9Q*&>5`Xgbd9rrOyNdE4 z7l1vI8#8+>7gHG!=8NMpaXJeS>)#9e!dww-~V?Qy8l4-!7T>1dpgQIP!n2nqN#%yf7x6Ic{B&3@u`X5JLT|_GNMVXp@-Bb>nD>7ku$sGPb%8#QllLREfqmG4zm=e))%{zO4(U zJ$`z~N3iijd2F&GE>B2}ujdi4)QLhoXduU^#S>BIass&#@|1|e>(_fJV>NygTn>6X zo62<*V&7Vy(nVIw5`1V*c!6@?bu>5HY75OCtUr@ZdN~RHQM}W;HD4pwI;4R zPIYDx{?e}a2)9tvT|UuTkA99e2%d!g0EZ?scbj%K6#P$qCp3Y==Bq`A3PoZFfWQGG zu@%5NWCO7%`of*kE%##^eOTF0@ubLfI5$NMylJMZPLG=`PnIr=?*^32_f`d&#W zVYz>jRmiwi!2TwtoZ^Mx49mO@$uZ(uTskY*qLhv~x(XKTs9FB%4Q1JK}am6%pocRiDlxpt3KZdbx$d3Ba zu(O#nRRCEDI+**1v*8qi+paV=7v{L8zxLUU<0wE%>A7qj%bdf5-d;o1KB1~mJsui^ zP$L@b!~;187R*qh!*4)z^o&T86+;=$KWk^oxv$~a837tsgp$9DXtoLqYqqL<>z5AL z&RFLbO-;)eCxMn>kBj|l%?MX8BEoQT_>y4BW;WVp_M?}9Nl5lQpGoDSrl=U^lA&d` zgAgJBsxnWpC~0;T~d5toilSg#L)_Qeb20gh>f;!V*s9DHof=5 zH?*2LZ~(g8_|t+;^YIni#_7=r1M(WmxYmy|lIiLg3Sup3@BQ6T!ytEJS+2?}k7GR0 z(w0u6VCA;;yqpX6;P~F_SFbym{0=+YO#FwvHlgiw+Zt&YpSEI*`LqK%>0>TR_YMnU z4cM9_=4UVjouExiOW>VsA~#xNjHP9)o5~R_lO7z8Oa@QUT%3xYhW%k8PiJtNgF}nx zkOfsZ4mKfMc-|&@_`vhHT8GZJY=_Q2lI>|bgXg+}F_dFME76YGTRk4G^N~)Jk3_qu zNzS5+UM4bozymzHc5`HVlKl0|(<7foFv$vyAW5&TxCj1xo}8hPPYWaFRpzZfOWge_ zi@3G>XSM+$v#ZR7qqVy&UK1oKuiiBZL{WKsG*!!#JZwDZ9uBFbxCt4>Zf zXd0ctL;t7CIeLF25vZY}x@gr0Fn$^jG{T9^FXOF8)x-03N%naf7{V`)4+)63DTaQ^ zVp8awq$Ws`^0r)_#L(sJ8%_H$y!&QyoT9|~kHIKNcvai(h79C^4rKc=9$+Jp=L7SI2Wi`Y9 z^6Rm=L|pz8vz0%h5ys4Jm2=a-#xr=e%;Y*jDdIzsY)D6XV%Z>fQSo=XX~qvWhq5jj zX!Z9?e-2xtOTRWH&)>mn1OU*<|F{9Oc*E-q(TiLqe4DW=LgUYy&bY$JtCww6%K1~O ze-7%(=Zo9j!!9^`b97}572qRV$Bbf7<7x%O76S!I6{GZw=b&LYuVM#l+ep$#v^@J3 zimys(F)f2UlE1q60hwgi{J{Pl^2f}gha$4Ze0tqs!@DH}X$-th)96XUtJfO~vY_*3 zxnlooE-ztZ;|@V-EBy<03tjr`rXbR}Y_mA8?cdhKFLI!~4ip-bA$Pwe1-FDtWV*3q zNAUDr9hRb$g0@D^R^f-5t;SnJaX^z>JIOD>Xs*da5-69c!dqIpR}G5Gf>P-jYWX~1 zz(snQdNzLAP_9uAd1JE2?Y7g-19P!*vx^Dl8j#C~p-27ttojegtsm_qg)mRE@_8gP z2M+|Ct0r*nxTk~~b-LY#e;y_{dq3@tgdV5`9D7}C#I_6{DyZ)%qE1qssY7h5Cyq1C zr=z4D7FX9s?;g0@|4w5Z%55wB>kCn($bsd+EHGjGJQV_p50a&YrH?_Ja1B^JR1a4& zwzp0MPaVE$ySrH25lD;V!sB%_}T=Ar&D6WbHjJ( z5aW>JFZ3D@G+Wt%;$8>wL4%wMHg=qwZoXm9Ix`H=`Kn zI*G$y$#NK4pL1=<65J;kq)FXsE{A>x)SPOL(2U)%f*Ec^{$Kp8D;0b^pT3N% z4kC4ha-FltzY}_GTpAhXS_xUrU zKEXq60EtLXsXerva{J@dwW>Gy@D+urp$r&Hh;1DkEFLNwtglC(C|MXp6ZfhnpNkf(^LT$b5sNXn9!_`zLYs^6J}Z{{dnNO*?&HJy>LZCtn^2RCO+ zoz+S!RUgQr_^%yTAvWP}aDI2V59)LM%1UnyWdIC?6w3cOi`dX+c%5}1n?ZJYk}-#q zW;YlH`A{HiVoC2O+!-vY`V!m8O`YB1LrjeW>a@uC0h@EK(Q>N&l13su6U>rI>Vt>f zdW49&r`F;l)>)i@+IFg79hdSf=^rZV2q5TC69v>T1sh5WEgDwNlimx9 zhR}MDNmAI4n8ZF!>@$o0oxQyQ3nw^Uj^z7)sC(Z5U^(V*^v+lO5P)>z0MF30k3r3Co(|wji)45J;#k`+oW; zDu9}E?b9Lz!o$*GoorZGbp~tU5nV#B+vrq9r-?5jpDZ2R`0cq5YxYcv`O@IWQCq8y z8<8Q%k@Z}*!X5rfkkK(CLg-6+(WXrCC3Qv-Z8*WugBtM=7ZcE4#^Fa#Y%$zTm z92Mv>{-Bwp3psJz^QG#DL4lY|zs@!f?SH71bPIYc0i%t8Df>OhL%d8^6J$_H?SjuX zaY=&ja{SGwlH{9x(&1+vnN^tlj%;E-t`&Tv6BA8&yc@`jr#V=3oB8N7*7`Kj4_m#w zuqh!_-u{5f%`Z|j0AH{5T3TQ?1b zZ=QRjO{WEmdbiL!8Dq>8gnqtzqJLk@IYhc1-MZ<|`OaOfQ@LYSX(Q=Lc*UkL2BE8B zx&V1`2J7{k0ac)m{n;582VZwW(GdgC$L_g=AQFK1i?vESnirzAV8-pmz9Eb;T9=&i(`7~rJt9?*hve$rsZC3 z@-zg$fcBAMQtsLm0u{w((VnglFdO@{E)k@_8-a4D!E#LPe|vZ2n!c~k9QQ7-n_s;UlC0oA;C6@0(30Mu z|I`Dd%=c7>=xpj%@vxKwf)7*RN(@=bDz z-SBwSo4uDtCQNxf>EOB(Xnp-+MPYfRD}(-iRUxmrJMuzN`%>|nedDx@+0AqKDUI}O zCx=w$p;<*>T$Nx&*$Q6~m)I|ki!oi1+_zq)%4b!{!|mNaa7Di#vmf} zkWL(Uze%U%-bk?4WVYh+RS(GNQW#5STzb1@&dOB$J;6AN$95B)*EV;M!pZO=X?^~w z8`CgpIZ$zqus#OpnucYT{sLoZnMr>(;Vjhv*@aRs0W$Kd@n_+#f01GHW$x3$mbIfa zE%N<}MLp$V4410J?u{g#2f@I%ztM0BUYW4_D`Ls*hcS-z@t{G|Fxzdew>Xq-Z6v_O z+Z$I+kuW@9Vv2a!vArdvk$u+DTGO9KRw;L7jJl;;bNc@f3lEPfgJia{jMpNDHBB4P z834a$ZTqksiUlE7HTb%!GwaczKqGiUGn7E$EB9(pQfQwz|Xam`v7ACkyukU_lT&rO+HOe@OorrJw7Z~2$jUBnoz34unRUGiNv$5?j|^B0;S}_ zQy#H7-aAi0Q+qjU>!mTG?;x|`_R9vUodovgk8R&*J_186Qw#>u*MD*%RFKSgcA8iYqq*rOTBgL01F!**SS!yrsWG=>}6*_Wk*@}>erNx*`BU608 zj!mjqP!?&~(bCF&K4_Ikb~x|y7lA>c7f((=q+Pv*wz*xV_e%G>9uaspad`dvh&)6o zKPyTQmC`*cEScZqW8+WpfNO8ZVD_WG?uM;jS7ig|5Ssx^vth=DFFabm9AGz?5wtlF64tu zo^MIL8n=V5TdS8_LlxIVBgs1HPpI!_Ls4%5GsWO5D&?`J4gkeK0bC0jHtCv(-TSg|-K3Pm05FO%($LMlt8Q zDB<@1)Ug}j(P}!trK04na`GH2Nrv)oWAj1k75z=ogV-*ddpW7<)riO4yEDL+twQP%}?_}*;x2PC&kNt&x4yymKuX~A#W8tK`<^%q#{sr1NwaxeLUfJyTvX8Me<6rd;8vwoBPGwJ)MCD><_U-q6GtWsVVLE1A%F zhkotWohi%#dudT?GOv4~x=kV%zl35@7QHW)dvfWC$SGyGfzWQc@TuWZZ^_z`W{K0V z%p!Yg{9!k+NG618`1%w4`2v(&dNBXQUlp@WCO;T-GPVwK#nS2aU)se_S)lw?G#| zsn?l?%R25)7&e=d&N&-MDF4_7GJ*2)-_7nOCd$7j>Xa80)Kfc85*vBngIB8T#tvLA z+Q=nMR^Ck(Ves2(dql4X0E2>Mt7+G z)KCx-Gq73q`pI5sICDhF3qG-&GtGp;M%RDrK$JYkFzl{5Sg4~YjTRTsC|JqGvsQZw zrX4M`re!Q$G!Jw_%DB0|u0xhWL~bH{<8ixJYjZNAkT?6g%a;LQ&taeN=dOWOWIwtm2KZxc zx(t+_AyvJ>Kkj|gNJ6$SW$0j%+D{uK3*+2Qih!gcwfFjsgvxyxaMd2~!jwEd`ECyxm$}hLp>XajX93Oc_>uE53G>51`5o9e!~%b~&9Db!=WG^htWdVl7_9(sh7|Y) zIz(tBzV=_2^so%y+P)Nzmvxnp@XqV8{Sy#lz67U49<}-9SXNFmOBxk;pRdm6^kb$r!uUZ;z=gOke9D)z6=QUtwekHH_w5` zu_aWC^lN5tcx}f&+XyoO$qE3cYVQGj7YP)3uhmRAC9{X-ICkCp>c0A74}L2f|epMi<67g*7O<^Si6l`Q`cKa}HHP0}K5u9Oi1v^60j z6Fk*tgG@|4^o)pIUkles&!N_=WXCIgQI9&=hVN5RjaW zce}sOK#N{PJc~XN2I;BEso}l*pAqSvc_ zL`mzS@YS+m&v%AJ(H-M;ZA`7GH<419i!9Xp1fPaxcLX z<~zmzKGrThz*1&19Qk}i=<8o;g?KPA>-BqwV1UH@{xJJAatVC6EPFJ)QpSKJvq*7G zh4<}Z@YbTU;K=T>b;DmafqfBD0&BP8g8PE+Zh5IKhbamH(eI#H$ZSU5z0N7D{h{H* zCwK&z`1@x?T-FWFLfol<8f?9J3$W=?ISjN2(u;RPGMd88?*Bt&lF|LbFhA=l9GK}> zZKDr#KmAu{a_insZ!S$cGN>VRZBYzr^RY>wk%->fa~{o?-Hh>S)UJiFSJPJagqztU zK(}^>g64zqGIW=lVXH&qor=)N<;+5;!!L=7^7GkEz51 z{-~B+{YuyU>;p9}&8$(v8aicra#buKy6AM0w%HZ6YU05)T@lu(Q}bDY<#NmNnQqO# zl8ElY-F`C;kIaN z!1CTI^{bvLJ=?1}kOeXk!afYTh!US2ch+K>s1q$<93N`vx@+5dIr?4*T3`Lz%zM7N zqLzWZk$QnI<$6KRQUr{SNF%TGnk@;OZ@9=`nQl4I9grE5a|dQ%{&v|f&m`kKN)vFW zhmv8E9+4blIt#d-|GBI?1hcnry-Mb{k+;`_$_#IE;nk;aWF6?sl02&~QU3UwD_K_a z)Hqt^>gk)ni;@8gZSZyv^lOXMT+LokT93y{prrRzX{n=1RTIXH!Pb?hW8uLRqrN_f zS6>ArMsp^#CWJA6Ut6GKBl%seWlHd>tF#4VG~W_Pvq)aELN$+$MuK$*LN`Er0W_p} z+;i7+Qn?lAREM(GG7b+<_qVfc42@cNA8yl&4B3qGc3wgV&`9ya%QtMp@}`uTrR*Vt zEg9^3WmY^L2Bb05rYnUVbOD%d1R^4~iDx%BJd+9TY|S?0f@EfG?+tpkf@>^1!^M-7 z8!rxS@!W2Xer_(_Z<&jPJXsFxm@I6Z@LK}FsLt{jo@9zdu;q2R94AJ5Ih4%j5BdhX zY=>-URY_DM?@rUSrnfs^=D@oGmwlgR$4$Q4!s}QK)*NknV2F>zDY}2;fqueB`Pu~5 z+5tK{(B>cpdAlWCcGSX^q`YbL44wjD@rkpT2h8yu;;|%i{@D#V;^G>ru^)?;WVb6R z+<&z$*by9bdnD@#Uht9M%nJ;7yDm5C8|!ZdPxZHVuN#)=lD#Ntqr^wE&5#{KY-+yE zI3a$rk##b}09q730|F#9JD)p5q#i@uNH(a@=pOTjy5TKG1r5Za)!&xWS+P6zbt_#< z4#2qFN$w@L?60I8wgq_pW8U_{Mt!4rOhU2z)+aUkWe_h%_6Tiq{=13sRwy)!CK{q? z=sHku;N2KGRAqBOHSqoARa$J!qG9j!W3 zI{_418Bl3etmv@YQvL(2YHhKiQM>?_031ns&H!;)|}1X134bi?N*BWdhIn-n-`Q zNXi-K0D>iVh{KW$ydpbJ^WXP)Mzw9-YrlP=Bij;)_2ueL8n9@0FsnA&Rrtd@rAE&n zo7tccjYMnTCOi!BHr)j@TkWQN(@@sdiu|ea295LMF^Ptr*)TMpM4kZT^NICc){&s& zzABFU{eq7ZYVs~zF#Uk@roGYA;iR#RFKv`P)8@Rbf(u3dWNDkZOg6bz6)S%Cgde$Y z&t~F}!`b0zWR(?X>N-IzM4h8*rat0fmML;k5U&jieq$YzvHYB(?aGp?qOaJ&SIhMg z;!28F!hDqVb9Vt|YIwIw5>1w#>-${$oTm9w`ARp5#I#hPabPCgSsY3cfF_w;@4KR_ z&iTLX8Ts57gpTyOJt95I?Br9VTLJ6Wh8escpT$u)-89cpMocE+!bK#I9VXsv63M;?;nB}mOJLGJ$1vNjW4~I+nqB&E##F2$!>d0Z;I~b% z?Q~Ed>TmJ2MdZfqrIMm*4ZuX+I$brYU$k)#HAhbWMJ1t{or~OyE5XY04J%>GaHecJ z)|QCHk}UXVYs3m%NVw82bwNURQ$rZUTLe)y-Q*7H3Al*WYeYh5B=Zz#B=;Qer#Ew# zOv?TJ#pf*SyDZg>CHWTaZ{IHd8MN7}|NVo+u+i`B+}g!2~~FV>kF_Or1YyvmeV*kngX0_#ViT>?RMr4?LtQ06bf1}sn| z1DtewceS-)e!45rSu`G_nO=@$H(-(vi7EP*vtu*f0?JjIugjFy-NHei_z!UZRlWCd z=ogq-WU1sxq(ocClX7eiY0tEgj1O1f~ehk0;b1}L6fXDtGal4=< zxqNH)jiY8iM_de$+-x$AcVozaT5bbTl%*Wdv z*HTrPlUY51AMr<9r8{h3->~7mV)Tr9hLJNWoAzx5&4eLpi3BW3{WD#)bC?YgBRkVj z<4e10njB#_$%`*rZ2Xvl_c;?Xq65QJn4*j1w7R_7!v~kT&vcJy6^}c9WT>7OzqE># zR+1{ydlPV-O~RIe`J=$jx8@UW39>%h;rimVD7S4Q-o9j<{iS`8pn+z`-C(M-ynrBW zhLc;Aa~c7G2EV-S4XbpUu<`1iBS^9RunL`-+x`ZL1&^=V!$!6Y`Q5QwcIpSWzJg$P zhOC7u`#ZmHasdrm_4evtFa#Z0QTnVU4o^!tc+GD!zjk`nK!Cx{tMJrOP0Pt7X$2$I?K(Q{sZ}v{g$M5 zq?$7qUf~7?h;6UuUZ~KKfq=uT$-g_T_ObnN{mDv-awBL{q*CCi^qd@opJ;t@df-bE zot1^Gnse|g&q%5Z$9lo>sl`n_OhFs>qs&4U;QTsGO&hYVN-bED5L{If)-f3L1eIr( zP8q@Zo)T6v<|6k^yS}_g-(cnL=Ctp|yu+R3<*F2BnSg^Y$Bv zw&Z}1Hm+B6FcX=&IA-M@ZVdTS^adYe*LGYpT0dQyyZpDOVUAEbrY9o|cVs>IrcCa2gRK{i0(TyF|}rVsLT&&b-Y33)ifYELs<3Yk)r zZVh%e36_0+Pn(*BVE!XM0Z-iAsqaHd>Mtq4#88&{5Qx_xei(PW`d}jTGno8UxMYV2 zhU(>!^|;=qKRUC~aMl`?Th?axbJ_g9%gl09)wG_Qr)e0VNK6QLWD8}atbQd9LnxJ} zuWj-#t5D-=oKYbXSkJRq*RjV(*s3EMp*>qVLu;x|>+a)*T`{B0re~Rz!^+xJ%wpLo zRttRHGi*MPA^#dkLs9rW;jz^IJ)4fIKHx-4G+H(t4>%6}G*Go3tVB*6?&Gk(y1FXg z6z4)J`qHu&TJuLiD~g=PW%+g~|2QfmU-7Z76R~%9fyL&*b;`AkBc3%6cAUcQG zi2DCXH3wDQhSv<{ac#Ok--14&}=L>zQ0@@q>Gq7v66z%aH3$iFO?Ezs?`&Cz8NLWW4XefCyz*F5Jo0~> z>=d!7IgFpMoHh-p#+vKT=U2KAS!+;y|5#~=0$p$*!Wj8$k{1+;YbtyhJPQ;K2;+|} zb+Vi8;P7o**yzVvm)g5+&fU)l6yt#R;`!h()%9bb|6ifeplbgsw3Wb6ij~~|2u}!8UTK^k#uhf35nLb=qE90pGbrM~G%~%#jf9s#@E#CgPY3c?nhM@e z@cPuF+VNrt_2)zD0|Bg#?lc^zJdL zhITHvxLKo|3ZWjARDCVw@(%q&^Rni6(<@21y7;9_q}93Q>L%Yw%An&ja*jm4W%`z5 z`Y?wzS$s2O-OT=0)s~2cy|nZ#hoql5>E=Li72haqDU&g}ZC0u6miRr&o$Aze%8W-U z1^x7+UURK4hJK4=Wer<@wWju&xDVdzK;_w$UPJ3C{r>#i@M9It+ixllcg3@;o#O9S zf@iM4P>qG!Z_If2c^MT07=B@s0Qi9TD%1I6XYDVUH=2zaczmbjLIMQswCZz2KX*&N zW}RU5Xc&J<4oDr}?moH>$5iWf+#a8)jbTPas=Im>GW;m0u6xFioF2u&#z_VP)P5F0 zL%4&(Lr$86EreM9XW-K+9B@+#pWBBo7|jUFjABl6@jay={>!{eehw=qbJ+mQ*&b)& zOWTE&wfY~WgMl8B&2k6R&fBgun~pdu`lgu-tBqf;9S7*qoh|#Fp6(KYL1%4rR^uZJ^^9`{W)lG{_-?22{RX9HH{E!`6aC986ZUmXnAtT@=+T#xnf7BCAG>SIc!QwX-#)4zDQLI{LbBJE5l zDyr?g^4gCD>$cZn0R;pI6?LZ)=xicc+%ghZaXC?AZUCsa1E7K6 z?R45wP;KjbjoF+kW}w*;Dg3bS6gLHXyR<>)1PihrwXrYd)g!N8Eig4ZtV z*OqMuFt|?DN8cXdOPpFf1pbtO`f_;q$P&9oxcQkvFai5McoL6!N@vPfq9q3VfOsoP zVcD(m6j8h72v5dcT_W|8%euYHQO~fH>3B4QUoPGR*O%^(VS1*gaHQQomJN2v{(Qz_ zx9wRcBh)lu_LF(1uDM3p`Mj?J7K9kcq)Y_F0UfCy1=W0pnD5+IOJ!m~@^($QGW^jc zUIUcseceJqwW@v3vG)H>qqJ14tT+$GmT}NXiUH)y%PLlEMCC*MN>w(*3rX*LR)I9$Uc*QcHvJaOJGNl&$;_&U_w^jZf5V14DKK&E%UKZ-~Xopv&0>B6cd@ zjDkutk9kn%KkR^QD$^6hVIc&;x;FPUEQDyN$3mZAA3s|tj8)0F^4jQ9$?wM88hY&- z1%a2SsbLG=PXAs2vZ$1lZZbi%cYv};Y?v0ntlB>wT>bWcjaq;4nD!A7qg5q7fI`B* zK5Z3er}vv$7m&|kHeg005fcP=Mtv6i+e{Gkl0)QJQ47iMG6q#N{_39 z{?EW`0z2DKid?SDe2PuCHRkaw-XO*&_x1ZU`OeA!LIc1DZu6#$*8w|>{5(&vU319} z^|Lo5{*l>A-O+@6cZ1!kM*b`&rvh7{pLd}(7#4mZY4uq43g+cA8tlq;2BYAHi+`M~ zAb<6Rdg9RIFiQji!>(g7!co7n=Ck7PwF01X-e_Q{_pA&}OEd9g@%;N4qG4cepXUP` z4%&2#j`N6abfiuaas6y^@iyabNK_tHL zI$o*)bDNzQ{fDrE;;n4cMC_Y<_fmhEE9q1X`|Zw%ALimS130grz2MUUP)xE`l9G2U zZfS(u!5ee0>LS~bT5)Drt^!5EH*Fni#Wf6w7{WhCU-&y3eFaAwUj~+yA%mak4F@fU z_&?)c68@NmZ}?yrL18rU3tMf>^z)D&avi6(9x<8pHxX^gmP6@S>Z2;-a1AR@r-H5=w_(|AVjPO9NKu5;(U>3^}K&pd~C{5G(ga7yLk-{ur2G0OlKmzgo=IF zh z8~i3qdbLn!hsC}Noylq(^__*AhrLY6>r(NKAf)k|gNg(mVAwE-EZSz(3E;c`aO`Y2 zdJPhUuiKM0zmu0WKupDBM~ZgFbzF3E-2X#>RcjBb6*DhDrh!ZIs`SBq`*1it$@MH5 za+9l5YShwLkw|A{sF77>Q(D*`fE%RTzABuqr=*mBF+dmsePY2f&PKLLaT_j?yU9Ez zl#FD3CPYQm@Sqr(x3cbX;5pnNQY~Q6EDx`IKZ1n521(98urKT?`d#tilu6`A=r^+m z+}BRnYZ0&&$(o{vT^ijR$23_-czj|7z+GfB&%JrIgs8D=#QQy50XG|bJ_*uR{olPs z>qlRE{y6I@z>x+J&;9QAX^@%4 z?@IA|z!{z(>VuE^U)B)5HytVmZL?r0{yin&LEXN%Ai~A-A*XGi4}+2OB9{O;zY%ee z`+Pi#!k=p|NLV7t2=f`$E<8)H*eE|3pFO=YDEf7jv`IwFn$c9J z%=c&;J&e>qm=px35_>g!~29r z(WF8!PXhq~f7F|&4T?wnYWIHpTN8%;w1D)J@FB<=;k6a#F#8GK5A94z{`@SXb(xWm zFON_0V&Taa$m(36A5=d_kO|>Ap3i=N=FxIsc;~)&KYoyXn>Qac3{`n50*N(FBy5LL zr(+Ew>g$ra(1?^N_hpxG&BnQD6}V^dH#rg%FD%4oy@tNe&`U4b^l)))qALbM2LtaH zeBg`D=c8$_oL3Z8zaOp31}JdI@mF64zx!MGf-1Vviw+V&dhHYBo{AR0S(~0PSzV?IDakn^ zVa|rG4g+W;Zq?%8`4N1?V)tYZB8bY_)<_nhRp2KlP zK!SDnZ%5r4Y&EUl`b8&TdiUA&{1b+}vcs%QJ^sT}cGCxTNo-PB zqNAe8*KM*IS{D1&_s`Fqt;Bdv{StBp5^Mm?fMpHjy27$XB;;y7Y=pawc-&qeCEBeT zR<%oh1&s3eLEpyewaCdX`V0Pt%!2w?F#bE&Z>Gx9gU4|{+hS*OUPDWHX|7{Y_TJ?( zNb9|m-CFHtjp2a~pEfM{R?vR4ArVM-g|we|ifC9bHB0)3Z`ay1m_5!?sYibJJZYG! zmq){s3OkLLe>5x6Ykn@W05qbmc2~v>E-`5SIJ3rSJbFrNlTI$c@<8$PIg9adO(~~< zDo)QH*I}6nBi32_2h-AYd0Gi}S}Lu!5ttdm!LGu~L)Z7FGd%4uF8_6+X9R|I403fu zZzH_cZPs3JBIn8c+SPB}Z~u`9aHJ@GBk`ZE0JCsSSL81;+i0>=rfjtNfB(pNln`AzaMdGb@C^L9md;9eJm15+U;qaE@GX9 zl^&dIs@c=NhV9(w?+5YZ@&Nxg#~?ki)Ae$g6ZnLgiVgZHkK?}W&7D##+WXb_c-99U zr&Hz(cCbtpw8w!jK&o#y;;x!aM7+Z@_rfo0y{ODe1RF!QIM$2R3_2%JeQtI(dW|%&4$K=k%m!9?Pjn;<%i$h0!oT+ z5328tyHxP>Gr(Y+)~&p<`~3zrjoQECKPpC|^O$pva1BEuR-`~-#N13*0Q#{BBqCtg z3=Bgx-^to4o4RgoFl*F4VMrpJV{e|0MiX*a>7lhc`EGq=)3VTrTdZ>?ecC_$!%na# z%!9WKNLkh0YLwB1m|ib99p8@z+Km8FkPN_e?+>I_b+tPH<1Cv6&AcchB{}>G3;BSUtY&UG=!`gEJqBots5?oALXM z@v9)rQ~_oh3-Dx(MqeUtnn6#2q>I#O$$;h%1E(XroqFLlUu0YnG6Q@luX+al;n++@ zv3W@fzxl7S^fDC1M0;U>nG>z-6J(g%P(H9aXmg>8`$Hfc3sk;Kny$>da+eAt0U2YAF`+HdOjOz&swq zR=tGI(VS{I$8u<<+Y`lLW#kuB9l*h5(HnS4i$qp!J5ug+T)fIzJGvy9(Sy`^hiVTt z8$SDCQH}vnLO_~O4Lub5y)7#}Qkce@rPDFtl;?DnJ^W$Px_Bwl;>K&hhA z%8cr=lX_j4^wpTax1tI%>3WZrxw_!r1WZN_>m&6Ki-g_GSi3>fuyiKw{GoL&AbFt^ zq%eJXet7Z2iBrBy?6zlYW7YLjy7Rf;pm;^1y(v*uHLtL!z0?;B`Ub&2lnGyV-hY8)?X0KcDAs_Y8(GQM^rdC)TM?$?O@B~=9eV3D#puX1=!8HwQw| zNSQ5h%2ACyQyG?p zxsfF>sou@xhe{F80_Cau29O{c0<+k-;p(P>jVN`$pHlz)-xpj4Y}P=kS*o+)6b2~f z^P3UhVd)up8!{tRqkWrH+WKBxzU_Wsm0y^9OZ2Z1A9{T$EF{?hnu@B8IEynyP&GR~z$|02N=!}YSbO);fiiG{42>m~F3Zv+0u+`SC#SP-J`^_> zNKQu0`%{Tx^AnFxJsPJi@;o z2@p=O)W(#Z73#<`TRfY7oSx4Fc}ZWKlFyJ({G2&hDw_pZ-ph3Xthzmk&-08SFVb!Q z4V<)DOVr`m*i?P?f*0H0M&jiqcKCMGM6oLd^fs%R`VB|Bpk21Q>yz zZ#sj0F%(S>yGEuj1(Hva>@9yPqMYRt3?fF6qlOQH&#G!x@RGbQzASGMKpXe$}c;~StjNl)$XNuI_?A5PSUARlL)LCP10qLoJ zwmOPi$j5xIk_S>}>T&L6zc6&K8$-Kzy5bXrJg9djPi6Dlg}slPv@3+mY_}@Y8_Z#h z9d+8|`GT+93aD#9Qj(1N=Jc7hF*XlaX3uQ$C4^2UV1x7atR}|tM2S-e04_Q)3uDWD zNeJo<>N=SoH}LGg8wj_1#K$M#uq4wqB?8;Te&4rPgKn(`u6p^aKM|gw5?z!Xlq)X- zdMZZdTy%n*?Rh%KvC4X(fpYnULrGxy9)bDwv2PfK(rs*gL@7H;(^KSui>fdsMADxo z(jias-y2bjoK2jf@|v}nSlYWu2y$-yHtmIs1i7ial7V{F`fQ{E-k($4lkh7)G4n`W zPvYl%tuT<&4wi@pB@1W!9o4Lrl z{9XSR|LV<#$>0|tgDTko^O0|>HL-|#!YS39Msa>D6lT7ogToRa9q^U79a)_>BoJxCzCnNP3c>7)cu=GO!k&NsYhI}r?V)Mlaz*bvf**7cabe5yV zs8m+(t<_qC5j&Zz_1%&Bvs+vYu3ibXg!p1$3r18NBlm12FLJ=gOo4fU%wEMr{=vD@^LT`b&C^3ucpXdWA{yJ9tMq{S`bxtS{^!xb!Z9c@fm5Dh7-z^#k z%A@5K?MRFcvr)}r{YBG+e2o=komz^0XCL1qtB}p z0uP}U7mPZk0#*ok?i?&Yb$o1-Wt9ZcU|LgRFjgT|Wmuc+G#u550JDd!)ORQbLriO5 zcAX44B2z@tFI>LUPVAnLZSy{a7}Kw0q*~jyY5oA+(v1*_q-(_?p1>@&q)fXb@Rq{f z&E;!%>NMvk^5eUbFGV$bjkkjVb>SqE&}leqDh{Z$-gL8Qh;5u1}Q&*%R5` zd=Em$l_6t$fXRdh2Qv5T0{h#k`?N0QfiTTz3Pv+?fbPHV&@SP_kpN z&DtzR$TSIamIWL%h{a^5Tp00m6om)M^_ifzZU5C%FXkFfn z|2>E6I)z3e2^1m`Td9jD#b?g|Kmm)8Bv5U#5Eq0MF5*y&UNjvwr1Eref(rZXy2IgK zmi2>z%1uccuZmX%X%PX<#m6?(j!eCatvw@575=$A*(2vz`2H&X0$<*ogvskU<1#EU zTlxN4ZM=DPce}Ob$YLH);5DZB%jRmwEgj-zY1Vv|x{a{*JZCz5S!XLM!Jmc0IAQ8t zT7kw7W$AS-G`zVQJc>nPo$1K-CrW71N^JVh*FlFh2=H*s)W7bX3yp!(^>%Qnr7N?8 zchvA{uTGYF0EDXMR?LWLHr;Q6XOse4gHk;3%=o_fRD+}F=g5)e+Bs*&2F=3;=_3Ni zZGzqeFx5!S0)i9MCfVs{RWs(J#Z1ZA^^8JW6N4ZU{W2)H7rZ8B+S^eNxc1i%@($%fYT!ABB4)r;M*{=ANNbLY1B{IPdAL<%KO;L@y+^cUL^R$0r3^9Oi%ChAZ+nP$*;Z7FNWe!-A+}BLV zQRb}FFHNAOgz(DFm9nUrGQJ!Ad~zeIF}}-+D$iEjK!^AO!3MRhjiQ*MUcKrmCK01)_iv*woNSHJi!Ng2iqS) zT|vdm-5OCyJ4Rwr^Tl2J_^k@4QXg+Es?t9KpS@-m&X*Sj7ZMe&_&_YfmS&U^^~b=w zudX_(wbVcK1R#om6bS~Ls`*Cinb@ZXL#d!AN@eCl-Gis?-@gWCK6QKS+45g<`!{CKVU;y3#5-C6) zRpG!h^OtKly~q>yDLugc5b8!_m{SPz>{udRKeatC&|IhdEl?#p3%|$;l4jAa9}Omf ze&2h>7&2>cWoV}o0D-ri4J#8T>KFWs9}X@<>z!^N@*6ZqRN@AhmIG2Cr=Ce;tx3o# zD(Ygfk0RxJ0Jkq%XcY(P!y8OY;!A)kM>ZB$VK_*r=ccPbvIRb84#W`c}pgX5HJVU&tT=nh{bz1FqoX9&ZI1TC- z(AolpX$#ASv?5AQ$|03}4)Fj(jMVTPWtl#lnbt*+iJ;~vrJELO1sJ-0d8u!GfZq8G z*L>mSv(!`5U0ZMT)QnFg6iXXDoiUE7yh`HHW*nt=5A`XLC4LW43(Scx#C@L%a%Tbq zYMzang)Xvn1|O5%m_u>m$&tD0V`Nv_2) z&LMEFF=qk0^_7;zfujF)1gKu6*;6s_*c3u4B*)q<%8bCRB%%Fm#muMt#F;xI&m%H%e$xt&; zpJQP7-GR8=Q-IrcIAr8>YBBsEtQbYGq#Rgi^EzQTOWw)5J|M~k0&1gxaufHScm{zN z6L#vx-MVS{DWn2R=Qh+)vQeMs>*vs>#+j_(iY#=10+|hsm!2*WxO(ONjYwwSoMo>A zgyWA|+kRHFB5L3y)#`cERiE}=8#@4Ne=1x3y3J~S_Dwv7Cx@9;we|Jvzwj9n)qG@O zf=%}w$r9-cT}n!PiYJGxB`cEtJ?x(`rRBt@3Q3>?Cv)lS6pZ z1=*;BRO+>Dl)x0h#zJu@*9x*yEh=5?qlR!iRQ8M(w{A1n@uFu3Rd2nu0h zM7v>d5@0mz$-Xq8l7j!f`c#ZdYGWN<(0xu>GWk$Pw)I#YG|HNEdyX7b3%@8V*!UUp z<^6Fie~dYbLoO@K=%S!LqL1@9m-|ki4;6r#SlJqa!F!XL@xJeG=5SSLcGhSf4>N%H z1MlCehM`|BMF-qvwVtb=?1F=;fB57qk}H$?D<$%X)O#Fw{ci}cuf3&hswE7Vq3&Qd z&DUAZ@-hTG-;nDtVE9-4iSB9-Q4$7p45yE34Xwb^n9`T*Z@xhy3aV!bS_%#gpse57N+b(Bzjb3(L1a%^3}&M7#NQF;u`rC z_)zO~DdHZe{J8;2*0v3RbVOE?Af=%M!~IID{&E25)kr>>2I_6`Wbwl`hV*ytqSpsB zWr1vn(B`X8n)U!WFfxBGS|p$s``hvGvC_@@UFPlitwm3G)5tIF16criC(I{fPJlt% zH;py3v&EJ_NAb4c3($qC55mScVBCzjkF1nww^G>OLH%(R(FpuzWr}U54MC5?mg=aR zqie&F;5bX%YglC*AKUg%1*(%<0J_&2Qt6DciO@Z=U^8rfUaVU~2b_ivrvO@g^h1;J z;Ol}ec7DY#Zts%~_n>N&^p5oU!p(BVQ*d-Cq}fp$yg$FG)q0i+y8Q!`9_g;UDm?8816kU{Yl;>?Y{-uABCOfw!7 z0WuSDB)2{PxjO9IPhrn-l`MQW78MVKob0=)18WV&(;=of*Ky2K+RHfhr^+CaX%|r6 z>MfGY1NvPoF~0@>pAxk=OjN;c1yO=Up$Nf+y1@)#UC+MC%6kBOj}HqG+*aKLdwlIC z-MOOXcsqJT$Z;uk3A9xns#k)+vyZi9#JLxK1cqfLL#sf6q}EX^oxNavJqCyGYgw|h zw>VrL|BJe>jH>eQ+9Z@t>6QjTx?7Nv?vRw0?k*{n5-Cx-OIo^-MjA=!4(U47{0{nm z;$1WIan_oTF7=#q?|b*&*R{9v7fMbfWX9b*=PvgQPI^}0M;(0*V$2Y?Wr6_K#;mu& zJ-<9)hu;@cM<5+#{ceMKj3UhI=e&BCuVvNVcj=c_VbR!NlV?Hjf&OvBU{NE7y15-z z;qHfd0OmyW$5b~9sdJbwt=N43OaE^#o0xDsBk)b(?8b--^+L^^b5i6-MUwVn zkJUX|wp#f46#`9?xC&k3>(NCkrx`;g@R?wmq%>ED>WP5j-%#@<33-SOR|pMcv}p zCm6Vdsx7q4Ia-o4)=Ny9{-$B?S^(&~CH!+5`W+}papfU{9!Tr5AF1d-ohlzf-bvK7Kq>z308W5c%WA+rQH=DSKNGAj5uE!lrZ;OPK;B z5~JXCscj)lj#if-0CA2x@qlY6DJgdIrpzw4n^6S)zfZ5A5ZRGi->@wAg_l@2J4^He z`!}oU9tD+AI2Y>;-z^pcX+Lqy{|nm{m&WhQqF7pWeEB3vT7L^x_tW?97jt!TvKKer zn9Fkd|ITZ>1Gj>Ze4ATp?=q@Ihu*yDZ4&?04wLKC?%FTGlRw@- zFQ#lnKXoim6yv72sUU&?yKwKjn>tPuk4l(aHp7Ew+IAabp79!?J{t%b{TN$KP?$1h zhZH^DL+|hG43j*>`sGDPB%T*8G{pQ2SNma*E_gv(lVS8hFjLj#5r{15LcKb3U^NLs z(3(}x`MT$}eM_&D`pu@bI7;?&dGD8qkU@%HhwGh)Y!?Y<4etIX(=cg1leqB&%)Q?O z=BFakxP%R6^7mj69@sZtD!xLUxQ2qbQdnKH5$6C~bk2bZiNw!&xjnh=Q|^widsk2l zJ26OhrRs)|2CLCiuWr%YA1KnCyyMVOdss^6254>8PhS?W3VF(XI#kSofxknWk($R0 z>dw5G)c*Ermjvt%=4K_?iuJewyU>)DicgPWRAI)amEa`j7Xi0^Q+_>277S5bjz-c;*q+ggdhu z^9+8#yDxffH}~s$P?6b84cFnpUGap|eQ^Rn%efHET1?kQ=M>QrSiFRVKG{hCm#6o? zLdzHbnImva#zYyhx2`Z-?4Xs*Vl3g8)IOOeMBfk2zLh@m<}-;kZdthDM27b?+&~BL z!4F%O<|J4gWMCIuTMHVDTp?@DyEESwDkgj4Rh*7Sda_Gxhq#`c|a^m#E-^@a$g|>jF z8B}^shZZD6wC?;wjKP@NRN(V8La;nyeir%9_lB?yZQw3a z9@3ZFMgW%1Z>h(d&?Wy76pP$QbFEuQuNM zBWd?W$sp^xVC*$!Yq6NbeVx^Kg59jRLob1dv08KV$ z&THR%b11$M&n%(O&dc!RK9A{uC0%Ud@pUU4g)DNmvPxu;ArteW)t5!sb`7{^0k_@- z_}k4E>V*?Xhku?5l!^nxi@P_xm_T*X z477Im3WRtC&Bfm|HewU;8&X$`uSs22)?Rs{N7fk+rNa069(1aQk-Vof`K)}IC1^k~ z%+P?)@+i$`NFtG7H#%;~)0>Pt`g~_@a@+gW2Raw8fYf}grPX)4tRg!1n$!b3(M{pb z;@T~uQ90hU8}LLOYFX^*AKeJYtw_LFkg}yXFjKf!q;jxuk;#mbPuA-{UOu|}xtU%18tRHL z7zu-cCTaQ(R@6dP1pa8!wxwX8%g=(EEF%_^_C=aG3-6ThC(c32W??4=3^sp2R4-PJ zQZZaQf3viQy6hqjUu02A!MD8X+!)!OAbFIXXQs81KDG&m6TuPG$|2)Q9;8ZU$M88q z7Nl*zJ$%KIoi|weH0FJegfaCE%CZeZ8w3iOvxfj-dX#6dA|{^?n=p34n;p65*!Rxa zTr8xz$H%jMbOd!nFtIL?OgW@b&UO7N(z-^~Ezxfah>X%H)5eV}M5*r@yPHQaBt z;J49nk%F`#DE0<7*<)iDPSOkhQKWJLt**#Y=X+~1+W!_o zZ#}DkSN8t7K<05qVHq|D*$*3d@m#1M`uW!jac;$S^DpBflm4(NX*=@73H_?Eeh%D_ z)EFqJcxSL|vl#2$H_KrxCpOSVC?*e~>63+u^sJRwgXMCkoA7n$NuQcwg{H!G<7*c? ztolC!3o$VN8qN0+B>iMyR;)e14OlVB_cg|NK4x}3%NubSf2*Y!5D+cV#IZ;|s)9SN zXKMl!he&)wNwfRQLsHg099rN6tfm8seTJw@8y6p-5m8*zZ0_hAl@>Pso+@7+d#ndk zC?HmZ$Rc4Obok!37X2?zUqKO71o)l`Nq@7Vl_?$^*0YOk2iepz$F1dwan9xEgucGi zi!_8dyfa9Ax#K<6S^pc+>^GkD-yDO5VtMT{RVGixrIy_7?9vga2JMac<3ck_n3L5F z=I!Wbn-+TtWm1N)7>a)1ktLtIxpWFy3T9N+_?_ybepm~s85%GoX zM@7sZ`RGhL>cwJA;&NjML{`9m*P6u6>Y_K+=5bq{UC|`f;0GIE<4yYW>wh(=cgLfW zZze|ih&T~0?N1bov#k>XgblD45X+LbtEb0!YL5hjVdO}2f|w=`BVCod1t%}z12s}H zmS^f!%*F63SSFJ8)BKy+-x1iBVBB3DX=t>n+zMMbY93R5%rA z8c8IiB-;Tyejo=&u;!*(UI zk}2UWqECN+>0<6VVu}Vz0#7n~d;ukWX=5vrlzo=>eW(d%Ne)v~qE(SnEOiu64AWeq zz$pBx(L;ku-_dafU`J#uW4E_@=ca_lA~bs$1N~crTZ)=g0-{rb&b;j zE>U1(ue^=Z)K>?E(k9@)6T!`^(EJ6-Eoot1<4*@|OLYLH9aSg~5zqdc;q1@5Mm!W# z@*B*&t&O_Zm*`>JyayN}k-q@$Dsuy&CGI+{M&S8^L}CVqbC5vapCSa&Cxn!5vokx> zsO3}j2v8RrWB8N3J3Xf#f95`xGG*rqBBD|KV{Sk;hj7Y+Ye`euC3!6}iEBMEI0aYR ziZ50;iQqGi^YT|*4*|Wa>SU{NX7ypOyMl^m+o2A}VCEo99-_=u@z?{Od}?7azYN$Z zrBYiiYmo&kd)iw6p&Pucx6p!v0v-WD$Fn6#`!c+l645v8b*%ODGPu;KoJG!mLn~ z?W$|WHRjA9=$AJHm9abjyehD0A903+Qwg9V@s48DCd_Yh)f2OpnH`_S{aR(T*F2j? zi#}D|@&!xyA%=rKbS95oZgE{3iJ8rw=UM+@vV>XiNxX3rgbWJNZ@%F%2z!l%#!2 z`Z5ivW_uggUSb#`us9<`eYQec_0mN-#24cQG5pk9avj1HUC zYSdcIg!c$5Sr-Gdc*=!;6=ebe8@>hj%O^0lE8E)*Hj{<-P3A8~Zfj0sEcR){!Q$x)@s715OpOUW;X-yJGL(6v%IxUZqM8AlPMjeROw<^}<`hy(tus54)Vr1p z6APOXZC1b}43k=Ux`?omzCwH<8j$EBFK$NEruASFutVQB8DSd3tp#Q00}7e8Rp0uA zt*Gcz09;R+?$!h@G6~G(lUX-;b@l-0UXO<;`x%zW8>aoptTh)Q7~A0TXDJSssvm+M z@qmgKh!=)(OhsDwf$OT$CIsCDa+-~~sFS0Rrp;zkvs3DbJc^ zG>L|_o;Fe*gSw?TJ*W@z2&r$ip{=H|>R02Q`lfy>4d(Zp)1)|0Wzaa0M-^8SJvMiA++@+K53smw*UF$S$11f1bX!wD-vb1Q35JxtEFLv zDsrevA_~Z8uyAt^-WAxbALOi?GVL3EoFk)+(OM=3t3-aaTF{x|dju?}Z;?_P8U{p1 zDI~$nz~ztbgrK7htP!2C(6XZf3l1-XRZJ21;`Ev>iR&`bgOz=kjgqa!q<}Q}sK>*F z_?Vb=7_2UB5*_04-iq(=zuPSYt$}!GYXFXnrnyTVuuxve@n|A%S$qU-Zspv@^o|ba z9&4IUac%T(L}rSgxaJ`m={!jgHqSxs?{c*Bo}b0Bf*{w+r>nYG)?~Tf<^ISTZIneeEP3pIa7VW@hwKZHSFR_@)$V=+McE{ zy$vo|5X)QO-hw|SV3xCCx!Eo0(4h0Byl+oyzN9&90_{|o;UOJ78^K}6NkHO$sgo;; zaat^#5nJYA&4^Rjeo#Wr2WB`c4@T*!Wqqe7b~WJb^}&f1LW zA)Qc7ub=fFx(hOu#+NjZr`^Q!d1p1to#3g0tG8ZjyUA!U*nF^)sH8IqKH<_%1TYL& z0CJ2vA79EoZFMYIPkFVLIfUPD?r`)yX_dd+Ng@nq^aU6Y{z6E0{LxED8QD?)9EtL4 z5H8PpV@)dx{a3_f_s{P2rdudXjST@u=BduzXHA-XlwSeu;i&DRX~YM%G8SxcnVrWW z=nG@aGUpHTdcZfqfj@D3b(We+BPD3o&0eYQ?F zs7mC1+;@*@L9BH9WiB_~Ix>;yUuQS{X!QO4p!9xNMUEDgOvdl^%BOJ$N;k-D%`;kx zu%+^^e*lI^|6kK;3SB@O&q-q&#S60hZu|2Tzv^xpP6hvrFN3jE@lZ$}?t-oA6VQy$ z0<@W?A=v)^2W${@K#0d+vs&id-Mrayd*d+x8lSpLB6GEVOi|qj&{>&{7yM*Nwd75z zkH}!ZMXGP$@;xslbSn5*d8+4Mz#tE*+vOg|5dg6GX5+(mw0HQN6jr+~-PQ}$!oLx# zbVf`BjYy!7T4@$&)8FxGHURdL>ecyBdo?b!dcZ+RxJCeN?Nbs%2Agas0O=#aSnkm7 zHzw`B{~JZGnWD9HY7vJ|)~kdJL+JmMSa(|KZ4ax8K{}3*JVZBV%=br<3_Z zS^oC2p1bb?RiM06T9rz?l|Hz-ce(wtzub~i5{-h~(?_fd ztbz222~K$L`iKE=SWxLU*g3nbpVWCA zHTy5r6gZIHz0XpN_I2mb1#QYkypG_TE76-wa1B)Ze6v8_-`DM<+iKF^HFBT;@4>ni z=Ek7@3%Y6O7;UF2D)LKp&hv035gjsnix?isL5XrztB*k;w5|~q z!{f|KUA$BeFsD+L7DJJMOBbvA>WC>e3y|nM?~cAP>ZB}CE$MSAy&19uj&9@&=X_*n z^MMnW<-uFafvJL#xw`O7zz(~fE9l}C=+`aD^kG;LfV+6gMV(fI&9VX?*W3L{s4Z#Y zdZot&mP`&S2R-edUGM5x{ah9Hqc{qrJ!Jp|+HGN-kA(~pt8krSac`X+EV?J{%>gHSW)0kdx?pg4;U- z-9<;otDjBd_^GHH{^d5?i^CcFnFIztonB``k7qVLd@k3Pzp3kq8rHs=Cj4E!5Dn#W zFZYG6Ufki^hE0gY<~3Rg=ON%2A@M=HkVnmTEdZ}+^TGjk%FrU*t?BRiI{VIteF;Ss zi#Nhh%1-%5Zv~-nUgymdxSOa$Fm)D_k3CECtM95{PxlR|4Zzcf)X@ZmMMMmymP?M@ zQ_?2n)Lg>+!Ri2F4RED(Qit>H!m{IoEztPJxiV&rdUxA+Cz^l`UHXlW>RoIh_oFKB zC`2MM=r%2vPv+Ztm>E)aHdQ>{Fq0tDkvJVyy6)KZcY!TXm||RZw+nIR zj_ps(kgj*7txi;-W)Of3Qh3J?hL4en-}^7hA`H88lAwD`(a6adn7uV&EdWLHoan7K zXa!IxJ?9=0x)Ogi3+|F!N5}{!E?}=-f+b3vFMfZqHm59Qy5?iKdj+i5v2-oQon{|! ze4!gNQqs|>@^nY})QA|Q?;bv|3j2yJAhO`3f&W&B!+^9q;;AVe>CgqVICVXqn4GUz zMouwEUvLDBE{Cs2<9Lg&ERacde%ig5Zkko;{?I~4x=%L5Z?ri49YH)2muh%@v%)r@ z%%tQcK&Ru`^~|jQ@jEi^0bsCtU`0ufY0G;I5Krv+Ro&GvpwmQc)1#)dsIIO^2NlNm zcNVQrU`&F1Zveo~WSVHPNWAOPH_-nL*x;h6#v*p{km&+gyE+28HtJ&3d#_)rt zYt^LkM&Hms3|boRds!enjWfE6tA_Q;yjzdpPh!Hc`}R#5K8+-G>Qzz1eCCo`N#7gq z9*rj+UB$gTN2>FNrAA19pRwFo+JY<*&^lev#V~O!iawtu{IH=q+&e>@*Yu+Gtg@qDH1f~CwQ|HvYh^V;i@yf1C6IQIpG(L_rIgWQv8dM#AV6MiXt*1G=HO zyaDHs433W+7*p+|=6#+)=y@mdfLkxmmS({xR%FX!vgD?~AdJ!_xL!=P889+X0LLViNb$e7(AhOt`ViPBCjvQV(PGBxXXz#&l%KJcDmgefn z0NI>I%xetj&qpHpRQy7eTANI{>Qz445tB%D@utILdPr>x#-!LqY!Tr+=+mm#D%Cv+ z7kW>0YwJ>rkoW6;%q15RqR2YDKSgT;1qwdGP(jHDg~clnH1m^BY7pwPI!7e6dw=BQ@sb~=4H-wX~8HL~KH0Hwej zIW5WVC_JS(*W?mp22#$?4t(?A`ODM|?TT7e;%2(i)7o6&WRTeSJ71GJQ&33ffSq)s z{&$yTvlw6l-%@`8>0;D=c}Re#diOa6v-Z>$$wM3mqTB_mEVFN5aYxb{I z!Z~2@s&420luvR67>cXfY0ZMs_ZlPwV8&x5DF6uXqZ3#Dh~sj&NR$h=(d;`kQJ;fP zV8zI(J&yiutLVGNu$|gIW%(~6Om&#menw6OwluEDBs~_zgfY@+@V<`}u|M^+k36kr z9so3e-B+o^6eg&YZI2)3erWH~GTeJn5@@0W=%?Z_J1O}3t zTE|D>$YX1TBNfEUwW>(2bj|nfTF!W7C0dKNrNjUIA$2UhO%EP1#x<)2 z#FQbCfOb45b;-_qLzWVf!lSEMt|~L5zEsPXLVvG6Qd43nP;%|>Ep7b2LylW$CP8l) z;&;Ti@Zp~tL>TIYjNmL0&b9kWJM??@m_Cu3A>)H3{%TyAhLwdh#gHpSeDrV;2#p!$ z9odXjcb&&!-eLAo*{ih~_1f!g{Rh>OpLUK&DcbWw8^c7{voXq!Os})I3a;?6Ri|24 z$)aeMOvGk}M-t9nGYkc#Jp;r59D|YQiZ0MznUfg;|M3G5e&hbIHDY$^Pka$CXAZ|Ih0Z zPkoap{`F4>mh3~VWvZ+C>h^}6@ogMr2ErT(!I(~SAuO!Jwh{gvobaKl$Go-F# z?{$;Xgc9%{5&r?x$k2;*bP1O&a`xStbQH^#I$L z{K(j#JuWTep!P1oaqV45Qsc)*yb7B_6=K4R7lED_H9eL@K~c2B-fLQNxhM{mp_dBG zx8QuZ1!W{0B|1r$N08TNdb^Z&{&}re06<;yIL6nwZ(u-#zM!v+GBWVM;G153;4kN<%58ACaDQ6Rrgp$+JM&W03ts?1R>dZY zwHX}EVp2Olb%3najbF9B%`g+wXp_j%LV*s)I{m1gJvZ?e?gw6rT(mwJ}6; zzqO6oI2}gnK&U-Yv+sim6mfah3)9#z&}}v)M&WUgalp>AXdLK)y-wu8+2fMtM|-$c z#76hYg_NME8wMXL_;N17#%8vww<wR(3jaPmfqDs{@ zpsWNXFv9WDEzW4wko$ugnJ+z7cQnJS!hNh zmw48x)ykbJAk6jh`wz~8C&NN$!`dcyaJT46QAHoZoKPqI9xJ60@jV^RC{^Rw`DtHm%4IDIq4Cr54U*kFg8S8l zKv-NcgI$Y80x`!WeDN*fc@(W)TG3c#`rmZZ1&+&R4)G8r;?4eh=MN9@S&KBk%Iafp zcjS-YyyA79#BfRKq{4qaI?S=x$)6yfB;<-Uf;nl^<6}r#L?p1g^&I2Q|JduWr2Hhc z=cNZcSa&0ZE!I8^jQR!^*(hNa2Y$imv#u^3TH;hwI{mIl}xN)pi*1eB8S`Xx+bI=Yx$9-Tkp zpBttg19SRK9v;wR2%)uh0B4QO`B~d!sO&Y^(=kLK`9qZ`ty6_-761K^;UZa!L&>M_ zkZ*?@Fhc?^V8KW^AT3CHvOp7@w^x*F<--Xa+TX2Lr0}(~P0HF6M6jD2XS1Kme zDpqk{)2q}Vx)lFc%bkPIDwRFEVX(nwKNo2eALR6q&;LQ`3AZjciibn`oQLQMD&Yo} z2~diex<*2ix0QjdnYllX-^BiD>Wn@eE~9K6-1}6{N)t}bJoQapXYpx3NZ7MHcP4Ol zI}x$#(pmT&v)fAl?r$7kNx&wTJ=-UD-wKn-ljsPAYxrh9!fC#nt!jYu9aC?^s)VPr zeRS<>pwZi0g@jU%g%|XvBetkFc1(X87bzI%Bt(m^RVokK;y((cjAJyuT1969^<=pz zP3^<)b4N?gvB-={HBV0(zBb;+ieMK3E*n#ao0+}M!=<6`s1$Q{0i1ifq2mZ8_1xio zlHpp~Tf`pDttRkVwvf5c&-%vx=lAg^3wyI~iyFx^UUHVFaka=kHXtLG zZpZ<_GmcF}*41TJyyZV1P71d6G|TX=?GVoLI@n56;1JP~+o6+w+iAC!aU{~v{v}5? z|Ns0yp+Rc&LsCIuQE$OPAgdf~f2?5F;l-tq6QX0l?z6AGmF=0#=SZj9XOLjU6k(^IZL$tW}<&9=?> zk7G@?sDA?$RFGCL|FI$PCz)CCj(>WnSmHC_MEyVQO{~%C|2JRd=&;k3ve|XIkogiE z@UQ|u>ht~29hIEBx$(zw`K%-W?p9H|+bu-ij@T=o82bA&c-dX!GNs%jFpO73!df6a z0Bo|O*DU101v%SvADQMP0H5Yxlgj!El(!@8A#zzmBD1zR++UvbDYgBytEiM0M^Bf#NOm*0ua`!HwR6AuL(s|=)nJEwl7XdNP@8d;@pjga=@VndY zfX!*g*euYPl&rD8HD06T_uEz9o(@8c*5>$;UFd`(t{V$j&1p@%Zt4{Zs=(WR4o~4r zrRaT9zBH2Nf1P$J1fB=JscACn<_c3&@&5Ufz$8(8#Meokh7& z3~zxm^WjS(x8HM#AMZRm@)G1Z3kv6gKm2@P@g4Y5>}V50ri?1UL-Kg0(M+0aI|=!z zpcWXTOtf<1IWJTWH5qLQhgywobdiJE`#&Gu^YFG7SuHDmzocBd(bVi@*?(Q?<~E)O z0gdp)!)48>y8o=SW$wLH6fr?RI*CaAnqEWE6J9U@;&+DloJ ze;76YdI+sIy{#kb8-=fU7SN_D29QZevmBIvn%w$G(lQ@qV%~#Ee*1L|4XJ(7`_xMg zVWp@7`VbFeZXAnk&XOlH!K$$&t9%ks(>D(@m*pudxdbe6fh555qZ=B5NKT5YkjBn> zw#esuq$juS08|755-t%l{0o?dBw)ERsh*aL!_`&G?$&kpxLpTaC1S2razG{GeNNyw zK=~B7s%%$~Yl@f=T!?iKZT8k0r%!DC1TPExMMK-6k@En)R$YlCq8T;`aj zi+{1;=gje~Rn+yUn0Cy2ZBo4v<@xkaj?dK6QPQQXdXE;wjxG)?mhYAq49NvP_t?x= zJ?-V(>60=nd{ToTNC7?TWbpaii!=^(jhNF-br&J}C2`5=d{rtt=?%oA5CgmBdA}tF zDPM9=ON*Dj*&&?Kcpw#*ZiC8uBxOH{F(k)7UV6B>FgwjX847} zk5HP@*oBmDqt>+FlP$FmARnJ69;U<|TRy+?KQJ~-fdrJNANNp?6Qc9ya%FT0^SPgO zU$~KcSMcOrNujw&-P}N?{ECQ9a$aB-82!$GRYMb~v) zqxn&s&IqfP{d1)V!jx-tt-kF>A7E0Cm^a_UIl+=zO;=epoH7T9)0iDDO>lgUQM$t` z!&{{OI=1r=1$ldC|Blo$UXtUwmwhBjZR6_(EmEt1*|yD&4!X$lrV`{*$b86iqOU_z zlOlkM(yUqZIEa?|nSZcq_Hlxd#coPGg%nr^v=Y8Moup^JthgX-@fle|G&AXcEE3rq zXt_jU|I+ERS9cU_DB)#9KO4NHQeVsYyzW23hevxXMUMJ-KrKt^{1@b7=bR_%@=FsJ zgY<2IVhcs9Z|qt8zz?f=GO6wI!ZQwWPxv6l_~*Xyq~ty>Ac&So@5da@Wn+6iErjKxxUs}x6HF|a9?>3o z7{n8MB!c2jUVmHoTNJ@+s`Z-vAf{Oozg2tm5|)rC zTqg!B5)qpXI14W?2@CD~PyBBbS$xn)D7zVu_;ba295Gp`Qlc?I2p=VfI-d$upW4P= zS^Hm*9|>p&+%}8w%xk$#eDr7PY!qfb4x(2!?kARAijvgmB+Y9G4m)ubwTk$>EHaYt zeGeLyv-N%|qRz1@Ko-b7YL$@_!(|8q99WwY3c^64lQT~cN={_)V8huF*Zg1@`yCp- z1|)@&7c%|Mm*YIH)pqtgd+_|#2GS{|JEO88B&C8-)L3_$Ol4B1wR54z>=f3}jG%!= z75R<#L0gct>RO%0lIkwUlj9C{m?X>@R1{yiH0YMS|gMS_CD zOxVyAh{i3Tv_0~gUP)mCSr5e>98>=zdNw2Z#r!mOy}3GHUh*R4#T-(-6jwiupTdF@Rz0Y2KjDm#C)^l;-5tZ!xm-NrcikgGDY=Tp9+8QrWO^BF(X4r2j zgbF!)i5o;!|8-kqH!s_}B0~nrG+)gZiPlIoramEjNZE~x#QnPka`Z)Agzc^EbOm+u zp;R<7+vLc7cLu%`G$(}p}Tmxl%_&^ZjRsxWF5j`zIqCF; zL|26K1c$wgX{(#0ibhDbi1+kcd24U^}oI#l0zU2LI*v#VDhZc4<=7m zYZF@#soydoyyx;51Lst|K_|}lGCX-l0HV+Ok1=4nmQa#1dr{zVZte`XgT{2T=SQo2 z2_L>dCXAj_>l!uN06uzMsi0p-)X_$j0>2hjS$yL383I(--%?`{LI(3KAj@P%i8B4B zDw-;oK%BdI4Q_iitK1a}ea%T0Q~9rUFBs+s1)UBbM+ev9{-$!d;V!%b74bHriA=vt z^95BCb@6O&VV?3aO@3kY_>1Z4bD|(?z3F6*(Vvw&bia4A%Ixr0g7 zGP-W;Yi?z3G2RP#q5;XUC70?P%bMX5MI&wTSWeX{Jw?5ymyU|0b|BD4UpJZh0K2!| zavd69QeJ$9&SL}Qn1E~-Bp@6PuBphRwuKpzC@ykXj@}7Gz48xU>NPessvDY}D8M5c z$7<*j&<{$X(s7^i9OY>4NkJmj8QCHxGD6on*>(w%t2~lbYAt|MH5}Up=FH;v>zd#vf{cM;grsOVKvp!H;5HO~vpW?aBiH2Yub+aiX4ZCFPI48c20<((Y7eURi4_atV6ilD~wiw)Yex`qta3!IS zpwE&#G08#9oG`o|>V@{yEdKel!BphWErdj;rL0}5;ZL&Xk;1UN+SBL0B{@t*`C(#- z6c#~i)3a2GdUZz9O`!42d+DBFEOB10Y|@?Mkj46iYj^J17HgIRLB>w0%1vG|=q~W3 zdLp2FlP}7|aP`(=hYD;_Kv9P!*&lrM3F;+Uvoqb-zI)4k0+A60mMg63xW_lI^yUlu zB0F+N+elVtct^!TF|*5T*k>H$=m8c=>O*!x@Ns0K=A$_K^BAW&TMtjzfeTjs#Mc$ZLsH%^JmUaLRo zx%CYYLg+~&bdEkIaAcvyzU+1HJfwYU;=o9tJ00>2*>^C&1fJujKj^mGKYMwvGX3cv zA@-$2cyd_Sov~A$c&}_n_`M^ePBhLcEYI2?DsV8FlX+-&oIrNC(9bX@xe2jWzboi0 z3%vXx1Tq6FjdA06=l2;zCJ2E>Ao%o0&CV)AeeH#KFZuJ}BB)BC%zj{WXaC;?Y;2 zUq$OlS)0$)q8y4&n)Xbz1Z6V{!i&762{qfKhs}U#iB&DuPIC@E(O5!hPK095oQMal z#EH5jL|$6mHbt8J==Dox4wrhg+JfjTqwcnB%Et+A!e0sMX5sWKgngeia~K3*0%5&~ zi<1@|;{eL0qB;E(@-#BSC_4W}Kws_Nw~3;Wyqz?1%Q13jpSHLm-5wP(vHK0$sfEOX zk|^hb`zLia)Z}l8c+KwJTpiMc|7&)e9{vYCi)BDW8qV*tiA@`u(ju|AjwuLef-#R+)|KjV}?j=OyQiy4!7ea-pcn$1e1MiefA zSjU56(*;QAAGg*m{N`)l^|0uI&ZTjcN%wrM9rtK#89C@!WIO(?(8O3|%EwB^^g|9nS&Sn@3Pbb7`7N!R3DY9Pq!OEVcZ3gWgAm|B&uig!jEp#pXF=eT~pUj`Bfdv55)HyhV>v z-{2?yg^#GlQ~9qI$E7v&8qN_Ou*47bhImixu?jz2>MR&T7YU6VHW|lqlGkAWU1NJS z_ayA!X{0W}g?-bh;?dmwJPVkh&!VY73HOAjrEXi9in^W8?&_7SmIA@i3+`HofTW5g&*6}!7}F%gl%STk0`a1LiHq~S zyA0baf>=DNps-8$M1rVi77?_&tT3UL_7(M7<6PwVIzMxlqyIcOD~5uK8;=~qB<2h5QB#f@3U^et5-)}#(nZk zn(uNWKE7RfCZ*YpGF%&nnplC_sbHWJ*0UuL&8%#&HBrXiAt4R5y=N+yW&;GyzNFjm z4OZ*>M-k=yWhxU>y{ff2HCS+n9V9PA)PNFY=HH5GK$QqVC~JUoYA+t@nl|}q!+{dr z{OT77Hw*<~a215XP3lwS>OFlE4S0#hxXG>{j)h_&U~#7n5~ahQrhz`I&cjRcy77C_ zmx>5qrJ8lS7EPv*gr(3ayVW&T$QSVmV_6|v0Ey0QdY1!E&z}W=AUIy%YFO)Fb)=VI zoqp?K*@57pUMuH!(AKS4pNoe^BDvNjF3G~@lc@wx6o=Z71FnPj7#j2=O^WZreepLz z)E32oyJm4)|FOTQmzyxMD!GYpl(kj)i7AW5?_{Lwx!b^$tY-c99K8#MhPQF{qvb`} zW0k{#f+7YyW_YJqxbcR>(?-e?6wk)}j(Hira$GBG5E?$g-E7;n&4Z6f@>ss5M89@3t`B_inmqcRVU^7}xdS$x9m z&{^b(Q2#}~sNzP6R4}FQ<-!rwA^YDvwXo39AIwJ8_1mGd(fq}X;16BTK&JXyXK|$? z;Bovq|D0@z8HkNwSVt|}jTiK3;9JCl->Do!QY1V+eUT=3bYy+;Me<_x2#P*SqMG&3 zy&~jOc<4niOm4|W3rk}R@V%B|Lo{6ml6=R*t{eKxU=x+5HCbp?y2w3zmmV?cFW+aW z1-s8;`s)$2sY`!8|G<)VTnUv^ZJ((5E~+eX1aU26&-F{DS1cU}AW7ZyW7uIY^}l#B z$D((N2xMf2PBPUNKPlVcEs?9G5tgwYC-j-!JYaXHcBwayfJNALv>7k~KyP2IPQJ`OUD&lapF$ zq8v)H{STABp~aKmUsqk*t*@Bwg$)m+1F7#w5v=^$9eTN(^^n+h>VUBZV_;47wFBOl zxJj)_E9Gd_`E>UliL5M_6}0?>7-oHl9aXsXq3H~C5^BX}w`GBTfyL_KE4%GpGuQHj z1(hMsDX`jF%dPm)pCq)LAAFg!lF=SG4ro*h961YYBW!fFcUlLeTN*3-c^*2tIsyB^xAdw_MJ+;92Q??iSE z!)q>J_!QR*_@dJoUB=ln5fhC!b+Uase0U%S*BE#ww(xOjwCMxO8g`<1uGYkD7$$|> zT4Ii~tPeWKoh0Bt8U`o zg{n!CI>)$AphDDebH(a`PIzskBi?0nq$;i+-0_yqHWcVU6Z)#UqU+7O(V$)!)(0tx z(Z=w>i~a~Rj*Rp1_u6N5 zbOkWJ_cPtx1310r>!#-z4b8fA>cSfTt}GYIQPQ(|Nc!X-+slId97&j-*nGf;Kc@4C ziKpWr7L)9}eCS4%JlDQ4fq8O^nPo<*`Qa5roNGAla@!V>tIC&>Aj9! zK=kLiHiX(f+_g3;atqy@S&>#2-V(JjPqRSGGCz8VS_AsXM_~ zXT^g;J3W$g;ye(swpn8%h=*6Jl}IWw70dADRo55$ZWKf}To>PPQN+RyvK^VmIA&_chBLi!z@rVH=wwBImM_H_LL~%?z zd?Czrzvk%fL%t6&f`7kldn zzxXaI(y#Uj>3*Q|Uac_Fz&tXvN9b~oBSig-lz2%B0(1Vp-$>E3bx-$J5X?nE>PwQ&W$LME8n_s))2Bk-^OEH{W7U%Ao%+x6wHi39^m3F$ee^$y!U#`bIvFlXIJ+HQA__RJTTVBt5YK=yz>*>e#f}KD=x;K{K(jA=xg-d$Iv-!Gf)8kP%NH zelO*B7P!j&_yM>~C&jq*NC%U5pv3A~`)1X1Hp%-Y__5Mmu?18>Xr~e0>HmwmzYMGL z`{IW|8kCj>X_N+Oqy-5@>FyMeR>A{^R#3V_x)B~O1F(}7>QPXwdUD>_xXB*H@<4=wzaqQv#Sy%h#9NVg^6@XPC(~$|>kT+^ojK_u zvU>gZ{Kxw(?Bw|NcJcfMEWx~+ln}IjU>7<-1s1j zE#!`^OW}DbUS|s7uKb&n^M?)PmF%%AZImS)5E8Ind7R3cchWOf7-vim@C>WLw#xQ@i{<--2%3}FUrQzZ~r8_{-Wv<{YH*SzH4X=5%q zpzaG=r!~E=``&rYe%Rh`34m|+PeZl>H3=FI{d)y0A^MQ2SI_(wJ{c-PBz}2-F+$21 zht^4K_=v!+y^0j6O^WS?al`+jDHVXQgsgLebNuiw$|eMD;0gUv+7eZMduCGZt13H6 zA$)k&C3KND?QijXsUXQv!b5)zq~Aju5q@e^Q(={q z9v?aNelBivVYs=_XTHvPfAkLL!*&_^$uZaqLoMvO+T$Q2PrL`K0_lRDjwC2Cs|J&8 zW5v4%))qf&zHnn*lPKN##vPNh`jYqu$2?Uq>TLifJ*zU$C)DgU0^Pmuepn@XCKI8b zAE&D}+RLMLf!&OEd7+6mJ7g5hv{>V8;H2%|kQ?|ZX2}{{bCgU#7^WPl6XB<8YZy7L zLZSRNXci*BVMwt|jd+Vx0NkDrnD>6#k?KC`?-x;rCPV0ta`=Jj)AiuQ42{mzB<3Ex zPecX(Ak{FP_x}0)M`2PAU{G-@CMFqcvmmo*pr}w`{i&M6)(#^@jMT6j#Xe)bJIw41>hBE83$SHOQpZoIHz>C1c+oZG&S z+w6U#wfFn{nxUW~oHBc`U+x%dXk@pM{BkTv&_41=UgUzs@g#S9LhMAX}SQ-BRdq!^}uX_Q`DQJ)JeR3AnEgjk^E zx|Q#2w1<2Hr7yL)d6&y(M?hrrb+81$l7F#unKQ8#DfACZvbOH!nlE;lc zK51WUYppZGRzGg7?kP6h`lRE^3lp6j>l6)$g2R>62&Ya`=A zr+$PC6T1AZGRXJ(ijfp{p;X2{#*=Q3y1qN!&5oDf67tcoaZ-r;&5ByMZ#p9|=}Yu% zD|fF)`$Wy-SY#|PVWzp5>|zz1%~{iRUIs2?i#N3ExNNi2Oi zY?StujBzRWG1MS<;I`NWpG400y!z_uPU~X1*r*Mx-tmH2^RCbjz*|Z*yC2LFm_{i; z$_M~<0qpG#IbL6M+)2XFY{IUu#i^!^i%*!9+rI&xfhMOWjJa}v1fQN1hjVi~ogDp` zu|FY3Pj=H0Os>=bKO%J3=Pwn+f&9ao$7b1cwdy~sCxZ5GP-(9Kb0M8Mrcm?4qffZN zrh>;5=lR8~rfl#?dw-1kw@YB?NXvLbNkMu74s00T!GY+1QT1GF1#^Q}fmmN>Q%vcA zw&WEFBMjdR4})E^@}$9Gqb3?7J7k4mNp|}scv2(j zTqEJd^`TQci_E>|MEZEn)e>)VGEI*h%5 zPQ(@jp!~%^t>8pLP2aSm614qy%L;1(vz|i!ha)?|y1a?f1nVWyEBk+p)si$vrVF_# zp_NT8F*K*U!saVsZ2;g;TVYm{#?wEShq_VD;qhVDR+(!auQa89am!j;G~IIU@vaZ3 z)yfoIcmLkjK_>Ecx#9Nmb5xR~@QDtJZb*vakp=A50~I@ z+AHQy;(y}NhKT4MTR+eh>Baj|5SA$`d+^+D^YvRRigyX*6~NT?zXHv_(u4dCXfRl`eR#?ePQvl=(rj2KHu zYwfXmEq*xgOU^UH)Hs*9pzK@g>5Ff87A9fhkZ2=DAqm-Zy1VVgR-;f&>CqxA3+hwG zOVhVl*vvg*_zP&uEJz8#ko)JDgt8hKn``id;ac@98eeG()i$uJlizV1ZrFblBBT(| zeUz5eld^@&Z6soSEM&58jb1yiEFV%am;E(Fbk1mHDS$1YrxHmbAkz6a*R#(C)K_O7 zSY>nC|40Ip2h7KUgrjHq@y?6dl7Uut@Dgc9Yc4F$DF@`9CSRP@(+kw0xkWq-7Ecg? zu*uap9-U1T84oSY!n0#10`FIfEXhWyCmyBig7%xslaVYKT3RS7s`XprHuN2ejTawp z`vHY-g9S{n;`6_X?k}XQ$K>*{ObQk4k3%Z)?ek?27>-(!9w!PUTf(sRJe3WoCq^3b zp%4jZ#1+`?0H=!P?7Efcqq8Ef&2_I!{|g_#4#CVj6?8)u0k)eF%N6);hDvTLe0F~E zQ)a{|ebKcvAniF?>K~)Qzd;UoxqbTG{LB~LhoWK%8yvv3u~@48;I=EYoFw^p4r~(W z)M5({S>D-Es-iFEC-HR`rtfCYC>!x!G_VI|KQmc(|8m-YC^EPgt3Dr_e7raMv39BI zKsg-xYs5~KVNQFDsQuBVNt-{m(q5(Y6~)#h%Xbbr-QKuq=R~H!g*tU>Thd5PiVYGW zhnJkmuXEVuV~gGP6v`fe8*Va60prK!7Y$ZQ;Clc-+f!biGi+VZNIte1RU#a3P6YJw z^2S!VPQdO|`T!B6w`=mn@mmsqwaXUh{2_EDOVwl$sP=DGVC432s?ni*~ z*woY9t{b;3VHZS?Z%?~+x)3fiF4~nwKSad9u-h8_0QdU#9`&ABsT}z@8jh$ikRiKD zW;@le$7!{G)RGK6jC+EJ^X%X$=ZSz|l2mpXpP?L8OQnrV z^3qMRou>_!n&{h{3tH+I@tR3!A_j(RYo-rYhifm#Kx{6lmek>hyWWy+VkSL)x&unX zvLsXx9H99QH#6WL*#O6SH6j@0O!-$jjL(-dU&;8H0P1KqcE!aVi{xV&KFiAW)hbD{ z6to^^7uQK9+4lXuZfs@K=k6@|wL~PmMW3QxGkCkMus$-_fA)cYYg=h7^TXX`^Aok| z5O2#ALt57+Mbn1MSEB@kr~t|&<^`9Y;^OMf{JVVRvjbFs|LfHC}Y8Yzmya^>wW4uJq>R_JzCVD|L zPlMlH=->lAH(-6Z$L}4+fz)z5Bx;AM|_YF@DD_$*U}Ttvwe!w%ZKaqu#YqaD_?4I* zrH;W8BkzNV^{S8w!+UgMEE9K;iXT9c;KlKNsCfN2&TKhMdd4$#m}eg;Vh_HbGXex) zj1S`}rxQXj{phAHb=ZN1!ni;k%f3dKsprAdeq}bK)b?!l{edv`ndaE@oxwdN)7wS# zvmnX(5hW3%tf;-=pJe%Lxn+9gx5w~w6Q?Rdg|*NRC6kg+g&KM^=*COlEm{Ux!u!~t9&An zS*f+jnZ92BCVG!VX=ez-S&Nlc^F(jnG5-@EL+6AA1jwa8h6VUHz+X392$~!^?Rw3T zdm%jZd4!q;E1BF1{*!Nvs7 zsLV-T(PEIHRWo~_ay;C39v4c-OeiR+9N7Cx?$XQiQ~JWW)ncH3%wMSBxzh|jbKN~m zb&`bgseg2_e6Z7Ai*Pao6HUoIpYICoHKA%0wt83hS$Br^?w4>fM$)2SK0>;G!P!%gTsIJx)VT_bJZm}`zdN0v`FkC}-A}Z}>8Vs1x z8YmVm^VTk#DC{nRch=q}d{rcvIZqA`=Z1-@8OfO2RKD=DT7L(Shr?b_4sQ5z`eJUM z8g;1DSD@=l5{+0+n5%g(1ms$&j{i#(+SSw&lX7H)o!2DCv@8Y1=)v}xO-6&AYNivP z))MP!&A)0JVoVl5q+B3y>QGD~u$g*>>4~aiADZLazzuKIo7?gU^X2K*47&XIDitzZ z()cN*5FOmrA}h-l!qnrJPJdX1M_=Nj4QRO=R(~s+rM*g;p=-?UP$-I^-r-EPW&$DO zBAl7xiY);|%G_>sMo8U31?k$6?blx3dlDVCQ+}i(pW)7xFT1~84+v=thodMaN ziNvuR2ZED_dx%GTNOtv~{)C@c5&kC5GHt?q zc{vfZr&^^NBj5l07znuxI`Nz9(1oMY{CfitJpraGAXL-lwerj{zgmWP`h$Iz*-5C#=(xW`MOO$smq zq-PUe0OW{IIHq!yq*Xc$vd9n|&FJGUO^n82OBEb+edRsALuU0JIlwG}9RpWj7PZwQ zY|m^;*L7{-9mjY+^Ka5D(-(Gn7fEm~h{0U%HDA$oXZdJfL6u=mCX90WTfMa@Z_-UY zF)sHq<+0KD)b-8!xEuV4Kfb-^G~Kf8#V$+ZsIG|mvTCs;%Okj3>mj?onQL7X>`|L? zjm}LdCfYMb)05{XS_2Pl!iA{fKPA@HS%e5j8q{+d~Wrq^0SUiRe$8; zt;lMiETrlb+QJYWbTtNQeOrTYP&9)yJ&2)T~29P}D_8SK$^&6ax+GAR!6 zXIQ?QPQaDy@UA|dwp09(hcfP+-tF$VII%HuwK|)C0DiubecMSqAd3W~p?9tU&^@PfOy-^$nUg4}?klv?aoEdwiufWzS4l|B;O)iB0)LEY zD=xg{0u}Hp($%aMeK*S$eL_eA3W`5x$0=2SZ4T7z*n$z!R=RbTW8){gKK2)>U}b%~ zqk!#*eI@Zwi%B*~X(dolK=4bg;$c0{W3WSL=Y93zFxHnDO8G3GB*1)8p|%YY08xh{ z2qV%cIi$$J(APCr4z&|iv3&)VqDEHfM`uxLVSxnFU2P(^rd;LGWn}7C8f5ihmKGFz zYsUFba+h&$M3vD(g$^kc;}==7Ktop>!BQhTD48gFt}t)Zt3HTak1i(xLZCiLs@YGf zF6^5iAO9SiM8_I_U$2sBqSMemq2i-1kjK`qZK0QjIGy)$eL$r+DIDgx6y8tlk{v#A z+sK+55hs#DxOvMQaLX21H7Q9EhhST4arVkH<-3y2X~OoN3Rg!qdqB)_Tf0{liV?=2 zJ$_!3+azbYOvRPyB16kfU5ER*4}j-uY$SDd-^<2q!1RUlA~dGD{`>6fy-T88tJ<7myCn!nF(aJcfokJX&BmqxA{(+gY!x^dqI@Mu zF}<%L`n}Wr-5t;Oiz5T|KD`H_pqh+e5spIo9!#{vO>$Q%~@62I`&CBe}<6yxNmpV*0xR z`Ap)?`|3cpXe$qnPNfttz!*9iK9txq z7g8R$e3&^G36I>NT;lyfokPx0tdWDY2+SeXs&#$hyagVe`}@(ApJfJdAWrp!Az&i#!Lj1^SI= z^(KisV-MM!P8DuhOxzW69IN3WokHb9dDG+-$m>FOLdIX2XbBm=nx^$E1hD0TJ`hUy znCfLib03`vj)r`<@beFOs-mQmyc2`m9x)fm!o$w98Sv`#Mp>8zvl>6eUqx^DI?o-b z59y-Iz5OpWt0{7mO zYM?R%I$$c(gV-M@wC}Fj1ToBryrH}+EL_b`gFc!mpgZax3WE(;QNad&qTE_+5c%Ty zpYA+U&k!1$^*R?}$GKXx?Sy64q-fTy=`ToV2sx%0fL1{@+vbHO{=TsQKNA0@UemxZ z6)~R#6n4m37GpcRh(@7}f>I40Bo3MlJUNQxiNzG+ZU^0{*KZVnDV?XAP0uvs_4F{s? zd2!nTP82sC)0G-ambihHh|VSRXHr`ZAh~7{G0B{7@a^}<7VD|Bh&(#g8leRCi1?J- z4DUnG5hHaH9`rx#MLy=S(l9qfmFOV>0Ib1fASAnXyl@&U-0i7GRsKQ@{zK2ioV3n; zt)_g0eC{o$egwg=2}~(nsvqKE2-|xt? z@_hr!`j`XKkj)6e+@L!$e-qXoT8%)p+Jsc(wHJPV=Khs}S%&UT2zo5&A(LRg!C+yX zA>F$Eyve6_;$y+;O|quE%np@pNQ5E7z9AU8zY>u|p-0k++FMr+d35Yi_0vyUcdVA| zLqd1Sid)4|W5UzATf5N;jPvhb0)xVw>7JNe(3P&$e(!A2mdS$EycFgW=F~WW=)Mn; zNCaJuU*;WK#HpbQX8pjJc;%&(rK|kPm~pzWs5A1l+2Bb5#K4Q@h(W8Uu?0z8aq(t9 zNfKRNNpM!BKf#X_9V7d%#@B-YdCUrVSx!{wg@a2e8i(A<&O3%IIoqey-DZuY?dIG- zCnHA-vNE*K7eELy{(z_ic7VY~S1F1~2{BXF;ot<(@rcL=datQ#yR`@)1lF4U_~1Pz z0T@lDS#Tr?YR0TssG9N*01Q+N2_owhTHAOBge(kcgL~qt zDPXgGMi_wNfL=*D+N)g2q>)vDSLxL{^K9`WqI?a4Et$@R<dZ@tC{*V)2VN2*fUz#()E|T4~PXe<|@9t z@B)=4@&AAxA4_9cBgP)vAs_oLGh)@JlC<&znKif5OyoM4WV3?*N(}=N!3U#lxX2|6 zkzrB*JG>Hy%qXev*xof*q(Va9LFedjbV+`%Ty>WC3l?_HHU!&`e7Fwg_8q40cWm7O z`a|*Ne}4q8<^M;j-2X4&f1$rtued~CX2~U$-^!tFVEqjxY#71{Zp^_I2BYeG!J7qm z#h!oBE716Am;CjAyjAEu!qYDUu+HoYbuwOXl|2_si@J)Opc$%lZCUH0nR+*=w(l z2O3k0Z((AwL4f&32L`-~FryQ=1_*aivKK8JIaU>wdgYDm)Q{bpbZ9kPuG6a(3`!7q{0#jlNgKqAn zXyFrHl;8w|79}!Xm>$|8|Ln&Tc{B?*^9eh#zbOTLSAn&oTSZFmy~jmM7;Q&{kS_)~ z$y--@xx+n}h;12&C9yHd{(C1GJfBXhh#t*e!;m%y%GG}T*yV%W8p|}8w)C2;BG()O zyjg+J-$x6Btl{H1ec& zcMt72*OZ&m_MAKH?s5w+yX=0Jy!MfN#tYF84-zPk#5ByQ@Yw;P^Z0gCo0(E~4(FpU zyXMkK2YL+abD|pOJ^7Vlk9qazH-zib_sZ2Xm~zz@laf3LOo+59?KbLo`IU%M^~Sa9 zZsu1eW8t*Nt3ck^zR*3(ocO>WnVz6lQ|RsFf6n1@)>W4%PN*9FK0uA$K9WE+fVQI=6nv)h~{;n9?4{) zPqfO+Av)s%*xxAd3W|R;v;cF&(t>NTxe4nNTLTiXlf|yDgb4A@O!jG}c!+>iMVAcl zrA7N=m}I>n@ww{lCv@tJs)3?EDS$pqh`dU&phYM4D*SM-u3{{F5EA`_Sss({>AB3h z*^^2&OW^l6RvMniFf4g}q#q&$XdTg|Nt?+2QP;D;(?E;!5p+4D_L^A2aA1W&Hrfa` z2UADomjfQvzzwoMx8S z7qKUI3b*p-+|wS6CcAaL51@gr_T_BKtZ5%(HCFV`Ro$2!_X$$I^tf9S%dLHsK^vk) z$YZ+k**)dx8X$quZ%9x?E?<7Yv|`_dlk}vGt9(FSX>HKAboZ?-p5B~qmg5u`P4x3Ey+=*0d!X z-oUO`GUO7BGc*N@^ZOPQmQ#h-8PMqFtovp0DBl5rMWsk~?Cwv)E?Nw@+?aFNg)$~P zL+Rc6xQ88dRdJ2TKh$51z}G7jq`CiD2Ub$_0ktK3%9X3|!^A(|aML4>iSD?@U&k2e zbkEOMoP`41^AyUp*&&j3?1~yDh7xeXhXmtfne0FpuL#D1`}eOE+vx=~zNuTS%qNnlNDg&) zEjj@CRcc7vIs>0!h&b;D%vhoxq|9&3!-KnwgN5HXxVyYr4&s4U7|Mi|JR328K7UOo zXMtOD<_20lAu z8OfRZ8$zHv!)JadiQ)0#jbRc>WnfQj$JLXx z{F&+Tly}=8P`dJmk)L-Koiq6MaUoF?ux4yxS}o33K$AAjO8c#&mV+8MwCRIQ$m*iBO(x71B!%mewVlYKOL0E?u~ zxb|0f1o1O7eFyE&v4Xidw28J~MXtceJj>)=ZvrLdT`1?oC5(&Fw&)&8qiZQK~5^Wv?z~YZ{77#1*2_ zG8vUvN`9tcZl-Qu`K-~`#|ruAs*Xckv+3Tk!oA&P|I9O9j;%5f)&wlyuNu5n? zuy;W0(-9;me~5PykvXz)=o`xg9b6jShoOh$4y=Vua!Kxl%Ot!D?X0?;f4UQ#6X4dG zO_Ky{yb3CCZje6j_SdifLgV;fzN)#Hr06e0G7M4mc6&XJ2c=}6A|;Mscdu@wf#y8) zBkF)J=5oy0j-(Z{MPu6_t{a_X$hW*=-?L_;sm?~?6w~hIEJo6r{A^(6JF+!ql?Ly4tduBt1{KFf-qXJm0pn?WqVU?ArbO<34mZEMVcAzV>i1NFFB=!7& z_fHfe^hz<%`ay{NdQN(`Mp-AC2|u63A3uO4$K1z-;R@9JktfSbl8ah!BSZ6UbK1LX zD?5vZRwbq|C5@^nbxh4@QPe4m)6f$SMb}h z5}MA|)!V&ddJ9V}B}tD{$qLD@Ri*v{-Q5*)A_0;#guy84DN>Vrgsggond7oqCq7z- zEdPQ62&cWSXbjn=bo$V+)4Y+RbP7C|yg$=yAvG!3Er>7ff^FS3E8A^y-4WehgsMl# zH+Tqtx4iB}^ktrOE*0WjfPXjSB}-5HxeSZjivK5Yt2>fZcp8H%zP54X^>O8aNlIQ? zB4U?60VN&a*^UZ6EoV^pK;J6um4~cxy5i~v$}d@|#dLGiKT0gzs%0;PBi%e0UX&yq z+9-xr62g@qJ13v{l2wIW^bm}z1r`UGnk@7sRQRBpq>RIEssmEVf190T$T*C3bW6#0 zr=>@OIF!ovO!~XW8VT?6t9CFWNd+vOrzp}!a-_*OSD4PQ#Pfa3W=LS%S)x`KG% zgfJ~xWiZ)o&>GihH!m%?cF2bKuFV<&nHt`2!Z&CFZeY z`=6$KPJ!9Bz&LjLexljia>JIfmsoQO)O;am)T1vzWeHX+v^Mk5hdFECIR>1Y#}|!N zhpkxty+>=Z4H}%9=0v(5?`mE!D@;%~+Qh&(uf^IMWkkcc<+;BCdqQpjtpJ_)(j&4yBlzI9aM+pOnS!wNA;T$}qg`3b+S|eyXTdijBFlV^xQO{#r z&Tn%=e?WzZyy=2ID*yk!(-XK6vh7d*a-%q!G^;UQYQBz{mtpOVW^)^NVZ#TTl|zyU z)mNURVF-K-kWXCC`6da9vHAwV%!B$3<{~Uy-ZYwf{%R%;_i!eG93G`b#HPdy_$CwJKG=>xoRiKU%WqD@9@#HlK6lirUx3Pi_Iy%z*V`Y2&n*GIJAITp0#G2D4te`)xYm8P4vJ3leSXh-&aeExOkIQMKq*+H^DO z_>871`35w1y;QRzn|OgH1X8$7a>ePO1S*k5CfP`7gnrUQcJCkWNM-=cPu)v&0+D|G1=ckSOvR+E1Y5|1M4rKfVD9+FK7M}JyfKsU-loyl?l!cS0t zfR^qtaEpN6-F#`)3Jj^OP3wd0?-Ink4pc1TbnIbkOpc8V`C=Dv<8LaFtDRamkqdq* ztoQEG#F7)5R!+kE<830<_`uE$|A$y*X;IQ7En=$H3fQJ|`ra-PrUy^%3ph>xIkGvn zAqF~K`^=hW_zX9B%iSxM+4HsM61TAq|0mmcZ1yTQ`3l)m2D)h|aYA;keh{0p z-J5Lge6c#A;#G46#-f=bMf}qt%w5NOUyxSZ_fwm)osVBIYe6D8FjPiSP83#e zcqWR&;OX2tVF?v%d7ffNKz$XqRX4a7$f8qqz!#_p@sSwZ#cL$7xCoZSJ<)xg$Y%TX zc?*%S-fwSdJ%Z?DXmUh0JhGgKZmekWt4oz}#sf|kV6FJpJrxrGTKs^du zj0(P(khhcj^c}5)A1?x7HP<3-zA1Ns5c^Dz#OgP$Jgukbm6_dZ$CE835AnUdyUf>y z&1y}$KBM^01B)LeGX|c+_u?r8`9j^qDF1dgO)9NA2t_wL!n8$(Qo{Wi5d*QUd;VN81EAJg@2|%%mn0PVXr}6zaRiQpHg9x_hfmqJ&n@Ey%3MVm;^~brWFXc;XFT9? zq50{7kElP}il~Xk_Pcw!X<)FfV zc>D$ydPY;U7m#%SVQguC+S4CG4aE{U$%9as5Y_#k5cOYu%1BzM zbnzuEz$JoDX@T5C59ld%icAfv^DG$wA(YiY6xN6`z7G)6`7ct)&)&t>8ki4nP=m%3 zR2YZTWs2m^EXEVhMvnfMOhZ>-;67q39?bJ8pp*IK!R(mn2>wcpU;p1klB7WP9?$7N z&>g7@q(qdbC*FmI9>{nKX@LooFqrb-G#62eau>4qI=yiCFIt|i6DzKlP`V7+-BzMo z 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

tOzcLmPbKGUy@FXGRFlY~f0z8-JVQrH;K?(%| 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 literal 0 HcmV?d00001 diff --git a/feature/setup/src/test/screenshots/com.f0x1d.logfox.setup.compose.SetupScreenContentTest.shouldShowDarkSetupScreenContent.png b/feature/setup/src/test/screenshots/com.f0x1d.logfox.feature.setup.presentation.ui.compose.SetupScreenContentTest.shouldShowDarkSetupScreenContent.png similarity index 94% rename from feature/setup/src/test/screenshots/com.f0x1d.logfox.setup.compose.SetupScreenContentTest.shouldShowDarkSetupScreenContent.png rename to feature/setup/src/test/screenshots/com.f0x1d.logfox.feature.setup.presentation.ui.compose.SetupScreenContentTest.shouldShowDarkSetupScreenContent.png index 31261d65054ef3a0c174ab4efde752f902e7fad8..56e00491101ed27425cb5c62df083a5c40b88f5f 100644 GIT binary patch delta 55 zcmeyegQ;gH(*za9%!#UovT3P_C8b5Fdc~-I MvEho1)4t6H0GVJH=l}o! diff --git a/feature/setup/src/test/screenshots/com.f0x1d.logfox.feature.setup.presentation.ui.compose.SetupScreenContentTest.shouldShowSetupScreenContent.png b/feature/setup/src/test/screenshots/com.f0x1d.logfox.feature.setup.presentation.ui.compose.SetupScreenContentTest.shouldShowSetupScreenContent.png new file mode 100644 index 0000000000000000000000000000000000000000..d968059dcb6cef32e0ba8fef3a89a0ce5e861aaa GIT binary patch literal 39627 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 UZy2^qs&jrk>-c@me+2yWpWWGf5&!@I literal 0 HcmV?d00001 diff --git a/feature/setup/src/test/screenshots/com.f0x1d.logfox.setup.compose.SetupScreenContentTest.shouldOpenAdbDialogOnSetupScreenContent.png b/feature/setup/src/test/screenshots/com.f0x1d.logfox.setup.compose.SetupScreenContentTest.shouldOpenAdbDialogOnSetupScreenContent.png deleted file mode 100644 index 87f8cfb9bde21b8f85aa77c09690e044e92e59ae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48482 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

^wQpI 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 diff --git a/feature/setup/src/test/screenshots/com.f0x1d.logfox.setup.compose.SetupScreenContentTest.shouldShowAdbDialogOnSetupScreenContent.png b/feature/setup/src/test/screenshots/com.f0x1d.logfox.setup.compose.SetupScreenContentTest.shouldShowAdbDialogOnSetupScreenContent.png deleted file mode 100644 index 87cfc39338124e4ca6157b1b09c4ad0c1064315b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 206610 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�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 = listOf(directory.name), +) { + fun File.isModule(): Boolean = File(this, "build.gradle.kts").isFile -requireNotNull(rootDir.listFiles()).filter { file -> - file.isDirectory && file.name in modulesDirectories -}.forEach { file -> - val modules = requireNotNull(file.listFiles()) + if (directory.isModule()) { + val moduleName = parentDirectoriesNames.joinToString( + prefix = ":", + separator = ":", + ) - modules.filter(File::isDirectory).forEach { moduleFile -> - if (submoduleNameRegex.matches(moduleFile.name)) { - include(":${file.name}:${moduleFile.name}") - } + include(moduleName) + } else { + directory + .listFiles() + ?.forEach { file -> + includeRecursive( + directory = file, + parentDirectoriesNames = parentDirectoriesNames + file.name, + ) + } } } diff --git a/feature/logging/.gitignore b/shared/.gitignore similarity index 100% rename from feature/logging/.gitignore rename to shared/.gitignore diff --git a/data/build.gradle.kts b/shared/build.gradle.kts similarity index 82% rename from data/build.gradle.kts rename to shared/build.gradle.kts index 1809be4b..20b336de 100644 --- a/data/build.gradle.kts +++ b/shared/build.gradle.kts @@ -6,4 +6,6 @@ android.namespace = "com.f0x1d.logfox.model" dependencies { implementation(libs.bundles.androidx) + + implementation(libs.timber) } diff --git a/data/src/main/kotlin/com/f0x1d/logfox/model/Device.kt b/shared/src/main/kotlin/com/f0x1d/logfox/model/Device.kt similarity index 100% rename from data/src/main/kotlin/com/f0x1d/logfox/model/Device.kt rename to shared/src/main/kotlin/com/f0x1d/logfox/model/Device.kt diff --git a/data/src/main/kotlin/com/f0x1d/logfox/model/Identifiable.kt b/shared/src/main/kotlin/com/f0x1d/logfox/model/Identifiable.kt similarity index 90% rename from data/src/main/kotlin/com/f0x1d/logfox/model/Identifiable.kt rename to shared/src/main/kotlin/com/f0x1d/logfox/model/Identifiable.kt index aecfa19a..6cd026a1 100644 --- a/data/src/main/kotlin/com/f0x1d/logfox/model/Identifiable.kt +++ b/shared/src/main/kotlin/com/f0x1d/logfox/model/Identifiable.kt @@ -2,7 +2,6 @@ package com.f0x1d.logfox.model import android.annotation.SuppressLint import androidx.recyclerview.widget.DiffUtil -import com.f0x1d.logfox.model.logline.LogLine interface Identifiable { val id: Any diff --git a/data/src/main/kotlin/com/f0x1d/logfox/model/UIDS.kt b/shared/src/main/kotlin/com/f0x1d/logfox/model/UIDS.kt similarity index 100% rename from data/src/main/kotlin/com/f0x1d/logfox/model/UIDS.kt rename to shared/src/main/kotlin/com/f0x1d/logfox/model/UIDS.kt diff --git a/data/src/main/kotlin/com/f0x1d/logfox/model/exception/TerminalNotSupportedException.kt b/shared/src/main/kotlin/com/f0x1d/logfox/model/exception/TerminalNotSupportedException.kt similarity index 100% rename from data/src/main/kotlin/com/f0x1d/logfox/model/exception/TerminalNotSupportedException.kt rename to shared/src/main/kotlin/com/f0x1d/logfox/model/exception/TerminalNotSupportedException.kt diff --git a/data/src/main/kotlin/com/f0x1d/logfox/model/logline/LogLine.kt b/shared/src/main/kotlin/com/f0x1d/logfox/model/logline/LogLine.kt similarity index 84% rename from data/src/main/kotlin/com/f0x1d/logfox/model/logline/LogLine.kt rename to shared/src/main/kotlin/com/f0x1d/logfox/model/logline/LogLine.kt index 146703fe..01f8afcb 100644 --- a/data/src/main/kotlin/com/f0x1d/logfox/model/logline/LogLine.kt +++ b/shared/src/main/kotlin/com/f0x1d/logfox/model/logline/LogLine.kt @@ -7,13 +7,13 @@ import java.util.Date data class LogLine( override val id: Long, - val dateAndTime: Long = System.currentTimeMillis(), - val uid: String = "", - val pid: String = "", - val tid: String = "", - val packageName: String? = null, - val level: LogLevel = LogLevel.INFO, - val tag: String = "", + val dateAndTime: Long, + val uid: String, + val pid: String, + val tid: String, + val packageName: String?, + val level: LogLevel, + val tag: String, val content: String, val originalContent: String, ) : Identifiable { diff --git a/data/src/main/kotlin/com/f0x1d/logfox/model/logline/LogLineExt.kt b/shared/src/main/kotlin/com/f0x1d/logfox/model/logline/LogLineExt.kt similarity index 87% rename from data/src/main/kotlin/com/f0x1d/logfox/model/logline/LogLineExt.kt rename to shared/src/main/kotlin/com/f0x1d/logfox/model/logline/LogLineExt.kt index c6272ed1..edf96b73 100644 --- a/data/src/main/kotlin/com/f0x1d/logfox/model/logline/LogLineExt.kt +++ b/shared/src/main/kotlin/com/f0x1d/logfox/model/logline/LogLineExt.kt @@ -3,6 +3,7 @@ package com.f0x1d.logfox.model.logline import android.content.Context import androidx.collection.LruCache import com.f0x1d.logfox.model.UIDS_MAPPINGS +import timber.log.Timber private val logRegex = "(.{14}) (.{5,}?) (.{1,5}) (.{1,5}) (.) (.+?): (.+)".toRegex() // time, uid, pid, tid, level, tag, message @@ -15,7 +16,11 @@ fun LogLine( line: String, context: Context ) = runCatching { - logRegex.find(line.trim())?.run { + logRegex.find(line.trim()).also { matchResult -> + if (matchResult == null) { + Timber.d("matchResult is null for $line") + } + }?.run { val uid = groupValues[2].replace(" ", "") val integerUid = uid.toIntOrNull() ?: UIDS_MAPPINGS[uid] ?: uidRegex.find(uid)?.run { 100_000 * groupValues[1].toInt() + 10_000 + groupValues[2].toInt() @@ -48,6 +53,8 @@ fun LogLine( originalContent = groupValues[0], ) } +}.onFailure { th -> + Timber.e("error while parsing", th) }.getOrNull() private fun mapLevel(level: String) = LogLevel.entries.find { diff --git a/data/src/main/kotlin/com/f0x1d/logfox/model/preferences/ShowLogValues.kt b/shared/src/main/kotlin/com/f0x1d/logfox/model/preferences/ShowLogValues.kt similarity index 100% rename from data/src/main/kotlin/com/f0x1d/logfox/model/preferences/ShowLogValues.kt rename to shared/src/main/kotlin/com/f0x1d/logfox/model/preferences/ShowLogValues.kt diff --git a/strings/src/main/res/values-ru/strings.xml b/strings/src/main/res/values-ru/strings.xml index 7ca76ee6..32e79969 100644 --- a/strings/src/main/res/values-ru/strings.xml +++ b/strings/src/main/res/values-ru/strings.xml @@ -157,4 +157,5 @@ Черный список Добавить в черный список Убрать из черного списка + Поделиться логами diff --git a/strings/src/main/res/values/strings.xml b/strings/src/main/res/values/strings.xml index 9ff9834a..786cbfa4 100644 --- a/strings/src/main/res/values/strings.xml +++ b/strings/src/main/res/values/strings.xml @@ -168,4 +168,5 @@ Remove from blacklist Are you sure want to add this app to blacklist? LogFox does not observe crashes for blacklisted apps Monet + Share logs