From e749b362ca458d37f4bfb466a780133c690e6718 Mon Sep 17 00:00:00 2001 From: Nik Clayton Date: Mon, 4 Dec 2023 16:58:36 +0100 Subject: [PATCH] refactor: Start creating core modules (#286) The existing code base is a single monolithic module. This is relatively simple to configure, but many of the tasks to compile the module and produce the final app have to run in series. This is unnecessarily slow. This change starts to split the code in to multiple modules, which are: - :core:account - AccountManager, to break a dependency cycle - :core:common - low level types or utilities used in many other modules - :core:database - database types, DAOs, and DI infrastructure - :core:network - network types, API definitions, and DI infrastructure - :core:preferences - shared preferences definitions and DI infrastructure - :core:testing - fakes and rules used across different modules Benchmarking with gradle-profiler shows a ~ 17% reduction in incremental build times after an ABI change. That will improve further as more code is moved to modules. The rough mechanics of the changes are: - Create the modules, and move existing files in to them. This causes a lot of churn in import arguments. - Convert build.gradle files to build.gradle.kts - Separate out the data required to display a tab (`TabViewData`) from the data required to configure a tab (`TabData`) to avoid circular dependencies. - Abstract the repeated build logic shared between the modules in to a set of plugins under `build-logic/`, to simplify configuration of the application and library builds. - Be explicit that some nullable types are non-null at time of use. Nullable properties in types imported from modules generally can't be smart cast to non-null. There's a detailed discussion of why this restriction exists at https://discuss.kotlinlang.org/t/what-is-the-reason-behind-smart-cast-being-impossible-to-perform-when-referenced-class-is-in-another-module/2201. The changes highlight design problems with the current code, including: - The main application code is too tightly coupled to the network types - Too many values are declared unnecessarily nullable - Dependency cycles between code that make modularisation difficult Future changes will add more modules. See #291. --- app/build.gradle | 250 ------------------ app/build.gradle.kts | 206 +++++++++++++++ app/lint-baseline.xml | 196 ++++---------- app/proguard-rules.pro | 13 +- .../app/pachli/updatecheck/UpdateCheck.kt | 2 +- .../app/pachli/updatecheck/UpdateCheck.kt | 2 +- .../app/pachli/updatecheck/UpdateCheck.kt | 2 +- .../java/app/pachli/AccountsInListFragment.kt | 6 +- app/src/main/java/app/pachli/BaseActivity.kt | 10 +- .../java/app/pachli/BottomSheetActivity.kt | 2 +- app/src/main/java/app/pachli/ListsActivity.kt | 12 +- app/src/main/java/app/pachli/MainActivity.kt | 17 +- .../main/java/app/pachli/PachliApplication.kt | 10 +- .../main/java/app/pachli/SplashActivity.kt | 2 +- .../java/app/pachli/StatusListActivity.kt | 4 +- app/src/main/java/app/pachli/TabData.kt | 150 ----------- .../java/app/pachli/TabPreferenceActivity.kt | 63 ++--- app/src/main/java/app/pachli/TabViewData.kt | 152 +++++++++++ .../main/java/app/pachli/ViewMediaActivity.kt | 2 +- .../pachli/adapter/AccountFieldEditAdapter.kt | 2 +- .../pachli/adapter/AccountSelectionAdapter.kt | 4 +- .../app/pachli/adapter/AccountViewHolder.kt | 2 +- .../java/app/pachli/adapter/EmojiAdapter.kt | 4 +- .../adapter/FilterableStatusViewHolder.kt | 2 +- .../pachli/adapter/FollowRequestViewHolder.kt | 6 +- .../java/app/pachli/adapter/PollAdapter.kt | 2 +- .../adapter/ReportNotificationViewHolder.kt | 6 +- .../pachli/adapter/StatusBaseViewHolder.kt | 17 +- .../adapter/StatusDetailedViewHolder.kt | 4 +- .../app/pachli/adapter/StatusViewHolder.kt | 8 +- .../java/app/pachli/adapter/TabAdapter.kt | 19 +- .../java/app/pachli/appstore/CacheUpdater.kt | 4 +- .../main/java/app/pachli/appstore/Events.kt | 10 +- .../components/account/AccountActivity.kt | 14 +- .../components/account/AccountFieldAdapter.kt | 6 +- .../components/account/AccountViewModel.kt | 8 +- .../account/list/ListsForAccountViewModel.kt | 4 +- .../account/media/AccountMediaFragment.kt | 8 +- .../account/media/AccountMediaGridAdapter.kt | 2 +- .../media/AccountMediaRemoteMediator.kt | 4 +- .../account/media/AccountMediaViewModel.kt | 4 +- .../accountlist/AccountListFragment.kt | 14 +- .../accountlist/adapter/AccountAdapter.kt | 2 +- .../announcements/AnnouncementAdapter.kt | 6 +- .../announcements/AnnouncementsActivity.kt | 2 +- .../announcements/AnnouncementsViewModel.kt | 6 +- .../components/compose/ComposeActivity.kt | 18 +- .../compose/ComposeAutoCompleteAdapter.kt | 4 +- .../components/compose/ComposeViewModel.kt | 14 +- .../components/compose/MediaUploader.kt | 4 +- .../compose/dialog/AddPollDialog.kt | 2 +- .../components/compose/dialog/FocusDialog.kt | 2 +- .../compose/view/ComposeOptionsView.kt | 2 +- .../compose/view/FocusIndicatorView.kt | 2 +- .../compose/view/PollPreviewView.kt | 2 +- .../components/compose/view/TootButton.kt | 2 +- .../conversation/ConversationViewData.kt | 4 +- .../conversation/ConversationViewHolder.kt | 1 + .../conversation/ConversationsFragment.kt | 4 +- .../ConversationsRemoteMediator.kt | 11 +- .../conversation/ConversationsViewModel.kt | 9 +- .../pachli/components/drafts/DraftHelper.kt | 12 +- .../components/drafts/DraftMediaAdapter.kt | 2 +- .../components/drafts/DraftsActivity.kt | 6 +- .../pachli/components/drafts/DraftsAdapter.kt | 10 +- .../components/drafts/DraftsViewModel.kt | 10 +- .../components/filters/EditFilterActivity.kt | 6 +- .../components/filters/EditFilterViewModel.kt | 6 +- .../components/filters/FiltersActivity.kt | 2 +- .../components/filters/FiltersAdapter.kt | 11 +- .../components/filters/FiltersListener.kt | 2 +- .../components/filters/FiltersViewModel.kt | 4 +- .../followedtags/FollowedTagsActivity.kt | 4 +- .../FollowedTagsRemoteMediator.kt | 6 +- .../followedtags/FollowedTagsViewModel.kt | 4 +- .../instanceinfo/InstanceInfoRepository.kt | 12 +- .../fragment/InstanceListFragment.kt | 4 +- .../pachli/components/login/LoginActivity.kt | 6 +- .../components/login/LoginWebViewViewModel.kt | 2 +- .../notifications/FollowViewHolder.kt | 8 +- .../notifications/NotificationFetcher.kt | 14 +- .../notifications/NotificationHelper.kt | 22 +- .../notifications/NotificationsFragment.kt | 24 +- .../NotificationsPagingAdapter.kt | 8 +- .../NotificationsPagingSource.kt | 8 +- .../notifications/NotificationsRepository.kt | 6 +- .../notifications/NotificationsViewModel.kt | 12 +- .../notifications/PushNotificationHelper.kt | 10 +- .../StatusNotificationViewHolder.kt | 8 +- .../notifications/StatusViewHolder.kt | 2 +- .../preference/AccountPreferencesFragment.kt | 10 +- .../NotificationPreferencesFragment.kt | 6 +- .../preference/PreferencesActivity.kt | 6 +- .../preference/PreferencesFragment.kt | 8 +- .../preference/ProxyPreferencesFragment.kt | 10 +- .../TabFilterPreferencesFragment.kt | 2 +- .../components/report/ReportViewModel.kt | 6 +- .../report/adapter/AdapterHandler.kt | 2 +- .../report/adapter/StatusViewHolder.kt | 8 +- .../report/adapter/StatusesPagingSource.kt | 4 +- .../fragments/ReportStatusesFragment.kt | 6 +- .../scheduled/ScheduledStatusActivity.kt | 2 +- .../scheduled/ScheduledStatusAdapter.kt | 2 +- .../scheduled/ScheduledStatusPagingSource.kt | 4 +- .../scheduled/ScheduledStatusViewModel.kt | 4 +- .../components/search/SearchActivity.kt | 2 +- .../components/search/SearchViewModel.kt | 10 +- .../search/adapter/SearchAccountsAdapter.kt | 2 +- .../search/adapter/SearchHashtagsAdapter.kt | 2 +- .../search/adapter/SearchPagingSource.kt | 4 +- .../adapter/SearchPagingSourceFactory.kt | 4 +- .../fragments/SearchAccountsFragment.kt | 6 +- .../search/fragments/SearchFragment.kt | 2 +- .../fragments/SearchHashtagsFragment.kt | 2 +- .../fragments/SearchStatusesFragment.kt | 10 +- .../timeline/CachedTimelineRepository.kt | 24 +- .../components/timeline/FiltersRepository.kt | 6 +- .../timeline/NetworkTimelineRepository.kt | 14 +- .../components/timeline/TimelineFragment.kt | 4 +- .../timeline/TimelinePagingAdapter.kt | 2 +- .../viewmodel/CachedTimelineRemoteMediator.kt | 24 +- .../viewmodel/CachedTimelineViewModel.kt | 8 +- .../viewmodel/NetworkTimelinePagingSource.kt | 2 +- .../NetworkTimelineRemoteMediator.kt | 6 +- .../viewmodel/NetworkTimelineViewModel.kt | 8 +- .../timeline/viewmodel/PageCache.kt | 6 +- .../timeline/viewmodel/TimelineViewModel.kt | 12 +- .../trending/TrendingLinkViewHolder.kt | 2 +- .../trending/TrendingLinksAdapter.kt | 2 +- .../trending/TrendingLinksRepository.kt | 2 +- .../trending/TrendingTagViewHolder.kt | 2 +- .../viewmodel/TrendingLinksViewModel.kt | 4 +- .../viewmodel/TrendingTagsViewModel.kt | 10 +- .../components/viewthread/ThreadAdapter.kt | 2 +- .../viewthread/ViewThreadViewModel.kt | 16 +- .../viewthread/edits/ViewEditsAdapter.kt | 16 +- .../viewthread/edits/ViewEditsFragment.kt | 6 +- .../viewthread/edits/ViewEditsViewModel.kt | 4 +- .../main/java/app/pachli/db/DraftsAlert.kt | 2 + app/src/main/java/app/pachli/entity/Report.kt | 12 - .../java/app/pachli/fragment/SFragment.kt | 16 +- .../app/pachli/fragment/ViewMediaFragment.kt | 2 +- .../app/pachli/fragment/ViewVideoFragment.kt | 2 +- .../interfaces/AccountSelectionListener.kt | 2 +- .../java/app/pachli/network/FilterModel.kt | 8 +- .../java/app/pachli/network/MediaUploadApi.kt | 21 -- .../network/ServerCapabilitiesRepository.kt | 6 +- .../app/pachli/pager/ImagePagerAdapter.kt | 2 +- .../java/app/pachli/pager/MainPagerAdapter.kt | 4 +- ...NotificationBlockStateBroadcastReceiver.kt | 4 +- .../receiver/SendStatusBroadcastReceiver.kt | 6 +- .../receiver/UnifiedPushBroadcastReceiver.kt | 4 +- .../app/pachli/service/SendStatusService.kt | 14 +- .../settings/AccountPreferenceDataStore.kt | 7 +- .../app/pachli/updatecheck/UpdateCheck.kt | 4 +- .../pachli/usecase/DeveloperToolsUseCase.kt | 8 +- .../java/app/pachli/usecase/LogoutUsecase.kt | 10 +- .../java/app/pachli/usecase/TimelineCases.kt | 12 +- .../app/pachli/util/AttachmentExtensions.kt | 31 +++ .../java/app/pachli/util/AttachmentHelper.kt | 6 +- .../java/app/pachli/util/CustomEmojiHelper.kt | 2 +- .../java/app/pachli/util/FocalPointUtil.kt | 2 +- .../main/java/app/pachli/util/LinkHelper.kt | 6 +- .../util/ListStatusAccessibilityDelegate.kt | 2 +- .../java/app/pachli/util/LocaleManager.kt | 4 +- .../main/java/app/pachli/util/LocaleUtils.kt | 2 +- .../pachli/util/NotificationTypeConverter.kt | 2 +- .../app/pachli/util/ShareShortcutHelper.kt | 2 +- .../util/StatusDisplayOptionsRepository.kt | 11 +- .../java/app/pachli/util/StatusExtensions.kt | 68 +++++ .../java/app/pachli/util/StatusViewHelper.kt | 30 +-- .../app/pachli/view/MediaPreviewImageView.kt | 2 +- app/src/main/java/app/pachli/view/PollView.kt | 4 +- .../java/app/pachli/view/PreviewCardView.kt | 2 +- .../app/pachli/viewdata/AttachmentViewData.kt | 4 +- .../pachli/viewdata/NotificationViewData.kt | 8 +- .../java/app/pachli/viewdata/PollViewData.kt | 6 +- .../app/pachli/viewdata/StatusViewData.kt | 30 +-- .../app/pachli/viewdata/TrendingViewData.kt | 2 +- .../viewmodel/AccountsInListViewModel.kt | 4 +- .../pachli/viewmodel/EditProfileViewModel.kt | 8 +- .../app/pachli/viewmodel/ListsViewModel.kt | 4 +- .../app/pachli/worker/PruneCacheWorker.kt | 4 +- .../app/pachli/BottomSheetActivityTest.kt | 10 +- app/src/test/java/app/pachli/FilterV1Test.kt | 12 +- .../test/java/app/pachli/MainActivityTest.kt | 18 +- .../java/app/pachli/StatusComparisonTest.kt | 4 +- .../components/compose/ComposeActivityTest.kt | 14 +- .../InstanceInfoRepositoryTest.kt | 14 +- .../NotificationsPagingSourceTest.kt | 4 +- .../NotificationsViewModelTestBase.kt | 12 +- .../NotificationsViewModelTestFilter.kt | 4 +- ...icationsViewModelTestNotificationAction.kt | 2 +- .../NotificationsViewModelTestStatusAction.kt | 2 +- ...ationsViewModelTestStatusDisplayOptions.kt | 2 +- .../NotificationsViewModelTestUiState.kt | 4 +- .../NotificationsViewModelTestVisibleId.kt | 2 +- .../CachedTimelineRemoteMediatorTest.kt | 16 +- .../CachedTimelineViewModelTestBase.kt | 9 +- ...CachedTimelineViewModelTestStatusAction.kt | 2 +- ...melineViewModelTestStatusDisplayOptions.kt | 2 +- .../CachedTimelineViewModelTestUiState.kt | 2 +- .../NetworkTimelinePagingSourceTest.kt | 2 +- .../NetworkTimelineRemoteMediatorTest.kt | 6 +- .../NetworkTimelineViewModelTestBase.kt | 9 +- ...etworkTimelineViewModelTestStatusAction.kt | 2 +- ...melineViewModelTestStatusDisplayOptions.kt | 2 +- .../NetworkTimelineViewModelTestUiState.kt | 2 +- .../components/timeline/StatusMocker.kt | 14 +- .../viewthread/ViewThreadViewModelTest.kt | 14 +- .../app/pachli/di/FakeMastodonApiModule.kt | 3 +- .../java/app/pachli/di/FakeNetworkModule.kt | 3 +- .../app/pachli/di/FakePreferencesModule.kt | 3 +- .../app/pachli/usecase/TimelineCasesTest.kt | 4 +- .../java/app/pachli/util/LinkHelperTest.kt | 4 +- .../java/app/pachli/util/LocaleUtilsTest.kt | 2 +- .../StatusDisplayOptionsRepositoryTest.kt | 11 +- build-logic/convention/build.gradle.kts | 67 +++++ .../AndroidApplicationConventionPlugin.kt | 46 ++++ .../kotlin/AndroidHiltConventionPlugin.kt | 41 +++ .../kotlin/AndroidLibraryConventionPlugin.kt | 59 +++++ .../kotlin/AndroidLintConventionPlugin.kt | 49 ++++ .../kotlin/AndroidRoomConventionPlugin.kt | 61 +++++ .../app/pachli/AndroidInstrumentedTests.kt | 35 +++ .../main/kotlin/app/pachli/KotlinAndroid.kt | 83 ++++++ .../main/kotlin/app/pachli/PachliFlavor.kt | 80 ++++++ .../kotlin/app/pachli/ProjectExtensions.kt | 26 ++ build-logic/gradle.properties | 21 ++ build-logic/settings.gradle.kts | 31 +++ build.gradle | 3 + checks/build.gradle | 36 --- checks/build.gradle.kts | 38 +++ checks/gradle.properties | 21 ++ checks/settings.gradle.kts | 30 +++ core/AndroidManifest.xml | 21 ++ core/accounts/build.gradle.kts | 41 +++ core/accounts/lint-baseline.xml | 4 + .../src/main/kotlin/AndroidManifest.xml | 21 ++ .../pachli/core/accounts}/AccountManager.kt | 31 ++- core/common/build.gradle.kts | 30 +++ core/common/lint-baseline.xml | 70 +++++ .../src/main/kotlin/AndroidManifest.xml | 21 ++ .../core/common}/di/CoroutineScopeModule.kt | 2 +- .../pachli/core/common/string}/StringUtils.kt | 2 +- .../common}/util/AbsoluteTimeFormatter.kt | 5 +- .../pachli/core/common}/util/NumberUtils.kt | 19 +- .../core/common/string}/StringUtilsTest.kt | 21 +- .../common}/util/AbsoluteTimeFormatterTest.kt | 19 +- .../core/common}/util/NumberUtilsTest.kt | 2 +- core/database/build.gradle.kts | 40 +++ core/database/lint-baseline.xml | 4 + .../1.json | 0 .../2.json | 0 .../3.json | 0 .../src/main/kotlin/AndroidManifest.xml | 21 ++ .../app/pachli/core/database}/AppDatabase.kt | 19 +- .../app/pachli/core/database}/Converters.kt | 31 ++- .../pachli/core/database/dao}/AccountDao.kt | 6 +- .../core/database/dao}/ConversationsDao.kt | 7 +- .../app/pachli/core/database/dao}/DraftDao.kt | 6 +- .../pachli/core/database/dao}/InstanceDao.kt | 8 +- .../pachli/core/database/dao}/RemoteKeyDao.kt | 4 +- .../pachli/core/database/dao}/TimelineDao.kt | 9 +- .../core/database/dao}/TranslatedStatusDao.kt | 3 +- .../core/database}/di/DatabaseModule.kt | 6 +- .../core/database/model}/AccountEntity.kt | 12 +- .../database/model}/ConversationEntity.kt | 21 +- .../core/database/model}/DraftEntity.kt | 12 +- .../core/database/model}/InstanceEntity.kt | 8 +- .../core/database/model}/RemoteKeyEntity.kt | 2 +- .../app/pachli/core/database/model/TabData.kt | 56 ++++ .../database/model}/TimelineStatusEntity.kt | 34 ++- .../database/model}/TranslatedStatusEntity.kt | 8 +- .../core/database/dao}/TimelineDaoTest.kt | 58 ++-- .../core/database}/di/FakeDatabaseModule.kt | 6 +- .../src/test/resources/robolectric.properties | 21 ++ core/network/build.gradle.kts | 44 +++ core/network/lint-baseline.xml | 26 ++ core/network/proguard-rules.pro | 21 ++ core/network/src/main/AndroidManifest.xml | 21 ++ .../app/pachli/core}/network/Operations.kt | 8 +- .../core/network}/StatusParsingHelper.kt | 6 +- .../core/network}/di/MastodonApiModule.kt | 4 +- .../pachli/core/network}/di/NetworkModule.kt | 40 +-- .../network}/json/GuardedBooleanAdapter.kt | 2 +- .../pachli/core/network}/json/Iso8601Utils.kt | 19 +- .../network}/json/Rfc3339DateJsonAdapter.kt | 2 +- .../pachli/core/network/model}/AccessToken.kt | 5 +- .../app/pachli/core/network/model}/Account.kt | 2 +- .../core/network/model}/Announcement.kt | 2 +- .../core/network/model}/AppCredentials.kt | 2 +- .../pachli/core/network/model}/Attachment.kt | 16 +- .../app/pachli/core/network/model}/Card.kt | 5 +- .../core/network/model}/Conversation.kt | 2 +- .../core/network/model}/DeletedStatus.kt | 2 +- .../app/pachli/core/network/model}/Emoji.kt | 2 +- .../app/pachli/core/network/model}/Error.kt | 2 +- .../app/pachli/core/network/model}/Filter.kt | 2 +- .../core/network/model}/FilterKeyword.kt | 2 +- .../core/network/model}/FilterResult.kt | 2 +- .../pachli/core/network/model}/FilterV1.kt | 2 +- .../app/pachli/core/network/model}/HashTag.kt | 2 +- .../core/network/model}/HttpHeaderLink.kt | 2 +- .../pachli/core/network/model}/InstanceV1.kt | 2 +- .../pachli/core}/network/model/InstanceV2.kt | 3 +- .../pachli/core/network/model/LinksHeader.kt | 35 +++ .../app/pachli/core/network/model}/Marker.kt | 2 +- .../pachli/core/network/model}/MastoList.kt | 2 +- .../core/network/model/MediaUploadApi.kt | 38 +++ .../core/network/model}/MediaUploadResult.kt | 2 +- .../pachli/core/network/model}/NewStatus.kt | 2 +- .../core/network/model}/Notification.kt | 31 ++- .../model}/NotificationSubscribeResult.kt | 2 +- .../app/pachli/core/network/model}/Poll.kt | 2 +- .../core/network/model}/Relationship.kt | 7 +- .../app/pachli/core/network/model/Report.kt | 29 ++ .../core/network/model}/ScheduledStatus.kt | 2 +- .../core/network/model}/SearchResult.kt | 2 +- .../app/pachli/core/network/model}/Status.kt | 52 +--- .../core/network/model}/StatusContext.kt | 2 +- .../pachli/core/network/model}/StatusEdit.kt | 2 +- .../core/network/model}/StatusParams.kt | 5 +- .../core/network/model}/StatusSource.kt | 5 +- .../core/network/model}/TimelineAccount.kt | 5 +- .../core/network/model}/TimelineKind.kt | 0 .../pachli/core/network/model}/Translation.kt | 2 +- .../pachli/core/network/model/TrendingTag.kt | 5 +- .../pachli/core/network/model}/TrendsLink.kt | 2 +- .../InstanceSwitchAuthInterceptor.kt | 31 ++- .../core/network/retrofit}/MastodonApi.kt | 84 +++--- .../pachli/core}/network/ServerKindTest.kt | 10 +- .../json/GuardedBooleanAdapterTest.kt | 4 +- .../core/network/model}/HttpHeaderLinkTest.kt | 2 +- .../InstanceV1SwitchAuthInterceptorTest.kt | 76 +++--- .../src/test/resources/robolectric.properties | 20 ++ core/preferences/build.gradle.kts | 36 +++ core/preferences/lint-baseline.xml | 4 + core/preferences/src/main/AndroidManifest.xml | 21 ++ .../core/preferences}/ProxyConfiguration.kt | 19 +- .../core/preferences}/SettingsConstants.kt | 2 +- .../SharedPreferencesExtensions.kt | 2 +- .../SharedPreferencesRepository.kt | 4 +- .../core/preferences}/di/PreferencesModule.kt | 2 +- .../preferences}/ProxyConfigurationTest.kt | 20 +- .../SharedPreferencesRepositoryTest.kt | 6 +- .../src/test/resources/robolectric.properties | 20 ++ core/testing/build.gradle.kts | 44 +++ core/testing/lint-baseline.xml | 140 ++++++++++ .../fakes/InMemorySharedPreferences.kt | 2 +- .../rules/LazyActivityScenarioRule.kt | 2 +- .../core/testing/rules}/MainCoroutineRule.kt | 2 +- gradle/libs.versions.toml | 28 +- plugins/markdown2resource/build.gradle.kts | 5 - plugins/markdown2resource/gradle.properties | 21 ++ plugins/markdown2resource/settings.gradle | 1 - plugins/markdown2resource/settings.gradle.kts | 30 +++ settings.gradle | 23 -- settings.gradle.kts | 33 +++ tools/build.gradle.kts | 2 +- tools/mklanguages/settings.gradle.kts | 30 +++ 360 files changed, 3410 insertions(+), 1737 deletions(-) delete mode 100644 app/build.gradle create mode 100644 app/build.gradle.kts delete mode 100644 app/src/main/java/app/pachli/TabData.kt create mode 100644 app/src/main/java/app/pachli/TabViewData.kt delete mode 100644 app/src/main/java/app/pachli/entity/Report.kt delete mode 100644 app/src/main/java/app/pachli/network/MediaUploadApi.kt create mode 100644 app/src/main/java/app/pachli/util/AttachmentExtensions.kt create mode 100644 app/src/main/java/app/pachli/util/StatusExtensions.kt create mode 100644 build-logic/convention/build.gradle.kts create mode 100644 build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt create mode 100644 build-logic/convention/src/main/kotlin/AndroidHiltConventionPlugin.kt create mode 100644 build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt create mode 100644 build-logic/convention/src/main/kotlin/AndroidLintConventionPlugin.kt create mode 100644 build-logic/convention/src/main/kotlin/AndroidRoomConventionPlugin.kt create mode 100644 build-logic/convention/src/main/kotlin/app/pachli/AndroidInstrumentedTests.kt create mode 100644 build-logic/convention/src/main/kotlin/app/pachli/KotlinAndroid.kt create mode 100644 build-logic/convention/src/main/kotlin/app/pachli/PachliFlavor.kt create mode 100644 build-logic/convention/src/main/kotlin/app/pachli/ProjectExtensions.kt create mode 100644 build-logic/gradle.properties create mode 100644 build-logic/settings.gradle.kts delete mode 100644 checks/build.gradle create mode 100644 checks/build.gradle.kts create mode 100644 checks/gradle.properties create mode 100644 checks/settings.gradle.kts create mode 100644 core/AndroidManifest.xml create mode 100644 core/accounts/build.gradle.kts create mode 100644 core/accounts/lint-baseline.xml create mode 100644 core/accounts/src/main/kotlin/AndroidManifest.xml rename {app/src/main/java/app/pachli/db => core/accounts/src/main/kotlin/app/pachli/core/accounts}/AccountManager.kt (90%) create mode 100644 core/common/build.gradle.kts create mode 100644 core/common/lint-baseline.xml create mode 100644 core/common/src/main/kotlin/AndroidManifest.xml rename {app/src/main/java/app/pachli => core/common/src/main/kotlin/app/pachli/core/common}/di/CoroutineScopeModule.kt (98%) rename {app/src/main/java/app/pachli/util => core/common/src/main/kotlin/app/pachli/core/common/string}/StringUtils.kt (97%) rename {app/src/main/java/app/pachli => core/common/src/main/kotlin/app/pachli/core/common}/util/AbsoluteTimeFormatter.kt (97%) rename {app/src/main/java/app/pachli => core/common/src/main/kotlin/app/pachli/core/common}/util/NumberUtils.kt (51%) rename {app/src/test/java/app/pachli => core/common/src/test/kotlin/app/pachli/core/common/string}/StringUtilsTest.kt (58%) rename {app/src/test/java/app/pachli => core/common/src/test/kotlin/app/pachli/core/common}/util/AbsoluteTimeFormatterTest.kt (77%) rename {app/src/test/java/app/pachli => core/common/src/test/kotlin/app/pachli/core/common}/util/NumberUtilsTest.kt (98%) create mode 100644 core/database/build.gradle.kts create mode 100644 core/database/lint-baseline.xml rename {app/schemas/app.pachli.db.AppDatabase => core/database/schemas/app.pachli.core.database.AppDatabase}/1.json (100%) rename {app/schemas/app.pachli.db.AppDatabase => core/database/schemas/app.pachli.core.database.AppDatabase}/2.json (100%) rename {app/schemas/app.pachli.db.AppDatabase => core/database/schemas/app.pachli.core.database.AppDatabase}/3.json (100%) create mode 100644 core/database/src/main/kotlin/AndroidManifest.xml rename {app/src/main/java/app/pachli/db => core/database/src/main/kotlin/app/pachli/core/database}/AppDatabase.kt (69%) rename {app/src/main/java/app/pachli/db => core/database/src/main/kotlin/app/pachli/core/database}/Converters.kt (86%) rename {app/src/main/java/app/pachli/db => core/database/src/main/kotlin/app/pachli/core/database/dao}/AccountDao.kt (90%) rename {app/src/main/java/app/pachli/db => core/database/src/main/kotlin/app/pachli/core/database/dao}/ConversationsDao.kt (92%) rename {app/src/main/java/app/pachli/db => core/database/src/main/kotlin/app/pachli/core/database/dao}/DraftDao.kt (93%) rename {app/src/main/java/app/pachli/db => core/database/src/main/kotlin/app/pachli/core/database/dao}/InstanceDao.kt (85%) rename {app/src/main/java/app/pachli/db => core/database/src/main/kotlin/app/pachli/core/database/dao}/RemoteKeyDao.kt (91%) rename {app/src/main/java/app/pachli/db => core/database/src/main/kotlin/app/pachli/core/database/dao}/TimelineDao.kt (97%) rename {app/src/main/java/app/pachli/db => core/database/src/main/kotlin/app/pachli/core/database/dao}/TranslatedStatusDao.kt (90%) rename {app/src/main/java/app/pachli => core/database/src/main/kotlin/app/pachli/core/database}/di/DatabaseModule.kt (96%) rename {app/src/main/java/app/pachli/db => core/database/src/main/kotlin/app/pachli/core/database/model}/AccountEntity.kt (96%) rename {app/src/main/java/app/pachli/components/conversation => core/database/src/main/kotlin/app/pachli/core/database/model}/ConversationEntity.kt (91%) rename {app/src/main/java/app/pachli/db => core/database/src/main/kotlin/app/pachli/core/database/model}/DraftEntity.kt (89%) rename {app/src/main/java/app/pachli/db => core/database/src/main/kotlin/app/pachli/core/database/model}/InstanceEntity.kt (92%) rename {app/src/main/java/app/pachli/db => core/database/src/main/kotlin/app/pachli/core/database/model}/RemoteKeyEntity.kt (97%) create mode 100644 core/database/src/main/kotlin/app/pachli/core/database/model/TabData.kt rename {app/src/main/java/app/pachli/db => core/database/src/main/kotlin/app/pachli/core/database/model}/TimelineStatusEntity.kt (94%) rename {app/src/main/java/app/pachli/db => core/database/src/main/kotlin/app/pachli/core/database/model}/TranslatedStatusEntity.kt (92%) rename {app/src/test/java/app/pachli/db => core/database/src/test/kotlin/app/pachli/core/database/dao}/TimelineDaoTest.kt (90%) rename {app/src/test/java/app/pachli => core/database/src/test/kotlin/app/pachli/core/database}/di/FakeDatabaseModule.kt (94%) create mode 100644 core/database/src/test/resources/robolectric.properties create mode 100644 core/network/build.gradle.kts create mode 100644 core/network/lint-baseline.xml create mode 100644 core/network/proguard-rules.pro create mode 100644 core/network/src/main/AndroidManifest.xml rename {app/src/main/java/app/pachli => core/network/src/main/kotlin/app/pachli/core}/network/Operations.kt (97%) rename {app/src/main/java/app/pachli/util => core/network/src/main/kotlin/app/pachli/core/network}/StatusParsingHelper.kt (94%) rename {app/src/main/java/app/pachli => core/network/src/main/kotlin/app/pachli/core/network}/di/MastodonApiModule.kt (92%) rename {app/src/main/java/app/pachli => core/network/src/main/kotlin/app/pachli/core/network}/di/NetworkModule.kt (78%) rename {app/src/main/java/app/pachli => core/network/src/main/kotlin/app/pachli/core/network}/json/GuardedBooleanAdapter.kt (97%) rename {app/src/main/java/app/pachli => core/network/src/main/kotlin/app/pachli/core/network}/json/Iso8601Utils.kt (93%) rename {app/src/main/java/app/pachli => core/network/src/main/kotlin/app/pachli/core/network}/json/Rfc3339DateJsonAdapter.kt (97%) rename {app/src/main/java/app/pachli/entity => core/network/src/main/kotlin/app/pachli/core/network/model}/AccessToken.kt (91%) rename {app/src/main/java/app/pachli/entity => core/network/src/main/kotlin/app/pachli/core/network/model}/Account.kt (98%) rename {app/src/main/java/app/pachli/entity => core/network/src/main/kotlin/app/pachli/core/network/model}/Announcement.kt (97%) rename {app/src/main/java/app/pachli/entity => core/network/src/main/kotlin/app/pachli/core/network/model}/AppCredentials.kt (95%) rename {app/src/main/java/app/pachli/entity => core/network/src/main/kotlin/app/pachli/core/network/model}/Attachment.kt (86%) rename {app/src/main/java/app/pachli/entity => core/network/src/main/kotlin/app/pachli/core/network/model}/Card.kt (95%) rename {app/src/main/java/app/pachli/entity => core/network/src/main/kotlin/app/pachli/core/network/model}/Conversation.kt (96%) rename {app/src/main/java/app/pachli/entity => core/network/src/main/kotlin/app/pachli/core/network/model}/DeletedStatus.kt (97%) rename {app/src/main/java/app/pachli/entity => core/network/src/main/kotlin/app/pachli/core/network/model}/Emoji.kt (96%) rename {app/src/main/java/app/pachli/entity => core/network/src/main/kotlin/app/pachli/core/network/model}/Error.kt (95%) rename {app/src/main/java/app/pachli/entity => core/network/src/main/kotlin/app/pachli/core/network/model}/Filter.kt (97%) rename {app/src/main/java/app/pachli/entity => core/network/src/main/kotlin/app/pachli/core/network/model}/FilterKeyword.kt (87%) rename {app/src/main/java/app/pachli/entity => core/network/src/main/kotlin/app/pachli/core/network/model}/FilterResult.kt (86%) rename {app/src/main/java/app/pachli/entity => core/network/src/main/kotlin/app/pachli/core/network/model}/FilterV1.kt (98%) rename {app/src/main/java/app/pachli/entity => core/network/src/main/kotlin/app/pachli/core/network/model}/HashTag.kt (69%) rename {app/src/main/java/app/pachli/util => core/network/src/main/kotlin/app/pachli/core/network/model}/HttpHeaderLink.kt (99%) rename {app/src/main/java/app/pachli/entity => core/network/src/main/kotlin/app/pachli/core/network/model}/InstanceV1.kt (98%) rename {app/src/main/java/app/pachli => core/network/src/main/kotlin/app/pachli/core}/network/model/InstanceV2.kt (99%) create mode 100644 core/network/src/main/kotlin/app/pachli/core/network/model/LinksHeader.kt rename {app/src/main/java/app/pachli/entity => core/network/src/main/kotlin/app/pachli/core/network/model}/Marker.kt (88%) rename {app/src/main/java/app/pachli/entity => core/network/src/main/kotlin/app/pachli/core/network/model}/MastoList.kt (95%) create mode 100644 core/network/src/main/kotlin/app/pachli/core/network/model/MediaUploadApi.kt rename {app/src/main/java/app/pachli/entity => core/network/src/main/kotlin/app/pachli/core/network/model}/MediaUploadResult.kt (86%) rename {app/src/main/java/app/pachli/entity => core/network/src/main/kotlin/app/pachli/core/network/model}/NewStatus.kt (97%) rename {app/src/main/java/app/pachli/entity => core/network/src/main/kotlin/app/pachli/core/network/model}/Notification.kt (79%) rename {app/src/main/java/app/pachli/entity => core/network/src/main/kotlin/app/pachli/core/network/model}/NotificationSubscribeResult.kt (95%) rename {app/src/main/java/app/pachli/entity => core/network/src/main/kotlin/app/pachli/core/network/model}/Poll.kt (97%) rename {app/src/main/java/app/pachli/entity => core/network/src/main/kotlin/app/pachli/core/network/model}/Relationship.kt (92%) create mode 100644 core/network/src/main/kotlin/app/pachli/core/network/model/Report.kt rename {app/src/main/java/app/pachli/entity => core/network/src/main/kotlin/app/pachli/core/network/model}/ScheduledStatus.kt (96%) rename {app/src/main/java/app/pachli/entity => core/network/src/main/kotlin/app/pachli/core/network/model}/SearchResult.kt (95%) rename {app/src/main/java/app/pachli/entity => core/network/src/main/kotlin/app/pachli/core/network/model}/Status.kt (74%) rename {app/src/main/java/app/pachli/entity => core/network/src/main/kotlin/app/pachli/core/network/model}/StatusContext.kt (95%) rename {app/src/main/java/app/pachli/entity => core/network/src/main/kotlin/app/pachli/core/network/model}/StatusEdit.kt (91%) rename {app/src/main/java/app/pachli/entity => core/network/src/main/kotlin/app/pachli/core/network/model}/StatusParams.kt (93%) rename {app/src/main/java/app/pachli/entity => core/network/src/main/kotlin/app/pachli/core/network/model}/StatusSource.kt (91%) rename {app/src/main/java/app/pachli/entity => core/network/src/main/kotlin/app/pachli/core/network/model}/TimelineAccount.kt (95%) rename {app/src/main/java/app/pachli/components/timeline => core/network/src/main/kotlin/app/pachli/core/network/model}/TimelineKind.kt (100%) rename {app/src/main/java/app/pachli/entity => core/network/src/main/kotlin/app/pachli/core/network/model}/Translation.kt (98%) rename app/src/main/java/app/pachli/entity/TrendingTagsResult.kt => core/network/src/main/kotlin/app/pachli/core/network/model/TrendingTag.kt (95%) rename {app/src/main/java/app/pachli/entity => core/network/src/main/kotlin/app/pachli/core/network/model}/TrendsLink.kt (98%) rename {app/src/main/java/app/pachli/network => core/network/src/main/kotlin/app/pachli/core/network/retrofit}/InstanceSwitchAuthInterceptor.kt (77%) rename {app/src/main/java/app/pachli/network => core/network/src/main/kotlin/app/pachli/core/network/retrofit}/MastodonApi.kt (93%) rename {app/src/test/java/app/pachli => core/network/src/test/kotlin/app/pachli/core}/network/ServerKindTest.kt (90%) rename {app/src/test/java/app/pachli => core/network/src/test/kotlin/app/pachli/core/network}/json/GuardedBooleanAdapterTest.kt (97%) rename {app/src/test/java/app/pachli/util => core/network/src/test/kotlin/app/pachli/core/network/model}/HttpHeaderLinkTest.kt (99%) rename {app/src/test/java/app/pachli/network => core/network/src/test/kotlin/app/pachli/core/network/retrofit}/InstanceV1SwitchAuthInterceptorTest.kt (64%) create mode 100644 core/network/src/test/resources/robolectric.properties create mode 100644 core/preferences/build.gradle.kts create mode 100644 core/preferences/lint-baseline.xml create mode 100644 core/preferences/src/main/AndroidManifest.xml rename {app/src/main/java/app/pachli/settings => core/preferences/src/main/kotlin/app/pachli/core/preferences}/ProxyConfiguration.kt (65%) rename {app/src/main/java/app/pachli/settings => core/preferences/src/main/kotlin/app/pachli/core/preferences}/SettingsConstants.kt (99%) rename {app/src/main/java/app/pachli/util => core/preferences/src/main/kotlin/app/pachli/core/preferences}/SharedPreferencesExtensions.kt (83%) rename {app/src/main/java/app/pachli/util => core/preferences/src/main/kotlin/app/pachli/core/preferences}/SharedPreferencesRepository.kt (96%) rename {app/src/main/java/app/pachli => core/preferences/src/main/kotlin/app/pachli/core/preferences}/di/PreferencesModule.kt (96%) rename {app/src/test/java/app/pachli/entity => core/preferences/src/test/kotlin/app/pachli/core/preferences}/ProxyConfigurationTest.kt (70%) rename {app/src/test/java/app/pachli/util => core/preferences/src/test/kotlin/app/pachli/core/preferences}/SharedPreferencesRepositoryTest.kt (96%) create mode 100644 core/preferences/src/test/resources/robolectric.properties create mode 100644 core/testing/build.gradle.kts create mode 100644 core/testing/lint-baseline.xml rename {app/src/test/java/app/pachli => core/testing/src/main/kotlin/app/pachli/core/testing}/fakes/InMemorySharedPreferences.kt (99%) rename {app/src/test/java/app/pachli => core/testing/src/main/kotlin/app/pachli/core/testing}/rules/LazyActivityScenarioRule.kt (98%) rename {app/src/test/java/app/pachli/components/timeline => core/testing/src/main/kotlin/app/pachli/core/testing/rules}/MainCoroutineRule.kt (97%) create mode 100644 plugins/markdown2resource/gradle.properties delete mode 100644 plugins/markdown2resource/settings.gradle create mode 100644 plugins/markdown2resource/settings.gradle.kts delete mode 100644 settings.gradle create mode 100644 settings.gradle.kts create mode 100644 tools/mklanguages/settings.gradle.kts diff --git a/app/build.gradle b/app/build.gradle deleted file mode 100644 index 5bdec3457..000000000 --- a/app/build.gradle +++ /dev/null @@ -1,250 +0,0 @@ -plugins { - alias(libs.plugins.android.application) - alias(libs.plugins.google.ksp) - alias(libs.plugins.kotlin.android) - alias(libs.plugins.kotlin.parcelize) - alias(libs.plugins.aboutlibraries) - alias(libs.plugins.hilt) - alias(libs.plugins.room) - - id "app.pachli.plugins.markdown2resource" -} - -apply from: 'gitTools.gradle' - -final def gitSha = ext.getGitSha() -final def gitRevCount = ext.getGitRevCount() - -// The app name -final def APP_NAME = "Pachli" -// The application id. Must be unique, e.g. based on your domain -final def APP_ID = "app.pachli" -// url of a custom app logo. Recommended size at least 600x600. Keep empty to use the default logo. -final def CUSTOM_LOGO_URL = "" -// e.g. mastodon.social. Keep empty to not suggest any instance on the signup screen -final def CUSTOM_INSTANCE = "" -// link to your support account. Will be linked on the about page when not empty. -final def SUPPORT_ACCOUNT_URL = "https://mastodon.social/@Pachli" - -android { - compileSdk 34 - namespace "app.pachli" - defaultConfig { - applicationId APP_ID - namespace "app.pachli" - minSdk 23 - targetSdk 34 - versionCode 8 - versionName "2.0.0" - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - vectorDrawables.useSupportLibrary = true - - resValue "string", "app_name", APP_NAME - - buildConfigField("String", "CUSTOM_LOGO_URL", "\"$CUSTOM_LOGO_URL\"") - buildConfigField("String", "CUSTOM_INSTANCE", "\"$CUSTOM_INSTANCE\"") - buildConfigField("String", "SUPPORT_ACCOUNT_URL", "\"$SUPPORT_ACCOUNT_URL\"") - } - buildTypes { - debug { - getIsDefault().set(true) - } - - release { - minifyEnabled true - shrinkResources true - proguardFiles 'proguard-rules.pro' - } - } - - flavorDimensions += "color" - flavorDimensions += "store" - - productFlavors { - blue { - dimension "color" - } - - orange { - dimension "color" - resValue "string", "app_name", APP_NAME + " Current" - applicationIdSuffix ".current" - versionNameSuffix "+" + gitSha - } - - fdroid { - dimension "store" - } - - github { - dimension "store" - } - - google { - dimension "store" - } - } - - lint { - lintConfig file("lint.xml") - // Regenerate by running `./gradlew updateLintBaselineOrangeDebug` - baseline = file("lint-baseline.xml") - } - - buildFeatures { - buildConfig true - resValues true - viewBinding true - } - testOptions { - unitTests { - returnDefaultValues = true - includeAndroidResources = true - } - unitTests.all { - systemProperty 'robolectric.logging.enabled', 'true' - systemProperty 'robolectric.lazyload', 'ON' - } - } - sourceSets { - androidTest.assets.srcDirs += files("$projectDir/schemas".toString()) - } - - // Exclude unneeded files added by libraries - packagingOptions.resources.excludes += [ - 'LICENSE_OFL', - 'LICENSE_UNICODE', - ] - - bundle { - language { - // bundle all languages in every apk so the dynamic language switching works - enableSplit = false - } - } - - dependenciesInfo { - includeInApk false - includeInBundle false - } - - applicationVariants.configureEach { variant -> - tasks.register("printVersionInfo${variant.name.capitalize()}") { - notCompatibleWithConfigurationCache("Should always print the version info") - println variant.versionCode + " " + variant.versionName - } - variant.outputs.configureEach { - // Set the "orange" release versionCode to the number of commits on the - // branch, to ensure the versionCode updates on every release. - if (variant.buildType.name == "release" && variant.flavorName.startsWith("orange")) { - versionCodeOverride = gitRevCount - } - outputFileName = "Pachli_${variant.versionName}_${variant.versionCode}_${gitSha}_" + - "${variant.flavorName}_${buildType.name}.apk" - } - } -} - -room { - schemaDirectory("$projectDir/schemas/") -} - -ksp { - arg("room.incremental", "true") - arg("room.generateKotlin", "true") -} - -configurations { - // JNI-only libraries don't play nicely with Robolectric - // see https://github.com/tuskyapp/Tusky/pull/3367 - testImplementation.exclude group: "org.conscrypt", module: "conscrypt-android" - testRuntime.exclude group: "org.conscrypt", module: "conscrypt-android" -} - -aboutLibraries { - configPath = "licenses" - includePlatform = false - duplicationMode = com.mikepenz.aboutlibraries.plugin.DuplicateMode.MERGE - prettyPrint = true -} - -markdown2resource { - files = [ layout.projectDirectory.file('../PRIVACY.md') ] -} - -// library versions are in PROJECT_ROOT/gradle/libs.versions.toml -dependencies { - implementation libs.kotlinx.coroutines.android - implementation libs.kotlinx.coroutines.rx3 - - implementation libs.bundles.androidx - implementation libs.bundles.room - ksp libs.androidx.room.compiler - - implementation libs.android.material - - implementation libs.gson - - implementation libs.bundles.retrofit - implementation libs.networkresult.calladapter - - implementation libs.bundles.okhttp - - implementation libs.conscrypt.android - - implementation libs.bundles.glide - ksp libs.glide.compiler - - implementation libs.bundles.rxjava3 - - implementation libs.bundles.autodispose - - implementation libs.hilt.android - ksp libs.hilt.compiler - - implementation libs.sparkbutton - - implementation libs.touchimageview - - implementation libs.bundles.material.drawer - implementation libs.material.typeface - - implementation libs.image.cropper - - implementation libs.bundles.filemojicompat - - implementation libs.bouncycastle - implementation libs.unified.push - - implementation libs.bundles.xmldiff - - implementation libs.bundles.aboutlibraries - implementation libs.timber - - googleImplementation libs.app.update - googleImplementation libs.app.update.ktx - - implementation libs.kotlin.result - implementation libs.semver - - testImplementation libs.androidx.test.junit - testImplementation libs.robolectric - testImplementation libs.bundles.mockito - testImplementation libs.mockwebserver - testImplementation libs.androidx.core.testing - testImplementation libs.kotlinx.coroutines.test - testImplementation libs.androidx.work.testing - testImplementation libs.truth - testImplementation libs.turbine - testImplementation libs.androidx.test.core.ktx - testImplementation libs.hilt.android.testing - kspTest libs.hilt.compiler - - androidTestImplementation libs.espresso.core - androidTestImplementation libs.androidx.room.testing - androidTestImplementation libs.androidx.test.junit - androidTestImplementation libs.hilt.android.testing - androidTestImplementation libs.androidx.test.core.ktx - - lintChecks project(":checks") -} diff --git a/app/build.gradle.kts b/app/build.gradle.kts new file mode 100644 index 000000000..c77a4b604 --- /dev/null +++ b/app/build.gradle.kts @@ -0,0 +1,206 @@ +/* + * Copyright 2023 Pachli Association + * + * This file is a part of Pachli. + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Pachli; if not, + * see . + */ + +import com.android.build.gradle.internal.api.ApkVariantOutputImpl + +plugins { + alias(libs.plugins.pachli.android.application) + alias(libs.plugins.pachli.android.hilt) + alias(libs.plugins.kotlin.parcelize) + alias(libs.plugins.aboutlibraries) + + id("app.pachli.plugins.markdown2resource") +} + +apply(from = "gitTools.gradle") +val getGitSha: groovy.lang.Closure by extra +val getGitRevCount: groovy.lang.Closure by extra + +android { + namespace = "app.pachli" + + defaultConfig { + applicationId = "app.pachli" + versionCode = 8 + versionName = "2.0.0" + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + testInstrumentationRunnerArguments["disableAnalytics"] = "true" + + vectorDrawables.useSupportLibrary = true + } + + buildTypes { + debug { + isDefault = true + } + + release { + isMinifyEnabled = true + isShrinkResources = true + proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") + } + } + + packaging { + resources.excludes.apply { + add("LICENSE_OFL") + add("LICENSE_UNICODE") + } + } + + bundle { + language { + // bundle all languages in every apk so the dynamic language switching works + enableSplit = false + } + } + + dependenciesInfo { + includeInApk = false + includeInBundle = false + } + + testOptions { + unitTests { + isReturnDefaultValues = true + isIncludeAndroidResources = true + } + unitTests.all { + it.systemProperty("robolectric.logging.enabled", "true") + it.systemProperty("robolectric.lazyload", "ON") + } + } + + applicationVariants.configureEach { + tasks.register("printVersionInfo${name.replaceFirstChar { it.uppercaseChar() }}") { + notCompatibleWithConfigurationCache("Should always print the version info") + doLast { + println("$versionCode $versionName") + } + } + outputs.configureEach { + this as ApkVariantOutputImpl + // Set the "orange" release versionCode to the number of commits on the + // branch, to ensure the versionCode updates on every release. Include the + // SHA of the current commit to help with troubleshooting bug reports + if (buildType.name == "release" && flavorName.startsWith("orange")) { + versionCodeOverride = getGitRevCount() + versionNameOverride = "$versionName+${getGitSha()}" + } + outputFileName = "Pachli_${versionName}_${versionCode}_${getGitSha()}_${flavorName}_${buildType.name}.apk" + } + } +} + +configurations { + // JNI-only libraries don't play nicely with Robolectric + // see https://github.com/tuskyapp/Tusky/pull/3367 and + // https://github.com/google/conscrypt/issues/649 + testImplementation { + exclude(group = "org.conscrypt", module = "conscrypt-android") + } +} + +aboutLibraries { + configPath = "licenses" + includePlatform = false + duplicationMode = com.mikepenz.aboutlibraries.plugin.DuplicateMode.MERGE + prettyPrint = true +} + +markdown2resource { + files.add(layout.projectDirectory.file("../PRIVACY.md")) +} + +dependencies { + // CachedTimelineRemoteMediator needs the @Transaction annotation from Room + compileOnly(libs.bundles.room) + testCompileOnly(libs.bundles.room) + + implementation(projects.core.accounts) + implementation(projects.core.common) + implementation(projects.core.database) + implementation(projects.core.network) + implementation(projects.core.preferences) + + implementation(libs.kotlinx.coroutines.android) + implementation(libs.kotlinx.coroutines.rx3) + + implementation(libs.bundles.androidx) + + implementation(libs.android.material) + + implementation(libs.gson) + + implementation(libs.bundles.retrofit) + implementation(libs.networkresult.calladapter) + + implementation(libs.bundles.okhttp) + + implementation(libs.conscrypt.android) + + implementation(libs.bundles.glide) + ksp(libs.glide.compiler) + + implementation(libs.bundles.rxjava3) + + implementation(libs.bundles.autodispose) + + implementation(libs.sparkbutton) + + implementation(libs.touchimageview) + + implementation(libs.bundles.material.drawer) + implementation(libs.material.typeface) + + implementation(libs.image.cropper) + + implementation(libs.bundles.filemojicompat) + + implementation(libs.bouncycastle) + implementation(libs.unified.push) + + implementation(libs.bundles.xmldiff) + + implementation(libs.bundles.aboutlibraries) + implementation(libs.timber) + + googleImplementation(libs.app.update) + googleImplementation(libs.app.update.ktx) + + implementation(libs.kotlin.result) + implementation(libs.semver) + + testImplementation(projects.core.testing) + testImplementation(libs.androidx.test.junit) + testImplementation(libs.robolectric) + testImplementation(libs.bundles.mockito) + testImplementation(libs.androidx.core.testing) + testImplementation(libs.kotlinx.coroutines.test) + testImplementation(libs.androidx.work.testing) + testImplementation(libs.truth) + testImplementation(libs.turbine) + testImplementation(libs.androidx.test.core.ktx) + + androidTestImplementation(libs.espresso.core) + androidTestImplementation(libs.androidx.room.testing) + androidTestImplementation(libs.androidx.test.junit) + androidTestImplementation(libs.androidx.test.core.ktx) + + lintChecks(projects.checks) +} diff --git a/app/lint-baseline.xml b/app/lint-baseline.xml index a42bd047a..f964741e3 100644 --- a/app/lint-baseline.xml +++ b/app/lint-baseline.xml @@ -1,5 +1,5 @@ - + @@ -960,7 +960,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~"> @@ -2075,72 +2075,6 @@ column="9"/> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -2830,7 +2742,7 @@ errorLine2=" ~~~~~~"> @@ -2962,7 +2874,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2973,7 +2885,7 @@ errorLine2=" ~~~~~~~~~~~~~"> @@ -2984,7 +2896,7 @@ errorLine2=" ~~~~~~~"> @@ -2995,7 +2907,7 @@ errorLine2=" ~~~~~~~"> @@ -3006,7 +2918,7 @@ errorLine2=" ~~~~~~~"> @@ -3017,7 +2929,7 @@ errorLine2=" ~~~~~~~"> @@ -3028,7 +2940,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~"> @@ -3039,7 +2951,7 @@ errorLine2=" ~~~~~~~"> @@ -3050,7 +2962,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~"> @@ -3061,7 +2973,7 @@ errorLine2=" ~~~~~~~"> @@ -3072,7 +2984,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~"> @@ -3083,7 +2995,7 @@ errorLine2=" ~~~~~~~"> @@ -3094,7 +3006,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~"> @@ -3105,7 +3017,7 @@ errorLine2=" ~~~~~~~"> @@ -3116,7 +3028,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~"> @@ -3127,7 +3039,7 @@ errorLine2=" ~~~~~~~"> @@ -3138,7 +3050,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~"> @@ -3149,7 +3061,7 @@ errorLine2=" ~~~~~~~"> @@ -3160,7 +3072,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~"> @@ -3171,7 +3083,7 @@ errorLine2=" ~~~~~~~"> @@ -3182,7 +3094,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~"> @@ -3193,7 +3105,7 @@ errorLine2=" ~~~~~~~"> @@ -3204,7 +3116,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~"> @@ -3215,7 +3127,7 @@ errorLine2=" ~~~~~~~"> @@ -3226,7 +3138,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~"> @@ -3237,7 +3149,7 @@ errorLine2=" ~~~~~~~"> @@ -3248,7 +3160,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~"> @@ -3259,7 +3171,7 @@ errorLine2=" ~~~~~~~"> @@ -3270,7 +3182,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~"> @@ -3281,7 +3193,7 @@ errorLine2=" ~~~~~~~"> @@ -3292,7 +3204,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~"> @@ -3303,7 +3215,7 @@ errorLine2=" ~~~~~~~"> @@ -3314,7 +3226,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~"> @@ -3325,7 +3237,7 @@ errorLine2=" ~~~~~~~"> @@ -3336,7 +3248,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~"> @@ -3347,7 +3259,7 @@ errorLine2=" ~~~~~~~"> @@ -3358,7 +3270,7 @@ errorLine2=" ~~~~~~~"> @@ -3369,7 +3281,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -3380,7 +3292,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -3611,7 +3523,7 @@ errorLine2=" ~~~~~~~~~"> @@ -3633,7 +3545,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -3644,7 +3556,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> @@ -3655,7 +3567,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~"> @@ -3688,7 +3600,7 @@ errorLine2=" ~~~~~~~~~"> @@ -3699,7 +3611,7 @@ errorLine2=" ~~~~~~~~"> @@ -3710,7 +3622,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~"> @@ -3721,7 +3633,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~"> @@ -5147,7 +5059,7 @@ errorLine2=" ^"> @@ -5158,7 +5070,7 @@ errorLine2=" ^"> diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index a0bd7df42..a454aab11 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -4,10 +4,8 @@ -optimizations !code/simplification/cast,!field/*,!class/merging/* -optimizationpasses 6 -allowaccessmodification --dontpreverify -dontusemixedcaseclassnames --dontskipnonpubliclibraryclasses -keepattributes *Annotation* # For native methods, see http://proguard.sourceforge.net/manual/examples.html#native @@ -40,18 +38,17 @@ # Pachli specific options # keep members of our model classes, they are used in json de/serialization --keepclassmembers class app.pachli.entity.* { *; } --keepclassmembers class app.pachli.network.model.* { *; } +-keepclassmembers class app.pachli.core.network.model.* { *; } --keep public enum app.pachli.entity.*$** { +-keep public enum app.pachli.core.network.model.*$** { **[] $VALUES; public *; } --keepclassmembers class app.pachli.components.conversation.ConversationAccountEntity { *; } --keepclassmembers class app.pachli.db.DraftAttachment { *; } +-keepclassmembers class app.pachli.core.database.model.ConversationAccountEntity { *; } +-keepclassmembers class app.pachli.core.database.model.DraftAttachment { *; } --keep enum app.pachli.db.DraftAttachment$Type { +-keep enum app.pachli.core.database.model.DraftAttachment$Type { public *; } diff --git a/app/src/fdroid/kotlin/app/pachli/updatecheck/UpdateCheck.kt b/app/src/fdroid/kotlin/app/pachli/updatecheck/UpdateCheck.kt index 99556cfb8..2d433380f 100644 --- a/app/src/fdroid/kotlin/app/pachli/updatecheck/UpdateCheck.kt +++ b/app/src/fdroid/kotlin/app/pachli/updatecheck/UpdateCheck.kt @@ -20,7 +20,7 @@ package app.pachli.updatecheck import android.content.Intent import android.net.Uri import app.pachli.BuildConfig -import app.pachli.util.SharedPreferencesRepository +import app.pachli.core.preferences.SharedPreferencesRepository import javax.inject.Inject import javax.inject.Singleton diff --git a/app/src/github/kotlin/app/pachli/updatecheck/UpdateCheck.kt b/app/src/github/kotlin/app/pachli/updatecheck/UpdateCheck.kt index e79a43c5e..86dda2292 100644 --- a/app/src/github/kotlin/app/pachli/updatecheck/UpdateCheck.kt +++ b/app/src/github/kotlin/app/pachli/updatecheck/UpdateCheck.kt @@ -19,7 +19,7 @@ package app.pachli.updatecheck import android.content.Intent import android.net.Uri -import app.pachli.util.SharedPreferencesRepository +import app.pachli.core.preferences.SharedPreferencesRepository import javax.inject.Inject class UpdateCheck @Inject constructor( diff --git a/app/src/google/kotlin/app/pachli/updatecheck/UpdateCheck.kt b/app/src/google/kotlin/app/pachli/updatecheck/UpdateCheck.kt index cbffc1a09..f0816e227 100644 --- a/app/src/google/kotlin/app/pachli/updatecheck/UpdateCheck.kt +++ b/app/src/google/kotlin/app/pachli/updatecheck/UpdateCheck.kt @@ -20,7 +20,7 @@ package app.pachli.updatecheck import android.content.Intent import android.net.Uri import app.pachli.BuildConfig -import app.pachli.util.SharedPreferencesRepository +import app.pachli.core.preferences.SharedPreferencesRepository import com.google.android.play.core.appupdate.AppUpdateManager import kotlinx.coroutines.suspendCancellableCoroutine import javax.inject.Inject diff --git a/app/src/main/java/app/pachli/AccountsInListFragment.kt b/app/src/main/java/app/pachli/AccountsInListFragment.kt index 110107569..e1dc58f77 100644 --- a/app/src/main/java/app/pachli/AccountsInListFragment.kt +++ b/app/src/main/java/app/pachli/AccountsInListFragment.kt @@ -29,13 +29,13 @@ import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.ListAdapter +import app.pachli.core.network.model.TimelineAccount +import app.pachli.core.preferences.PrefKeys +import app.pachli.core.preferences.SharedPreferencesRepository import app.pachli.databinding.FragmentAccountsInListBinding import app.pachli.databinding.ItemFollowRequestBinding -import app.pachli.entity.TimelineAccount -import app.pachli.settings.PrefKeys import app.pachli.util.BindingHolder import app.pachli.util.Either -import app.pachli.util.SharedPreferencesRepository import app.pachli.util.emojify import app.pachli.util.hide import app.pachli.util.loadAvatar diff --git a/app/src/main/java/app/pachli/BaseActivity.kt b/app/src/main/java/app/pachli/BaseActivity.kt index 27b7f5901..d12bb25f1 100644 --- a/app/src/main/java/app/pachli/BaseActivity.kt +++ b/app/src/main/java/app/pachli/BaseActivity.kt @@ -35,16 +35,16 @@ import androidx.core.content.ContextCompat import app.pachli.MainActivity.Companion.redirectIntent import app.pachli.adapter.AccountSelectionAdapter import app.pachli.components.login.LoginActivity -import app.pachli.db.AccountEntity -import app.pachli.db.AccountManager +import app.pachli.core.accounts.AccountManager +import app.pachli.core.database.model.AccountEntity +import app.pachli.core.preferences.PrefKeys +import app.pachli.core.preferences.PrefKeys.APP_THEME +import app.pachli.core.preferences.SharedPreferencesRepository import app.pachli.interfaces.AccountSelectionListener import app.pachli.interfaces.PermissionRequester -import app.pachli.settings.PrefKeys -import app.pachli.settings.PrefKeys.APP_THEME import app.pachli.util.APP_THEME_DEFAULT import app.pachli.util.EmbeddedFontFamily import app.pachli.util.EmbeddedFontFamily.Companion.from -import app.pachli.util.SharedPreferencesRepository import app.pachli.util.THEME_BLACK import com.google.android.material.color.MaterialColors import com.google.android.material.snackbar.Snackbar diff --git a/app/src/main/java/app/pachli/BottomSheetActivity.kt b/app/src/main/java/app/pachli/BottomSheetActivity.kt index 4430ef3c1..169aba027 100644 --- a/app/src/main/java/app/pachli/BottomSheetActivity.kt +++ b/app/src/main/java/app/pachli/BottomSheetActivity.kt @@ -26,7 +26,7 @@ import androidx.annotation.VisibleForTesting import androidx.lifecycle.lifecycleScope import app.pachli.components.account.AccountActivity import app.pachli.components.viewthread.ViewThreadActivity -import app.pachli.network.MastodonApi +import app.pachli.core.network.retrofit.MastodonApi import app.pachli.util.looksLikeMastodonUrl import app.pachli.util.openLink import at.connyduck.calladapter.networkresult.fold diff --git a/app/src/main/java/app/pachli/ListsActivity.kt b/app/src/main/java/app/pachli/ListsActivity.kt index 2301bc1d7..4ac77bacd 100644 --- a/app/src/main/java/app/pachli/ListsActivity.kt +++ b/app/src/main/java/app/pachli/ListsActivity.kt @@ -36,9 +36,9 @@ import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView +import app.pachli.core.network.model.MastoList import app.pachli.databinding.ActivityListsBinding import app.pachli.databinding.DialogListBinding -import app.pachli.entity.MastoList import app.pachli.util.hide import app.pachli.util.show import app.pachli.util.viewBinding @@ -134,13 +134,9 @@ class ListsActivity : BaseActivity() { editText.text?.let { editText.setSelection(it.length) } } - list?.let { - if (it.exclusive == null) { - binding.exclusiveCheckbox.visible(false) - } else { - binding.exclusiveCheckbox.isChecked = it.exclusive - } - } + list?.exclusive?.let { + binding.exclusiveCheckbox.isChecked = isTaskRoot + } ?: binding.exclusiveCheckbox.hide() } private fun showListDeleteDialog(list: MastoList) { diff --git a/app/src/main/java/app/pachli/MainActivity.kt b/app/src/main/java/app/pachli/MainActivity.kt index c379c4121..f71615f29 100644 --- a/app/src/main/java/app/pachli/MainActivity.kt +++ b/app/src/main/java/app/pachli/MainActivity.kt @@ -77,17 +77,18 @@ import app.pachli.components.preference.PreferencesActivity import app.pachli.components.scheduled.ScheduledStatusActivity import app.pachli.components.search.SearchActivity import app.pachli.components.trending.TrendingActivity +import app.pachli.core.database.model.AccountEntity +import app.pachli.core.database.model.TabKind +import app.pachli.core.network.model.Account +import app.pachli.core.network.model.Notification +import app.pachli.core.preferences.PrefKeys import app.pachli.databinding.ActivityMainBinding -import app.pachli.db.AccountEntity import app.pachli.db.DraftsAlert -import app.pachli.entity.Account -import app.pachli.entity.Notification import app.pachli.interfaces.AccountSelectionListener import app.pachli.interfaces.ActionButtonActivity import app.pachli.interfaces.FabFragment import app.pachli.interfaces.ReselectableFragment import app.pachli.pager.MainPagerAdapter -import app.pachli.settings.PrefKeys import app.pachli.updatecheck.UpdateCheck import app.pachli.updatecheck.UpdateNotificationFrequency import app.pachli.usecase.DeveloperToolsUseCase @@ -854,7 +855,7 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider { // Save the previous tab so it can be restored later val previousTab = tabAdapter.tabs.getOrNull(binding.viewPager.currentItem) - val tabs = accountManager.activeAccount!!.tabPreferences + val tabs = accountManager.activeAccount!!.tabPreferences.map { TabViewData.from(it) } // Detach any existing mediator before changing tab contents and attaching a new mediator tabLayoutMediator?.detach() @@ -865,8 +866,8 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider { tabLayoutMediator = TabLayoutMediator(activeTabLayout, binding.viewPager, true) { tab: TabLayout.Tab, position: Int -> tab.icon = AppCompatResources.getDrawable(this@MainActivity, tabs[position].icon) - tab.contentDescription = when (tabs[position].id) { - LIST -> tabs[position].arguments[1] + tab.contentDescription = when (tabs[position].kind) { + TabKind.LIST -> tabs[position].arguments[1] else -> getString(tabs[position].text) } }.also { it.attach() } @@ -876,7 +877,7 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider { // - The previously selected tab (if it hasn't been removed) // - Left-most tab val position = if (selectNotificationTab) { - tabs.indexOfFirst { it.id == NOTIFICATIONS } + tabs.indexOfFirst { it.kind == TabKind.NOTIFICATIONS } } else { previousTab?.let { tabs.indexOfFirst { it == previousTab } } }.takeIf { it != -1 } ?: 0 diff --git a/app/src/main/java/app/pachli/PachliApplication.kt b/app/src/main/java/app/pachli/PachliApplication.kt index fb12d9c77..341a0eae7 100644 --- a/app/src/main/java/app/pachli/PachliApplication.kt +++ b/app/src/main/java/app/pachli/PachliApplication.kt @@ -24,13 +24,13 @@ import androidx.work.ExistingPeriodicWorkPolicy import androidx.work.PeriodicWorkRequestBuilder import androidx.work.WorkManager import app.pachli.components.notifications.createWorkerNotificationChannel -import app.pachli.settings.NEW_INSTALL_SCHEMA_VERSION -import app.pachli.settings.PrefKeys -import app.pachli.settings.PrefKeys.APP_THEME -import app.pachli.settings.SCHEMA_VERSION +import app.pachli.core.preferences.NEW_INSTALL_SCHEMA_VERSION +import app.pachli.core.preferences.PrefKeys +import app.pachli.core.preferences.PrefKeys.APP_THEME +import app.pachli.core.preferences.SCHEMA_VERSION +import app.pachli.core.preferences.SharedPreferencesRepository import app.pachli.util.APP_THEME_DEFAULT import app.pachli.util.LocaleManager -import app.pachli.util.SharedPreferencesRepository import app.pachli.util.setAppNightMode import app.pachli.worker.PruneCacheWorker import app.pachli.worker.WorkerFactory diff --git a/app/src/main/java/app/pachli/SplashActivity.kt b/app/src/main/java/app/pachli/SplashActivity.kt index f02665309..0d966fc45 100644 --- a/app/src/main/java/app/pachli/SplashActivity.kt +++ b/app/src/main/java/app/pachli/SplashActivity.kt @@ -23,7 +23,7 @@ import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import app.pachli.components.login.LoginActivity -import app.pachli.db.AccountManager +import app.pachli.core.accounts.AccountManager import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject diff --git a/app/src/main/java/app/pachli/StatusListActivity.kt b/app/src/main/java/app/pachli/StatusListActivity.kt index fb7d5ab17..e490a0c64 100644 --- a/app/src/main/java/app/pachli/StatusListActivity.kt +++ b/app/src/main/java/app/pachli/StatusListActivity.kt @@ -29,9 +29,9 @@ import app.pachli.appstore.FilterChangedEvent import app.pachli.components.compose.ComposeActivity import app.pachli.components.timeline.TimelineFragment import app.pachli.components.timeline.TimelineKind +import app.pachli.core.network.model.Filter +import app.pachli.core.network.model.FilterV1 import app.pachli.databinding.ActivityStatuslistBinding -import app.pachli.entity.Filter -import app.pachli.entity.FilterV1 import app.pachli.interfaces.ActionButtonActivity import app.pachli.interfaces.AppBarLayoutHost import app.pachli.util.unsafeLazy diff --git a/app/src/main/java/app/pachli/TabData.kt b/app/src/main/java/app/pachli/TabData.kt deleted file mode 100644 index 19e3af4a4..000000000 --- a/app/src/main/java/app/pachli/TabData.kt +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright 2019 Conny Duck - * - * This file is a part of Pachli. - * - * This program is free software; you can redistribute it and/or modify it under the terms of the - * GNU General Public License as published by the Free Software Foundation; either version 3 of the - * License, or (at your option) any later version. - * - * Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even - * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General - * Public License for more details. - * - * You should have received a copy of the GNU General Public License along with Pachli; if not, - * see . - */ - -package app.pachli - -import android.content.Context -import androidx.annotation.DrawableRes -import androidx.annotation.StringRes -import androidx.fragment.app.Fragment -import app.pachli.components.conversation.ConversationsFragment -import app.pachli.components.notifications.NotificationsFragment -import app.pachli.components.timeline.TimelineFragment -import app.pachli.components.timeline.TimelineKind -import app.pachli.components.trending.TrendingLinksFragment -import app.pachli.components.trending.TrendingTagsFragment -import java.util.Objects - -/** this would be a good case for a sealed class, but that does not work nice with Room */ - -const val HOME = "Home" -const val NOTIFICATIONS = "Notifications" -const val LOCAL = "Local" -const val FEDERATED = "Federated" -const val DIRECT = "Direct" -const val TRENDING_TAGS = "TrendingTags" -const val TRENDING_LINKS = "TrendingLinks" -const val TRENDING_STATUSES = "TrendingStatuses" -const val HASHTAG = "Hashtag" -const val LIST = "List" -const val BOOKMARKS = "Bookmarks" - -data class TabData( - val id: String, - @StringRes val text: Int, - @DrawableRes val icon: Int, - val fragment: (List) -> Fragment, - val arguments: List = emptyList(), - val title: (Context) -> String = { context -> context.getString(text) }, -) { - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - - other as TabData - - if (id != other.id) return false - return arguments == other.arguments - } - - override fun hashCode() = Objects.hash(id, arguments) -} - -fun createTabDataFromId(id: String, arguments: List = emptyList()): TabData { - return when (id) { - HOME -> TabData( - id = HOME, - text = R.string.title_home, - icon = R.drawable.ic_home_24dp, - fragment = { TimelineFragment.newInstance(TimelineKind.Home) }, - ) - NOTIFICATIONS -> TabData( - id = NOTIFICATIONS, - text = R.string.title_notifications, - icon = R.drawable.ic_notifications_24dp, - fragment = { NotificationsFragment.newInstance() }, - ) - LOCAL -> TabData( - id = LOCAL, - text = R.string.title_public_local, - icon = R.drawable.ic_local_24dp, - fragment = { TimelineFragment.newInstance(TimelineKind.PublicLocal) }, - ) - FEDERATED -> TabData( - id = FEDERATED, - text = R.string.title_public_federated, - icon = R.drawable.ic_public_24dp, - fragment = { TimelineFragment.newInstance(TimelineKind.PublicFederated) }, - ) - DIRECT -> TabData( - id = DIRECT, - text = R.string.title_direct_messages, - icon = R.drawable.ic_reblog_direct_24dp, - fragment = { ConversationsFragment.newInstance() }, - ) - TRENDING_TAGS -> TabData( - id = TRENDING_TAGS, - text = R.string.title_public_trending_hashtags, - icon = R.drawable.ic_trending_up_24px, - fragment = { TrendingTagsFragment.newInstance() }, - ) - TRENDING_LINKS -> TabData( - id = TRENDING_LINKS, - text = R.string.title_public_trending_links, - icon = R.drawable.ic_trending_up_24px, - fragment = { TrendingLinksFragment.newInstance() }, - ) - TRENDING_STATUSES -> TabData( - id = TRENDING_STATUSES, - text = R.string.title_public_trending_statuses, - icon = R.drawable.ic_trending_up_24px, - fragment = { TimelineFragment.newInstance(TimelineKind.TrendingStatuses) }, - ) - HASHTAG -> TabData( - id = HASHTAG, - text = R.string.hashtags, - icon = R.drawable.ic_hashtag, - fragment = { args -> TimelineFragment.newInstance(TimelineKind.Tag(args)) }, - arguments = arguments, - title = { context -> arguments.joinToString(separator = " ") { context.getString(R.string.title_tag, it) } }, - ) - LIST -> TabData( - id = LIST, - text = R.string.list, - icon = R.drawable.ic_list, - fragment = { args -> TimelineFragment.newInstance(TimelineKind.UserList(args.first(), args.last())) }, - arguments = arguments, - title = { arguments.getOrNull(1).orEmpty() }, - ) - BOOKMARKS -> TabData( - id = BOOKMARKS, - text = R.string.title_bookmarks, - icon = R.drawable.ic_bookmark_active_24dp, - fragment = { TimelineFragment.newInstance(TimelineKind.Bookmarks) }, - ) - else -> throw IllegalArgumentException("unknown tab type") - } -} - -fun defaultTabs(): List { - return listOf( - createTabDataFromId(HOME), - createTabDataFromId(NOTIFICATIONS), - createTabDataFromId(LOCAL), - createTabDataFromId(DIRECT), - ) -} diff --git a/app/src/main/java/app/pachli/TabPreferenceActivity.kt b/app/src/main/java/app/pachli/TabPreferenceActivity.kt index 834f680ac..9dd740b16 100644 --- a/app/src/main/java/app/pachli/TabPreferenceActivity.kt +++ b/app/src/main/java/app/pachli/TabPreferenceActivity.kt @@ -42,9 +42,11 @@ import app.pachli.adapter.ItemInteractionListener import app.pachli.adapter.TabAdapter import app.pachli.appstore.EventHub import app.pachli.appstore.MainTabsChangedEvent +import app.pachli.core.database.model.TabData +import app.pachli.core.database.model.TabKind +import app.pachli.core.network.model.MastoList +import app.pachli.core.network.retrofit.MastodonApi import app.pachli.databinding.ActivityTabPreferenceBinding -import app.pachli.entity.MastoList -import app.pachli.network.MastodonApi import app.pachli.util.getDimension import app.pachli.util.hide import app.pachli.util.show @@ -78,7 +80,7 @@ class TabPreferenceActivity : BaseActivity(), ItemInteractionListener { private val binding by viewBinding(ActivityTabPreferenceBinding::inflate) - private lateinit var currentTabs: MutableList + private lateinit var currentTabs: MutableList private lateinit var currentTabsAdapter: TabAdapter private lateinit var touchHelper: ItemTouchHelper private lateinit var addTabAdapter: TabAdapter @@ -108,7 +110,7 @@ class TabPreferenceActivity : BaseActivity(), ItemInteractionListener { setDisplayShowHomeEnabled(true) } - currentTabs = accountManager.activeAccount?.tabPreferences.orEmpty().toMutableList() + currentTabs = accountManager.activeAccount?.tabPreferences.orEmpty().map { TabViewData.from(it) }.toMutableList() currentTabsAdapter = TabAdapter(currentTabs, false, this, currentTabs.size <= MIN_TAB_COUNT) binding.currentTabsRecyclerView.adapter = currentTabsAdapter binding.currentTabsRecyclerView.layoutManager = LinearLayoutManager(this) @@ -116,7 +118,7 @@ class TabPreferenceActivity : BaseActivity(), ItemInteractionListener { MaterialDividerItemDecoration(this, MaterialDividerItemDecoration.VERTICAL), ) - addTabAdapter = TabAdapter(listOf(createTabDataFromId(DIRECT)), true, this) + addTabAdapter = TabAdapter(listOf(TabViewData.from(TabData(TabKind.DIRECT))), true, this) binding.addTabRecyclerView.adapter = addTabAdapter binding.addTabRecyclerView.layoutManager = LinearLayoutManager(this) @@ -176,15 +178,15 @@ class TabPreferenceActivity : BaseActivity(), ItemInteractionListener { onBackPressedDispatcher.addCallback(onFabDismissedCallback) } - override fun onTabAdded(tab: TabData) { + override fun onTabAdded(tab: TabViewData) { toggleFab(false) - if (tab.id == HASHTAG) { + if (tab.kind == TabKind.HASHTAG) { showAddHashtagDialog() return } - if (tab.id == LIST) { + if (tab.kind == TabKind.LIST) { showSelectListDialog() return } @@ -202,13 +204,13 @@ class TabPreferenceActivity : BaseActivity(), ItemInteractionListener { saveTabs() } - override fun onActionChipClicked(tab: TabData, tabPosition: Int) { + override fun onActionChipClicked(tab: TabViewData, tabPosition: Int) { showAddHashtagDialog(tab, tabPosition) } - override fun onChipClicked(tab: TabData, tabPosition: Int, chipPosition: Int) { + override fun onChipClicked(tab: TabViewData, tabPosition: Int, chipPosition: Int) { val newArguments = tab.arguments.filterIndexed { i, _ -> i != chipPosition } - val newTab = tab.copy(arguments = newArguments) + val newTab = tab.copy(tabData = tab.tabData.copy(arguments = newArguments)) currentTabs[tabPosition] = newTab saveTabs() @@ -233,7 +235,7 @@ class TabPreferenceActivity : BaseActivity(), ItemInteractionListener { onFabDismissedCallback.isEnabled = expand } - private fun showAddHashtagDialog(tab: TabData? = null, tabPosition: Int = 0) { + private fun showAddHashtagDialog(tab: TabViewData? = null, tabPosition: Int = 0) { val frameLayout = FrameLayout(this) val padding = Utils.dpToPx(this, 8) frameLayout.updatePadding(left = padding, right = padding) @@ -250,11 +252,11 @@ class TabPreferenceActivity : BaseActivity(), ItemInteractionListener { .setPositiveButton(R.string.action_save) { _, _ -> val input = editText.text.toString().trim() if (tab == null) { - val newTab = createTabDataFromId(HASHTAG, listOf(input)) + val newTab = TabViewData.from(TabData(TabKind.HASHTAG, listOf(input))) currentTabs.add(newTab) currentTabsAdapter.notifyItemInserted(currentTabs.size - 1) } else { - val newTab = tab.copy(arguments = tab.arguments + input) + val newTab = tab.copy(tabData = tab.tabData.copy(arguments = tab.arguments + input)) currentTabs[tabPosition] = newTab currentTabsAdapter.notifyItemChanged(tabPosition) @@ -308,7 +310,7 @@ class TabPreferenceActivity : BaseActivity(), ItemInteractionListener { .setView(statusLayout) .setAdapter(adapter) { _, position -> adapter.getItem(position)?.let { item -> - val newTab = createTabDataFromId(LIST, listOf(item.id, item.title)) + val newTab = TabViewData.from(TabData(TabKind.LIST, listOf(item.id, item.title))) currentTabs.add(newTab) currentTabsAdapter.notifyItemInserted(currentTabs.size - 1) updateAvailableTabs() @@ -357,46 +359,47 @@ class TabPreferenceActivity : BaseActivity(), ItemInteractionListener { } private fun updateAvailableTabs() { - val addableTabs: MutableList = mutableListOf() + val addableTabs: MutableList = mutableListOf() - val homeTab = createTabDataFromId(HOME) + val homeTab = TabViewData.from(TabData(TabKind.HOME)) if (!currentTabs.contains(homeTab)) { addableTabs.add(homeTab) } - val notificationTab = createTabDataFromId(NOTIFICATIONS) + val notificationTab = TabViewData.from(TabData(TabKind.NOTIFICATIONS)) if (!currentTabs.contains(notificationTab)) { addableTabs.add(notificationTab) } - val localTab = createTabDataFromId(LOCAL) + val localTab = TabViewData.from(TabData(TabKind.LOCAL)) if (!currentTabs.contains(localTab)) { addableTabs.add(localTab) } - val federatedTab = createTabDataFromId(FEDERATED) + val federatedTab = TabViewData.from(TabData(TabKind.FEDERATED)) if (!currentTabs.contains(federatedTab)) { addableTabs.add(federatedTab) } - val directMessagesTab = createTabDataFromId(DIRECT) + val directMessagesTab = TabViewData.from(TabData(TabKind.DIRECT)) if (!currentTabs.contains(directMessagesTab)) { addableTabs.add(directMessagesTab) } - val trendingTagsTab = createTabDataFromId(TRENDING_TAGS) + val trendingTagsTab = TabViewData.from(TabData(TabKind.TRENDING_TAGS)) if (!currentTabs.contains(trendingTagsTab)) { addableTabs.add(trendingTagsTab) } - val trendingLinksTab = createTabDataFromId(TRENDING_LINKS) + val trendingLinksTab = TabViewData.from(TabData(TabKind.TRENDING_LINKS)) if (!currentTabs.contains(trendingLinksTab)) { addableTabs.add(trendingLinksTab) } - createTabDataFromId(TRENDING_STATUSES).apply { - currentTabs.contains(this) || addableTabs.add(this) + val trendingStatusesTab = TabViewData.from(TabData(TabKind.TRENDING_STATUSES)) + if (!currentTabs.contains(trendingStatusesTab)) { + addableTabs.add(trendingStatusesTab) } - val bookmarksTab = createTabDataFromId(BOOKMARKS) + val bookmarksTab = TabViewData.from(TabData(TabKind.BOOKMARKS)) if (!currentTabs.contains(trendingTagsTab)) { addableTabs.add(bookmarksTab) } - addableTabs.add(createTabDataFromId(HASHTAG)) - addableTabs.add(createTabDataFromId(LIST)) + addableTabs.add(TabViewData.from(TabData(TabKind.HASHTAG))) + addableTabs.add(TabViewData.from(TabData(TabKind.LIST))) addTabAdapter.updateData(addableTabs) @@ -414,7 +417,7 @@ class TabPreferenceActivity : BaseActivity(), ItemInteractionListener { private fun saveTabs() { accountManager.activeAccount?.let { lifecycleScope.launch(Dispatchers.IO) { - it.tabPreferences = currentTabs + it.tabPreferences = currentTabs.map { it.tabData } accountManager.saveAccount(it) } } @@ -425,7 +428,7 @@ class TabPreferenceActivity : BaseActivity(), ItemInteractionListener { super.onPause() if (tabsChanged) { lifecycleScope.launch { - eventHub.dispatch(MainTabsChangedEvent(currentTabs)) + eventHub.dispatch(MainTabsChangedEvent(currentTabs.map { it.tabData })) } } } diff --git a/app/src/main/java/app/pachli/TabViewData.kt b/app/src/main/java/app/pachli/TabViewData.kt new file mode 100644 index 000000000..3e653bc1f --- /dev/null +++ b/app/src/main/java/app/pachli/TabViewData.kt @@ -0,0 +1,152 @@ +/* + * Copyright 2023 Pachli Association + * + * This file is a part of Pachli. + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Pachli; if not, + * see . + */ + +package app.pachli + +import android.content.Context +import androidx.annotation.DrawableRes +import androidx.annotation.StringRes +import androidx.fragment.app.Fragment +import app.pachli.components.conversation.ConversationsFragment +import app.pachli.components.notifications.NotificationsFragment +import app.pachli.components.timeline.TimelineFragment +import app.pachli.components.timeline.TimelineKind +import app.pachli.components.trending.TrendingLinksFragment +import app.pachli.components.trending.TrendingTagsFragment +import app.pachli.core.database.model.TabData +import app.pachli.core.database.model.TabKind + +/** + * Wrap a [TabData] with additional information to display a tab with that data. + * + * @param tabData wrapped [TabData] + * @param text text to use for this tab when displayed in lists + * @param icon icon to use when displaying the tab + * @param fragment [Fragment] to display the tab's contents + * @param title title to display in the action bar if this tab is active + */ +data class TabViewData( + val tabData: TabData, + @StringRes val text: Int, + @DrawableRes val icon: Int, + val fragment: (List) -> Fragment, + val title: (Context) -> String = { context -> context.getString(text) }, +) { + val kind get() = this.tabData.kind + + val arguments get() = this.tabData.arguments + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as TabViewData + + if (tabData != other.tabData) return false + + return true + } + + override fun hashCode() = tabData.hashCode() + + companion object { + fun from(tabKind: TabKind) = from(TabData.from(tabKind)) + + fun from(tabData: TabData) = when (tabData.kind) { + TabKind.HOME -> TabViewData( + tabData = tabData, + text = R.string.title_home, + icon = R.drawable.ic_home_24dp, + fragment = { TimelineFragment.newInstance(TimelineKind.Home) }, + ) + TabKind.NOTIFICATIONS -> TabViewData( + tabData = tabData, + text = R.string.title_notifications, + icon = R.drawable.ic_notifications_24dp, + fragment = { NotificationsFragment.newInstance() }, + ) + TabKind.LOCAL -> TabViewData( + tabData = tabData, + text = R.string.title_public_local, + icon = R.drawable.ic_local_24dp, + fragment = { TimelineFragment.newInstance(TimelineKind.PublicLocal) }, + ) + TabKind.FEDERATED -> TabViewData( + tabData = tabData, + text = R.string.title_public_federated, + icon = R.drawable.ic_public_24dp, + fragment = { TimelineFragment.newInstance(TimelineKind.PublicFederated) }, + ) + TabKind.DIRECT -> TabViewData( + tabData = tabData, + text = R.string.title_direct_messages, + icon = R.drawable.ic_reblog_direct_24dp, + fragment = { ConversationsFragment.newInstance() }, + ) + TabKind.TRENDING_TAGS -> TabViewData( + tabData = tabData, + text = R.string.title_public_trending_hashtags, + icon = R.drawable.ic_trending_up_24px, + fragment = { TrendingTagsFragment.newInstance() }, + ) + TabKind.TRENDING_LINKS -> TabViewData( + tabData = tabData, + text = R.string.title_public_trending_links, + icon = R.drawable.ic_trending_up_24px, + fragment = { TrendingLinksFragment.newInstance() }, + ) + TabKind.TRENDING_STATUSES -> TabViewData( + tabData = tabData, + text = R.string.title_public_trending_statuses, + icon = R.drawable.ic_trending_up_24px, + fragment = { TimelineFragment.newInstance(TimelineKind.TrendingStatuses) }, + ) + TabKind.HASHTAG -> TabViewData( + tabData = tabData, + text = R.string.hashtags, + icon = R.drawable.ic_hashtag, + fragment = { args -> TimelineFragment.newInstance(TimelineKind.Tag(args)) }, + title = { context -> + tabData.arguments.joinToString(separator = " ") { + context.getString( + R.string.title_tag, + it, + ) + } + }, + ) + TabKind.LIST -> TabViewData( + tabData = tabData, + text = R.string.list, + icon = R.drawable.ic_list, + fragment = { args -> + TimelineFragment.newInstance( + TimelineKind.UserList(args.first(), args.last()), + ) + }, + title = { tabData.arguments.getOrNull(1).orEmpty() }, + ) + TabKind.BOOKMARKS -> TabViewData( + tabData = tabData, + text = R.string.title_bookmarks, + icon = R.drawable.ic_bookmark_active_24dp, + fragment = { TimelineFragment.newInstance(TimelineKind.Bookmarks) }, + ) + else -> throw IllegalArgumentException("unknown tab type: $tabData") + } + } +} diff --git a/app/src/main/java/app/pachli/ViewMediaActivity.kt b/app/src/main/java/app/pachli/ViewMediaActivity.kt index ed9a73210..9e12e3b3f 100644 --- a/app/src/main/java/app/pachli/ViewMediaActivity.kt +++ b/app/src/main/java/app/pachli/ViewMediaActivity.kt @@ -47,8 +47,8 @@ import androidx.viewpager2.adapter.FragmentStateAdapter import androidx.viewpager2.widget.ViewPager2 import app.pachli.BuildConfig.APPLICATION_ID import app.pachli.components.viewthread.ViewThreadActivity +import app.pachli.core.network.model.Attachment import app.pachli.databinding.ActivityViewMediaBinding -import app.pachli.entity.Attachment import app.pachli.fragment.ViewImageFragment import app.pachli.fragment.ViewVideoFragment import app.pachli.pager.ImagePagerAdapter diff --git a/app/src/main/java/app/pachli/adapter/AccountFieldEditAdapter.kt b/app/src/main/java/app/pachli/adapter/AccountFieldEditAdapter.kt index e477765fb..e0ecb589b 100644 --- a/app/src/main/java/app/pachli/adapter/AccountFieldEditAdapter.kt +++ b/app/src/main/java/app/pachli/adapter/AccountFieldEditAdapter.kt @@ -20,8 +20,8 @@ import android.view.LayoutInflater import android.view.ViewGroup import androidx.core.widget.doAfterTextChanged import androidx.recyclerview.widget.RecyclerView +import app.pachli.core.network.model.StringField import app.pachli.databinding.ItemEditFieldBinding -import app.pachli.entity.StringField import app.pachli.util.BindingHolder import app.pachli.util.fixTextSelection diff --git a/app/src/main/java/app/pachli/adapter/AccountSelectionAdapter.kt b/app/src/main/java/app/pachli/adapter/AccountSelectionAdapter.kt index 94423a22d..ae452c8fc 100644 --- a/app/src/main/java/app/pachli/adapter/AccountSelectionAdapter.kt +++ b/app/src/main/java/app/pachli/adapter/AccountSelectionAdapter.kt @@ -23,9 +23,9 @@ import android.view.ViewGroup import android.widget.ArrayAdapter import androidx.preference.PreferenceManager import app.pachli.R +import app.pachli.core.database.model.AccountEntity +import app.pachli.core.preferences.PrefKeys import app.pachli.databinding.ItemAutocompleteAccountBinding -import app.pachli.db.AccountEntity -import app.pachli.settings.PrefKeys import app.pachli.util.emojify import app.pachli.util.loadAvatar diff --git a/app/src/main/java/app/pachli/adapter/AccountViewHolder.kt b/app/src/main/java/app/pachli/adapter/AccountViewHolder.kt index 456dbf570..8b6c1835b 100644 --- a/app/src/main/java/app/pachli/adapter/AccountViewHolder.kt +++ b/app/src/main/java/app/pachli/adapter/AccountViewHolder.kt @@ -19,8 +19,8 @@ package app.pachli.adapter import androidx.recyclerview.widget.RecyclerView import app.pachli.R +import app.pachli.core.network.model.TimelineAccount import app.pachli.databinding.ItemAccountBinding -import app.pachli.entity.TimelineAccount import app.pachli.interfaces.AccountActionListener import app.pachli.interfaces.LinkListener import app.pachli.util.emojify diff --git a/app/src/main/java/app/pachli/adapter/EmojiAdapter.kt b/app/src/main/java/app/pachli/adapter/EmojiAdapter.kt index a53c9e80e..6ce3580b2 100644 --- a/app/src/main/java/app/pachli/adapter/EmojiAdapter.kt +++ b/app/src/main/java/app/pachli/adapter/EmojiAdapter.kt @@ -20,8 +20,8 @@ import android.view.LayoutInflater import android.view.ViewGroup import androidx.appcompat.widget.TooltipCompat import androidx.recyclerview.widget.RecyclerView +import app.pachli.core.network.model.Emoji import app.pachli.databinding.ItemEmojiButtonBinding -import app.pachli.entity.Emoji import app.pachli.util.BindingHolder import com.bumptech.glide.Glide import java.util.Locale @@ -32,7 +32,7 @@ class EmojiAdapter( private val animate: Boolean, ) : RecyclerView.Adapter>() { - private val emojiList: List = emojiList.filter { emoji -> emoji.visibleInPicker == null || emoji.visibleInPicker } + private val emojiList: List = emojiList.filter { emoji -> emoji.visibleInPicker == null || emoji.visibleInPicker!! } .sortedBy { it.shortcode.lowercase(Locale.ROOT) } override fun getItemCount() = emojiList.size diff --git a/app/src/main/java/app/pachli/adapter/FilterableStatusViewHolder.kt b/app/src/main/java/app/pachli/adapter/FilterableStatusViewHolder.kt index d5da21960..f896cdd88 100644 --- a/app/src/main/java/app/pachli/adapter/FilterableStatusViewHolder.kt +++ b/app/src/main/java/app/pachli/adapter/FilterableStatusViewHolder.kt @@ -19,8 +19,8 @@ package app.pachli.adapter import android.view.View import app.pachli.R +import app.pachli.core.network.model.Filter import app.pachli.databinding.ItemStatusWrapperBinding -import app.pachli.entity.Filter import app.pachli.interfaces.StatusActionListener import app.pachli.util.StatusDisplayOptions import app.pachli.viewdata.StatusViewData diff --git a/app/src/main/java/app/pachli/adapter/FollowRequestViewHolder.kt b/app/src/main/java/app/pachli/adapter/FollowRequestViewHolder.kt index ee8b3de63..290b40581 100644 --- a/app/src/main/java/app/pachli/adapter/FollowRequestViewHolder.kt +++ b/app/src/main/java/app/pachli/adapter/FollowRequestViewHolder.kt @@ -24,18 +24,18 @@ import android.text.style.StyleSpan import androidx.recyclerview.widget.RecyclerView import app.pachli.R import app.pachli.components.notifications.NotificationsPagingAdapter +import app.pachli.core.common.string.unicodeWrap +import app.pachli.core.network.model.TimelineAccount +import app.pachli.core.network.parseAsMastodonHtml import app.pachli.databinding.ItemFollowRequestBinding -import app.pachli.entity.TimelineAccount import app.pachli.interfaces.AccountActionListener import app.pachli.interfaces.LinkListener import app.pachli.util.StatusDisplayOptions import app.pachli.util.emojify import app.pachli.util.hide import app.pachli.util.loadAvatar -import app.pachli.util.parseAsMastodonHtml import app.pachli.util.setClickableText import app.pachli.util.show -import app.pachli.util.unicodeWrap import app.pachli.util.visible import app.pachli.viewdata.NotificationViewData diff --git a/app/src/main/java/app/pachli/adapter/PollAdapter.kt b/app/src/main/java/app/pachli/adapter/PollAdapter.kt index 5f91d5775..a7b9a3d36 100644 --- a/app/src/main/java/app/pachli/adapter/PollAdapter.kt +++ b/app/src/main/java/app/pachli/adapter/PollAdapter.kt @@ -20,8 +20,8 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView +import app.pachli.core.network.model.Emoji import app.pachli.databinding.ItemPollBinding -import app.pachli.entity.Emoji import app.pachli.util.BindingHolder import app.pachli.util.emojify import app.pachli.util.visible diff --git a/app/src/main/java/app/pachli/adapter/ReportNotificationViewHolder.kt b/app/src/main/java/app/pachli/adapter/ReportNotificationViewHolder.kt index 940777ab5..a69c766af 100644 --- a/app/src/main/java/app/pachli/adapter/ReportNotificationViewHolder.kt +++ b/app/src/main/java/app/pachli/adapter/ReportNotificationViewHolder.kt @@ -23,14 +23,14 @@ import androidx.recyclerview.widget.RecyclerView import app.pachli.R import app.pachli.components.notifications.NotificationActionListener import app.pachli.components.notifications.NotificationsPagingAdapter +import app.pachli.core.common.string.unicodeWrap +import app.pachli.core.network.model.Report +import app.pachli.core.network.model.TimelineAccount import app.pachli.databinding.ItemReportNotificationBinding -import app.pachli.entity.Report -import app.pachli.entity.TimelineAccount import app.pachli.util.StatusDisplayOptions import app.pachli.util.emojify import app.pachli.util.getRelativeTimeSpanString import app.pachli.util.loadAvatar -import app.pachli.util.unicodeWrap import app.pachli.viewdata.NotificationViewData import at.connyduck.sparkbutton.helpers.Utils import java.util.Date diff --git a/app/src/main/java/app/pachli/adapter/StatusBaseViewHolder.kt b/app/src/main/java/app/pachli/adapter/StatusBaseViewHolder.kt index 282315538..6504a6c7a 100644 --- a/app/src/main/java/app/pachli/adapter/StatusBaseViewHolder.kt +++ b/app/src/main/java/app/pachli/adapter/StatusBaseViewHolder.kt @@ -21,24 +21,26 @@ import androidx.core.text.HtmlCompat import androidx.recyclerview.widget.RecyclerView import app.pachli.R import app.pachli.ViewMediaActivity.Companion.newSingleImageIntent -import app.pachli.entity.Attachment -import app.pachli.entity.Emoji -import app.pachli.entity.PreviewCardKind -import app.pachli.entity.Status -import app.pachli.entity.description +import app.pachli.core.common.util.AbsoluteTimeFormatter +import app.pachli.core.common.util.formatNumber +import app.pachli.core.database.model.TranslationState +import app.pachli.core.network.model.Attachment +import app.pachli.core.network.model.Emoji +import app.pachli.core.network.model.PreviewCardKind +import app.pachli.core.network.model.Status import app.pachli.interfaces.StatusActionListener -import app.pachli.util.AbsoluteTimeFormatter import app.pachli.util.CardViewMode import app.pachli.util.CompositeWithOpaqueBackground import app.pachli.util.StatusDisplayOptions import app.pachli.util.aspectRatios import app.pachli.util.decodeBlurHash +import app.pachli.util.description import app.pachli.util.emojify import app.pachli.util.expandTouchSizeToFillRow -import app.pachli.util.formatNumber import app.pachli.util.getFormattedDescription import app.pachli.util.getRelativeTimeSpanString import app.pachli.util.hide +import app.pachli.util.iconResource import app.pachli.util.loadAvatar import app.pachli.util.makeIcon import app.pachli.util.setClickableMentions @@ -50,7 +52,6 @@ import app.pachli.view.PollView import app.pachli.view.PreviewCardView import app.pachli.viewdata.PollViewData.Companion.from import app.pachli.viewdata.StatusViewData -import app.pachli.viewdata.TranslationState import at.connyduck.sparkbutton.SparkButton import at.connyduck.sparkbutton.helpers.Utils import com.bumptech.glide.Glide diff --git a/app/src/main/java/app/pachli/adapter/StatusDetailedViewHolder.kt b/app/src/main/java/app/pachli/adapter/StatusDetailedViewHolder.kt index 6549bb216..fcfac3a37 100644 --- a/app/src/main/java/app/pachli/adapter/StatusDetailedViewHolder.kt +++ b/app/src/main/java/app/pachli/adapter/StatusDetailedViewHolder.kt @@ -10,14 +10,14 @@ import android.view.View import androidx.recyclerview.widget.RecyclerView import app.pachli.R import app.pachli.databinding.ItemStatusDetailedBinding -import app.pachli.entity.description -import app.pachli.entity.icon import app.pachli.interfaces.StatusActionListener import app.pachli.util.CardViewMode import app.pachli.util.NoUnderlineURLSpan import app.pachli.util.StatusDisplayOptions import app.pachli.util.createClickableText +import app.pachli.util.description import app.pachli.util.hide +import app.pachli.util.icon import app.pachli.util.show import app.pachli.viewdata.StatusViewData import java.text.DateFormat diff --git a/app/src/main/java/app/pachli/adapter/StatusViewHolder.kt b/app/src/main/java/app/pachli/adapter/StatusViewHolder.kt index bc61c98cf..2ea2e8d19 100644 --- a/app/src/main/java/app/pachli/adapter/StatusViewHolder.kt +++ b/app/src/main/java/app/pachli/adapter/StatusViewHolder.kt @@ -21,17 +21,17 @@ import android.text.TextUtils import android.view.View import androidx.recyclerview.widget.RecyclerView import app.pachli.R +import app.pachli.core.common.string.unicodeWrap +import app.pachli.core.common.util.formatNumber +import app.pachli.core.network.model.Emoji +import app.pachli.core.network.model.Filter import app.pachli.databinding.ItemStatusBinding -import app.pachli.entity.Emoji -import app.pachli.entity.Filter import app.pachli.interfaces.StatusActionListener import app.pachli.util.SmartLengthInputFilter import app.pachli.util.StatusDisplayOptions import app.pachli.util.emojify -import app.pachli.util.formatNumber import app.pachli.util.hide import app.pachli.util.show -import app.pachli.util.unicodeWrap import app.pachli.util.visible import app.pachli.viewdata.StatusViewData import at.connyduck.sparkbutton.helpers.Utils diff --git a/app/src/main/java/app/pachli/adapter/TabAdapter.kt b/app/src/main/java/app/pachli/adapter/TabAdapter.kt index 6ffc08eed..5e09b43e8 100644 --- a/app/src/main/java/app/pachli/adapter/TabAdapter.kt +++ b/app/src/main/java/app/pachli/adapter/TabAdapter.kt @@ -22,10 +22,9 @@ import android.view.ViewGroup import androidx.core.view.size import androidx.recyclerview.widget.RecyclerView import androidx.viewbinding.ViewBinding -import app.pachli.HASHTAG -import app.pachli.LIST import app.pachli.R -import app.pachli.TabData +import app.pachli.TabViewData +import app.pachli.core.database.model.TabKind import app.pachli.databinding.ItemTabPreferenceBinding import app.pachli.databinding.ItemTabPreferenceSmallBinding import app.pachli.util.BindingHolder @@ -35,22 +34,22 @@ import app.pachli.util.show import com.google.android.material.chip.Chip interface ItemInteractionListener { - fun onTabAdded(tab: TabData) + fun onTabAdded(tab: TabViewData) fun onTabRemoved(position: Int) fun onStartDelete(viewHolder: RecyclerView.ViewHolder) fun onStartDrag(viewHolder: RecyclerView.ViewHolder) - fun onActionChipClicked(tab: TabData, tabPosition: Int) - fun onChipClicked(tab: TabData, tabPosition: Int, chipPosition: Int) + fun onActionChipClicked(tab: TabViewData, tabPosition: Int) + fun onChipClicked(tab: TabViewData, tabPosition: Int, chipPosition: Int) } class TabAdapter( - private var data: List, + private var data: List, private val small: Boolean, private val listener: ItemInteractionListener, private var removeButtonEnabled: Boolean = false, ) : RecyclerView.Adapter>() { - fun updateData(newData: List) { + fun updateData(newData: List) { this.data = newData notifyDataSetChanged() } @@ -81,7 +80,7 @@ class TabAdapter( } else { val binding = holder.binding as ItemTabPreferenceBinding - if (tab.id == LIST) { + if (tab.kind == TabKind.LIST) { binding.textView.text = tab.arguments.getOrNull(1).orEmpty() } else { binding.textView.setText(tab.text) @@ -107,7 +106,7 @@ class TabAdapter( (if (removeButtonEnabled) android.R.attr.textColorTertiary else R.attr.textColorDisabled), ) - if (tab.id == HASHTAG) { + if (tab.kind == TabKind.HASHTAG) { binding.chipGroup.show() /* diff --git a/app/src/main/java/app/pachli/appstore/CacheUpdater.kt b/app/src/main/java/app/pachli/appstore/CacheUpdater.kt index 421e82f27..1e68b41b2 100644 --- a/app/src/main/java/app/pachli/appstore/CacheUpdater.kt +++ b/app/src/main/java/app/pachli/appstore/CacheUpdater.kt @@ -1,7 +1,7 @@ package app.pachli.appstore -import app.pachli.db.AccountManager -import app.pachli.db.TimelineDao +import app.pachli.core.accounts.AccountManager +import app.pachli.core.database.dao.TimelineDao import com.google.gson.Gson import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers diff --git a/app/src/main/java/app/pachli/appstore/Events.kt b/app/src/main/java/app/pachli/appstore/Events.kt index c74acab09..2fe8b25c5 100644 --- a/app/src/main/java/app/pachli/appstore/Events.kt +++ b/app/src/main/java/app/pachli/appstore/Events.kt @@ -1,10 +1,10 @@ package app.pachli.appstore -import app.pachli.TabData -import app.pachli.entity.Account -import app.pachli.entity.Filter -import app.pachli.entity.Poll -import app.pachli.entity.Status +import app.pachli.core.database.model.TabData +import app.pachli.core.network.model.Account +import app.pachli.core.network.model.Filter +import app.pachli.core.network.model.Poll +import app.pachli.core.network.model.Status data class FavoriteEvent(val statusId: String, val favourite: Boolean) : Event data class ReblogEvent(val statusId: String, val reblog: Boolean) : Event diff --git a/app/src/main/java/app/pachli/components/account/AccountActivity.kt b/app/src/main/java/app/pachli/components/account/AccountActivity.kt index bf0fbde14..66c6cb319 100644 --- a/app/src/main/java/app/pachli/components/account/AccountActivity.kt +++ b/app/src/main/java/app/pachli/components/account/AccountActivity.kt @@ -55,16 +55,17 @@ import app.pachli.components.account.list.ListsForAccountFragment import app.pachli.components.accountlist.AccountListActivity import app.pachli.components.compose.ComposeActivity import app.pachli.components.report.ReportActivity +import app.pachli.core.database.model.AccountEntity +import app.pachli.core.network.model.Account +import app.pachli.core.network.model.Relationship +import app.pachli.core.network.parseAsMastodonHtml +import app.pachli.core.preferences.PrefKeys import app.pachli.databinding.ActivityAccountBinding -import app.pachli.db.AccountEntity import app.pachli.db.DraftsAlert -import app.pachli.entity.Account -import app.pachli.entity.Relationship import app.pachli.interfaces.AccountSelectionListener import app.pachli.interfaces.ActionButtonActivity import app.pachli.interfaces.LinkListener import app.pachli.interfaces.ReselectableFragment -import app.pachli.settings.PrefKeys import app.pachli.util.Error import app.pachli.util.Loading import app.pachli.util.Success @@ -72,7 +73,6 @@ import app.pachli.util.emojify import app.pachli.util.getDomain import app.pachli.util.hide import app.pachli.util.loadAvatar -import app.pachli.util.parseAsMastodonHtml import app.pachli.util.reduceSwipeSensitivity import app.pachli.util.setClickableText import app.pachli.util.show @@ -659,9 +659,9 @@ class AccountActivity : viewModel.changeSubscribingState() } if (relation.notifying != null) { - subscribing = relation.notifying + subscribing = relation.notifying!! } else if (relation.subscribing != null) { - subscribing = relation.subscribing + subscribing = relation.subscribing!! } } diff --git a/app/src/main/java/app/pachli/components/account/AccountFieldAdapter.kt b/app/src/main/java/app/pachli/components/account/AccountFieldAdapter.kt index 8fff01b6f..514c35703 100644 --- a/app/src/main/java/app/pachli/components/account/AccountFieldAdapter.kt +++ b/app/src/main/java/app/pachli/components/account/AccountFieldAdapter.kt @@ -20,13 +20,13 @@ import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import app.pachli.R +import app.pachli.core.network.model.Emoji +import app.pachli.core.network.model.Field +import app.pachli.core.network.parseAsMastodonHtml import app.pachli.databinding.ItemAccountFieldBinding -import app.pachli.entity.Emoji -import app.pachli.entity.Field import app.pachli.interfaces.LinkListener import app.pachli.util.BindingHolder import app.pachli.util.emojify -import app.pachli.util.parseAsMastodonHtml import app.pachli.util.setClickableText class AccountFieldAdapter( diff --git a/app/src/main/java/app/pachli/components/account/AccountViewModel.kt b/app/src/main/java/app/pachli/components/account/AccountViewModel.kt index b70205a2c..b34b0b660 100644 --- a/app/src/main/java/app/pachli/components/account/AccountViewModel.kt +++ b/app/src/main/java/app/pachli/components/account/AccountViewModel.kt @@ -9,10 +9,10 @@ import app.pachli.appstore.EventHub import app.pachli.appstore.MuteEvent import app.pachli.appstore.ProfileEditedEvent import app.pachli.appstore.UnfollowEvent -import app.pachli.db.AccountManager -import app.pachli.entity.Account -import app.pachli.entity.Relationship -import app.pachli.network.MastodonApi +import app.pachli.core.accounts.AccountManager +import app.pachli.core.network.model.Account +import app.pachli.core.network.model.Relationship +import app.pachli.core.network.retrofit.MastodonApi import app.pachli.util.Error import app.pachli.util.Loading import app.pachli.util.Resource diff --git a/app/src/main/java/app/pachli/components/account/list/ListsForAccountViewModel.kt b/app/src/main/java/app/pachli/components/account/list/ListsForAccountViewModel.kt index 35e5d9983..a41208f7d 100644 --- a/app/src/main/java/app/pachli/components/account/list/ListsForAccountViewModel.kt +++ b/app/src/main/java/app/pachli/components/account/list/ListsForAccountViewModel.kt @@ -18,8 +18,8 @@ package app.pachli.components.account.list import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import app.pachli.entity.MastoList -import app.pachli.network.MastodonApi +import app.pachli.core.network.model.MastoList +import app.pachli.core.network.retrofit.MastodonApi import at.connyduck.calladapter.networkresult.getOrThrow import at.connyduck.calladapter.networkresult.onFailure import at.connyduck.calladapter.networkresult.onSuccess diff --git a/app/src/main/java/app/pachli/components/account/media/AccountMediaFragment.kt b/app/src/main/java/app/pachli/components/account/media/AccountMediaFragment.kt index d03387486..bd7526c4c 100644 --- a/app/src/main/java/app/pachli/components/account/media/AccountMediaFragment.kt +++ b/app/src/main/java/app/pachli/components/account/media/AccountMediaFragment.kt @@ -33,12 +33,12 @@ import androidx.recyclerview.widget.GridLayoutManager import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener import app.pachli.R import app.pachli.ViewMediaActivity +import app.pachli.core.accounts.AccountManager +import app.pachli.core.network.model.Attachment +import app.pachli.core.preferences.PrefKeys +import app.pachli.core.preferences.SharedPreferencesRepository import app.pachli.databinding.FragmentTimelineBinding -import app.pachli.db.AccountManager -import app.pachli.entity.Attachment import app.pachli.interfaces.RefreshableFragment -import app.pachli.settings.PrefKeys -import app.pachli.util.SharedPreferencesRepository import app.pachli.util.hide import app.pachli.util.openLink import app.pachli.util.show diff --git a/app/src/main/java/app/pachli/components/account/media/AccountMediaGridAdapter.kt b/app/src/main/java/app/pachli/components/account/media/AccountMediaGridAdapter.kt index ca838b148..607d84f9a 100644 --- a/app/src/main/java/app/pachli/components/account/media/AccountMediaGridAdapter.kt +++ b/app/src/main/java/app/pachli/components/account/media/AccountMediaGridAdapter.kt @@ -11,8 +11,8 @@ import androidx.core.view.setPadding import androidx.paging.PagingDataAdapter import androidx.recyclerview.widget.DiffUtil import app.pachli.R +import app.pachli.core.network.model.Attachment import app.pachli.databinding.ItemAccountMediaBinding -import app.pachli.entity.Attachment import app.pachli.util.BindingHolder import app.pachli.util.decodeBlurHash import app.pachli.util.getFormattedDescription diff --git a/app/src/main/java/app/pachli/components/account/media/AccountMediaRemoteMediator.kt b/app/src/main/java/app/pachli/components/account/media/AccountMediaRemoteMediator.kt index e11a63ddb..c11524df2 100644 --- a/app/src/main/java/app/pachli/components/account/media/AccountMediaRemoteMediator.kt +++ b/app/src/main/java/app/pachli/components/account/media/AccountMediaRemoteMediator.kt @@ -21,8 +21,8 @@ import androidx.paging.LoadType import androidx.paging.PagingState import androidx.paging.RemoteMediator import app.pachli.components.timeline.util.ifExpected -import app.pachli.db.AccountEntity -import app.pachli.network.MastodonApi +import app.pachli.core.database.model.AccountEntity +import app.pachli.core.network.retrofit.MastodonApi import app.pachli.viewdata.AttachmentViewData import retrofit2.HttpException diff --git a/app/src/main/java/app/pachli/components/account/media/AccountMediaViewModel.kt b/app/src/main/java/app/pachli/components/account/media/AccountMediaViewModel.kt index 443290105..40c71b636 100644 --- a/app/src/main/java/app/pachli/components/account/media/AccountMediaViewModel.kt +++ b/app/src/main/java/app/pachli/components/account/media/AccountMediaViewModel.kt @@ -22,8 +22,8 @@ import androidx.paging.ExperimentalPagingApi import androidx.paging.Pager import androidx.paging.PagingConfig import androidx.paging.cachedIn -import app.pachli.db.AccountManager -import app.pachli.network.MastodonApi +import app.pachli.core.accounts.AccountManager +import app.pachli.core.network.retrofit.MastodonApi import app.pachli.viewdata.AttachmentViewData import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject diff --git a/app/src/main/java/app/pachli/components/accountlist/AccountListFragment.kt b/app/src/main/java/app/pachli/components/accountlist/AccountListFragment.kt index 4118c47e6..0df85b0b5 100644 --- a/app/src/main/java/app/pachli/components/accountlist/AccountListFragment.kt +++ b/app/src/main/java/app/pachli/components/accountlist/AccountListFragment.kt @@ -37,17 +37,17 @@ import app.pachli.components.accountlist.adapter.FollowAdapter import app.pachli.components.accountlist.adapter.FollowRequestsAdapter import app.pachli.components.accountlist.adapter.FollowRequestsHeaderAdapter import app.pachli.components.accountlist.adapter.MutesAdapter +import app.pachli.core.accounts.AccountManager +import app.pachli.core.network.model.HttpHeaderLink +import app.pachli.core.network.model.Relationship +import app.pachli.core.network.model.TimelineAccount +import app.pachli.core.network.retrofit.MastodonApi +import app.pachli.core.preferences.PrefKeys +import app.pachli.core.preferences.SharedPreferencesRepository import app.pachli.databinding.FragmentAccountListBinding -import app.pachli.db.AccountManager -import app.pachli.entity.Relationship -import app.pachli.entity.TimelineAccount import app.pachli.interfaces.AccountActionListener import app.pachli.interfaces.AppBarLayoutHost import app.pachli.interfaces.LinkListener -import app.pachli.network.MastodonApi -import app.pachli.settings.PrefKeys -import app.pachli.util.HttpHeaderLink -import app.pachli.util.SharedPreferencesRepository import app.pachli.util.hide import app.pachli.util.show import app.pachli.util.viewBinding diff --git a/app/src/main/java/app/pachli/components/accountlist/adapter/AccountAdapter.kt b/app/src/main/java/app/pachli/components/accountlist/adapter/AccountAdapter.kt index 7d9a87943..1ab043461 100644 --- a/app/src/main/java/app/pachli/components/accountlist/adapter/AccountAdapter.kt +++ b/app/src/main/java/app/pachli/components/accountlist/adapter/AccountAdapter.kt @@ -18,8 +18,8 @@ package app.pachli.components.accountlist.adapter import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView +import app.pachli.core.network.model.TimelineAccount import app.pachli.databinding.ItemFooterBinding -import app.pachli.entity.TimelineAccount import app.pachli.interfaces.AccountActionListener import app.pachli.util.BindingHolder import app.pachli.util.removeDuplicates diff --git a/app/src/main/java/app/pachli/components/announcements/AnnouncementAdapter.kt b/app/src/main/java/app/pachli/components/announcements/AnnouncementAdapter.kt index 8ab5789aa..738b09de7 100644 --- a/app/src/main/java/app/pachli/components/announcements/AnnouncementAdapter.kt +++ b/app/src/main/java/app/pachli/components/announcements/AnnouncementAdapter.kt @@ -25,16 +25,16 @@ import android.view.ViewGroup import androidx.core.view.size import androidx.recyclerview.widget.RecyclerView import app.pachli.R +import app.pachli.core.common.util.AbsoluteTimeFormatter +import app.pachli.core.network.model.Announcement +import app.pachli.core.network.parseAsMastodonHtml import app.pachli.databinding.ItemAnnouncementBinding -import app.pachli.entity.Announcement import app.pachli.interfaces.LinkListener -import app.pachli.util.AbsoluteTimeFormatter import app.pachli.util.BindingHolder import app.pachli.util.EmojiSpan import app.pachli.util.emojify import app.pachli.util.equalByMinute import app.pachli.util.getRelativeTimeSpanString -import app.pachli.util.parseAsMastodonHtml import app.pachli.util.setClickableText import app.pachli.util.visible import com.bumptech.glide.Glide diff --git a/app/src/main/java/app/pachli/components/announcements/AnnouncementsActivity.kt b/app/src/main/java/app/pachli/components/announcements/AnnouncementsActivity.kt index 956177e49..7c0387535 100644 --- a/app/src/main/java/app/pachli/components/announcements/AnnouncementsActivity.kt +++ b/app/src/main/java/app/pachli/components/announcements/AnnouncementsActivity.kt @@ -32,8 +32,8 @@ import app.pachli.R import app.pachli.StatusListActivity import app.pachli.adapter.EmojiAdapter import app.pachli.adapter.OnEmojiSelectedListener +import app.pachli.core.preferences.PrefKeys import app.pachli.databinding.ActivityAnnouncementsBinding -import app.pachli.settings.PrefKeys import app.pachli.util.Error import app.pachli.util.Loading import app.pachli.util.Success diff --git a/app/src/main/java/app/pachli/components/announcements/AnnouncementsViewModel.kt b/app/src/main/java/app/pachli/components/announcements/AnnouncementsViewModel.kt index 8a7e19726..80c3b0b65 100644 --- a/app/src/main/java/app/pachli/components/announcements/AnnouncementsViewModel.kt +++ b/app/src/main/java/app/pachli/components/announcements/AnnouncementsViewModel.kt @@ -23,9 +23,9 @@ import androidx.lifecycle.viewModelScope import app.pachli.appstore.AnnouncementReadEvent import app.pachli.appstore.EventHub import app.pachli.components.instanceinfo.InstanceInfoRepository -import app.pachli.entity.Announcement -import app.pachli.entity.Emoji -import app.pachli.network.MastodonApi +import app.pachli.core.network.model.Announcement +import app.pachli.core.network.model.Emoji +import app.pachli.core.network.retrofit.MastodonApi import app.pachli.util.Error import app.pachli.util.Loading import app.pachli.util.Resource diff --git a/app/src/main/java/app/pachli/components/compose/ComposeActivity.kt b/app/src/main/java/app/pachli/components/compose/ComposeActivity.kt index 5c143c3a9..17d5fda99 100644 --- a/app/src/main/java/app/pachli/components/compose/ComposeActivity.kt +++ b/app/src/main/java/app/pachli/components/compose/ComposeActivity.kt @@ -76,19 +76,19 @@ import app.pachli.components.compose.dialog.showAddPollDialog import app.pachli.components.compose.view.ComposeOptionsListener import app.pachli.components.compose.view.ComposeScheduleView import app.pachli.components.instanceinfo.InstanceInfoRepository +import app.pachli.core.database.model.AccountEntity +import app.pachli.core.database.model.DraftAttachment +import app.pachli.core.network.model.Attachment +import app.pachli.core.network.model.Emoji +import app.pachli.core.network.model.NewPoll +import app.pachli.core.network.model.Status +import app.pachli.core.preferences.PrefKeys +import app.pachli.core.preferences.PrefKeys.APP_THEME +import app.pachli.core.preferences.SharedPreferencesRepository import app.pachli.databinding.ActivityComposeBinding -import app.pachli.db.AccountEntity -import app.pachli.db.DraftAttachment -import app.pachli.entity.Attachment -import app.pachli.entity.Emoji -import app.pachli.entity.NewPoll -import app.pachli.entity.Status -import app.pachli.settings.PrefKeys -import app.pachli.settings.PrefKeys.APP_THEME import app.pachli.util.APP_THEME_DEFAULT import app.pachli.util.MentionSpan import app.pachli.util.PickMediaFiles -import app.pachli.util.SharedPreferencesRepository import app.pachli.util.THEME_BLACK import app.pachli.util.getInitialLanguages import app.pachli.util.getLocaleList diff --git a/app/src/main/java/app/pachli/components/compose/ComposeAutoCompleteAdapter.kt b/app/src/main/java/app/pachli/components/compose/ComposeAutoCompleteAdapter.kt index 5447e20a3..56e34cdc3 100644 --- a/app/src/main/java/app/pachli/components/compose/ComposeAutoCompleteAdapter.kt +++ b/app/src/main/java/app/pachli/components/compose/ComposeAutoCompleteAdapter.kt @@ -24,11 +24,11 @@ import android.widget.Filter import android.widget.Filterable import androidx.annotation.WorkerThread import app.pachli.R +import app.pachli.core.network.model.Emoji +import app.pachli.core.network.model.TimelineAccount import app.pachli.databinding.ItemAutocompleteAccountBinding import app.pachli.databinding.ItemAutocompleteEmojiBinding import app.pachli.databinding.ItemAutocompleteHashtagBinding -import app.pachli.entity.Emoji -import app.pachli.entity.TimelineAccount import app.pachli.util.emojify import app.pachli.util.loadAvatar import app.pachli.util.visible diff --git a/app/src/main/java/app/pachli/components/compose/ComposeViewModel.kt b/app/src/main/java/app/pachli/components/compose/ComposeViewModel.kt index 4a9d19502..e34134103 100644 --- a/app/src/main/java/app/pachli/components/compose/ComposeViewModel.kt +++ b/app/src/main/java/app/pachli/components/compose/ComposeViewModel.kt @@ -27,16 +27,16 @@ import app.pachli.components.drafts.DraftHelper import app.pachli.components.instanceinfo.InstanceInfo import app.pachli.components.instanceinfo.InstanceInfoRepository import app.pachli.components.search.SearchType -import app.pachli.db.AccountManager -import app.pachli.entity.Attachment -import app.pachli.entity.Emoji -import app.pachli.entity.NewPoll -import app.pachli.entity.Status -import app.pachli.network.MastodonApi +import app.pachli.core.accounts.AccountManager +import app.pachli.core.common.string.randomAlphanumericString +import app.pachli.core.network.model.Attachment +import app.pachli.core.network.model.Emoji +import app.pachli.core.network.model.NewPoll +import app.pachli.core.network.model.Status +import app.pachli.core.network.retrofit.MastodonApi import app.pachli.service.MediaToSend import app.pachli.service.ServiceClient import app.pachli.service.StatusToSend -import app.pachli.util.randomAlphanumericString import at.connyduck.calladapter.networkresult.fold import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers diff --git a/app/src/main/java/app/pachli/components/compose/MediaUploader.kt b/app/src/main/java/app/pachli/components/compose/MediaUploader.kt index fcf421037..0e54a73ea 100644 --- a/app/src/main/java/app/pachli/components/compose/MediaUploader.kt +++ b/app/src/main/java/app/pachli/components/compose/MediaUploader.kt @@ -30,13 +30,13 @@ import app.pachli.BuildConfig import app.pachli.R import app.pachli.components.compose.ComposeActivity.QueuedMedia import app.pachli.components.instanceinfo.InstanceInfo -import app.pachli.network.MediaUploadApi +import app.pachli.core.common.string.randomAlphanumericString +import app.pachli.core.mastodon.model.MediaUploadApi import app.pachli.network.ProgressRequestBody import app.pachli.util.MEDIA_SIZE_UNKNOWN import app.pachli.util.getImageSquarePixels import app.pachli.util.getMediaSize import app.pachli.util.getServerErrorMessage -import app.pachli.util.randomAlphanumericString import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers diff --git a/app/src/main/java/app/pachli/components/compose/dialog/AddPollDialog.kt b/app/src/main/java/app/pachli/components/compose/dialog/AddPollDialog.kt index 1098d0652..15f8dc191 100644 --- a/app/src/main/java/app/pachli/components/compose/dialog/AddPollDialog.kt +++ b/app/src/main/java/app/pachli/components/compose/dialog/AddPollDialog.kt @@ -22,8 +22,8 @@ import android.view.WindowManager import android.widget.ArrayAdapter import androidx.appcompat.app.AlertDialog import app.pachli.R +import app.pachli.core.network.model.NewPoll import app.pachli.databinding.DialogAddPollBinding -import app.pachli.entity.NewPoll fun showAddPollDialog( context: Context, diff --git a/app/src/main/java/app/pachli/components/compose/dialog/FocusDialog.kt b/app/src/main/java/app/pachli/components/compose/dialog/FocusDialog.kt index 1c583e88e..6086439ff 100644 --- a/app/src/main/java/app/pachli/components/compose/dialog/FocusDialog.kt +++ b/app/src/main/java/app/pachli/components/compose/dialog/FocusDialog.kt @@ -25,8 +25,8 @@ import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.lifecycleScope +import app.pachli.core.network.model.Attachment.Focus import app.pachli.databinding.DialogFocusBinding -import app.pachli.entity.Attachment.Focus import com.bumptech.glide.Glide import com.bumptech.glide.load.DataSource import com.bumptech.glide.load.engine.GlideException diff --git a/app/src/main/java/app/pachli/components/compose/view/ComposeOptionsView.kt b/app/src/main/java/app/pachli/components/compose/view/ComposeOptionsView.kt index b0c827f54..cf37c7f9e 100644 --- a/app/src/main/java/app/pachli/components/compose/view/ComposeOptionsView.kt +++ b/app/src/main/java/app/pachli/components/compose/view/ComposeOptionsView.kt @@ -20,7 +20,7 @@ import android.content.Context import android.util.AttributeSet import android.widget.RadioGroup import app.pachli.R -import app.pachli.entity.Status +import app.pachli.core.network.model.Status class ComposeOptionsView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : RadioGroup(context, attrs) { diff --git a/app/src/main/java/app/pachli/components/compose/view/FocusIndicatorView.kt b/app/src/main/java/app/pachli/components/compose/view/FocusIndicatorView.kt index bf168d6a5..83da003a4 100644 --- a/app/src/main/java/app/pachli/components/compose/view/FocusIndicatorView.kt +++ b/app/src/main/java/app/pachli/components/compose/view/FocusIndicatorView.kt @@ -10,7 +10,7 @@ import android.graphics.Point import android.util.AttributeSet import android.view.MotionEvent import android.view.View -import app.pachli.entity.Attachment +import app.pachli.core.network.model.Attachment import kotlin.math.ceil import kotlin.math.max import kotlin.math.min diff --git a/app/src/main/java/app/pachli/components/compose/view/PollPreviewView.kt b/app/src/main/java/app/pachli/components/compose/view/PollPreviewView.kt index a458b7bcc..e1754d686 100644 --- a/app/src/main/java/app/pachli/components/compose/view/PollPreviewView.kt +++ b/app/src/main/java/app/pachli/components/compose/view/PollPreviewView.kt @@ -22,8 +22,8 @@ import android.view.LayoutInflater import android.widget.LinearLayout import app.pachli.R import app.pachli.adapter.PreviewPollOptionsAdapter +import app.pachli.core.network.model.NewPoll import app.pachli.databinding.ViewPollPreviewBinding -import app.pachli.entity.NewPoll class PollPreviewView @JvmOverloads constructor( context: Context?, diff --git a/app/src/main/java/app/pachli/components/compose/view/TootButton.kt b/app/src/main/java/app/pachli/components/compose/view/TootButton.kt index 847e92f39..013299fe6 100644 --- a/app/src/main/java/app/pachli/components/compose/view/TootButton.kt +++ b/app/src/main/java/app/pachli/components/compose/view/TootButton.kt @@ -20,7 +20,7 @@ import android.content.Context import android.graphics.Color import android.util.AttributeSet import app.pachli.R -import app.pachli.entity.Status +import app.pachli.core.network.model.Status import com.google.android.material.button.MaterialButton import com.mikepenz.iconics.IconicsDrawable import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial diff --git a/app/src/main/java/app/pachli/components/conversation/ConversationViewData.kt b/app/src/main/java/app/pachli/components/conversation/ConversationViewData.kt index c48d5798e..97e9881c2 100644 --- a/app/src/main/java/app/pachli/components/conversation/ConversationViewData.kt +++ b/app/src/main/java/app/pachli/components/conversation/ConversationViewData.kt @@ -16,7 +16,9 @@ package app.pachli.components.conversation -import app.pachli.entity.Poll +import app.pachli.core.database.model.ConversationAccountEntity +import app.pachli.core.database.model.ConversationEntity +import app.pachli.core.network.model.Poll import app.pachli.viewdata.StatusViewData data class ConversationViewData( diff --git a/app/src/main/java/app/pachli/components/conversation/ConversationViewHolder.kt b/app/src/main/java/app/pachli/components/conversation/ConversationViewHolder.kt index 4208d49b8..88f074fa6 100644 --- a/app/src/main/java/app/pachli/components/conversation/ConversationViewHolder.kt +++ b/app/src/main/java/app/pachli/components/conversation/ConversationViewHolder.kt @@ -25,6 +25,7 @@ import android.widget.TextView import androidx.recyclerview.widget.RecyclerView import app.pachli.R import app.pachli.adapter.StatusBaseViewHolder +import app.pachli.core.database.model.ConversationAccountEntity import app.pachli.interfaces.StatusActionListener import app.pachli.util.SmartLengthInputFilter import app.pachli.util.StatusDisplayOptions diff --git a/app/src/main/java/app/pachli/components/conversation/ConversationsFragment.kt b/app/src/main/java/app/pachli/components/conversation/ConversationsFragment.kt index bce4e35c3..3c4b4e59a 100644 --- a/app/src/main/java/app/pachli/components/conversation/ConversationsFragment.kt +++ b/app/src/main/java/app/pachli/components/conversation/ConversationsFragment.kt @@ -40,13 +40,13 @@ import app.pachli.StatusListActivity import app.pachli.adapter.StatusBaseViewHolder import app.pachli.appstore.EventHub import app.pachli.components.account.AccountActivity +import app.pachli.core.preferences.PrefKeys +import app.pachli.core.preferences.SharedPreferencesRepository import app.pachli.databinding.FragmentTimelineBinding import app.pachli.fragment.SFragment import app.pachli.interfaces.ActionButtonActivity import app.pachli.interfaces.ReselectableFragment import app.pachli.interfaces.StatusActionListener -import app.pachli.settings.PrefKeys -import app.pachli.util.SharedPreferencesRepository import app.pachli.util.StatusDisplayOptionsRepository import app.pachli.util.hide import app.pachli.util.show diff --git a/app/src/main/java/app/pachli/components/conversation/ConversationsRemoteMediator.kt b/app/src/main/java/app/pachli/components/conversation/ConversationsRemoteMediator.kt index a66c7adc7..5ba0993bf 100644 --- a/app/src/main/java/app/pachli/components/conversation/ConversationsRemoteMediator.kt +++ b/app/src/main/java/app/pachli/components/conversation/ConversationsRemoteMediator.kt @@ -4,11 +4,12 @@ import androidx.paging.ExperimentalPagingApi import androidx.paging.LoadType import androidx.paging.PagingState import androidx.paging.RemoteMediator -import app.pachli.db.AccountManager -import app.pachli.db.ConversationsDao -import app.pachli.di.TransactionProvider -import app.pachli.network.MastodonApi -import app.pachli.util.HttpHeaderLink +import app.pachli.core.accounts.AccountManager +import app.pachli.core.database.dao.ConversationsDao +import app.pachli.core.database.di.TransactionProvider +import app.pachli.core.database.model.ConversationEntity +import app.pachli.core.network.model.HttpHeaderLink +import app.pachli.core.network.retrofit.MastodonApi import retrofit2.HttpException @OptIn(ExperimentalPagingApi::class) diff --git a/app/src/main/java/app/pachli/components/conversation/ConversationsViewModel.kt b/app/src/main/java/app/pachli/components/conversation/ConversationsViewModel.kt index 6de8f9c13..8b130aeba 100644 --- a/app/src/main/java/app/pachli/components/conversation/ConversationsViewModel.kt +++ b/app/src/main/java/app/pachli/components/conversation/ConversationsViewModel.kt @@ -23,10 +23,11 @@ import androidx.paging.Pager import androidx.paging.PagingConfig import androidx.paging.cachedIn import androidx.paging.map -import app.pachli.db.AccountManager -import app.pachli.db.ConversationsDao -import app.pachli.di.TransactionProvider -import app.pachli.network.MastodonApi +import app.pachli.core.accounts.AccountManager +import app.pachli.core.database.dao.ConversationsDao +import app.pachli.core.database.di.TransactionProvider +import app.pachli.core.database.model.ConversationEntity +import app.pachli.core.network.retrofit.MastodonApi import app.pachli.usecase.TimelineCases import app.pachli.util.EmptyPagingSource import at.connyduck.calladapter.networkresult.fold diff --git a/app/src/main/java/app/pachli/components/drafts/DraftHelper.kt b/app/src/main/java/app/pachli/components/drafts/DraftHelper.kt index 4cd6b0bda..713bc11e6 100644 --- a/app/src/main/java/app/pachli/components/drafts/DraftHelper.kt +++ b/app/src/main/java/app/pachli/components/drafts/DraftHelper.kt @@ -22,12 +22,12 @@ import android.webkit.MimeTypeMap import androidx.core.content.FileProvider import androidx.core.net.toUri import app.pachli.BuildConfig -import app.pachli.db.DraftAttachment -import app.pachli.db.DraftDao -import app.pachli.db.DraftEntity -import app.pachli.entity.Attachment -import app.pachli.entity.NewPoll -import app.pachli.entity.Status +import app.pachli.core.database.dao.DraftDao +import app.pachli.core.database.model.DraftAttachment +import app.pachli.core.database.model.DraftEntity +import app.pachli.core.network.model.Attachment +import app.pachli.core.network.model.NewPoll +import app.pachli.core.network.model.Status import app.pachli.util.copyToFile import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.Dispatchers diff --git a/app/src/main/java/app/pachli/components/drafts/DraftMediaAdapter.kt b/app/src/main/java/app/pachli/components/drafts/DraftMediaAdapter.kt index 698372890..570cf97de 100644 --- a/app/src/main/java/app/pachli/components/drafts/DraftMediaAdapter.kt +++ b/app/src/main/java/app/pachli/components/drafts/DraftMediaAdapter.kt @@ -23,7 +23,7 @@ import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView import app.pachli.R -import app.pachli.db.DraftAttachment +import app.pachli.core.database.model.DraftAttachment import app.pachli.view.MediaPreviewImageView import com.bumptech.glide.Glide import com.bumptech.glide.load.engine.DiskCacheStrategy diff --git a/app/src/main/java/app/pachli/components/drafts/DraftsActivity.kt b/app/src/main/java/app/pachli/components/drafts/DraftsActivity.kt index 1e2469286..eb3b97540 100644 --- a/app/src/main/java/app/pachli/components/drafts/DraftsActivity.kt +++ b/app/src/main/java/app/pachli/components/drafts/DraftsActivity.kt @@ -27,10 +27,10 @@ import androidx.recyclerview.widget.LinearLayoutManager import app.pachli.BaseActivity import app.pachli.R import app.pachli.components.compose.ComposeActivity +import app.pachli.core.database.model.DraftEntity +import app.pachli.core.network.parseAsMastodonHtml import app.pachli.databinding.ActivityDraftsBinding -import app.pachli.db.DraftEntity import app.pachli.db.DraftsAlert -import app.pachli.util.parseAsMastodonHtml import app.pachli.util.visible import at.connyduck.calladapter.networkresult.fold import com.google.android.material.bottomsheet.BottomSheetBehavior @@ -103,7 +103,7 @@ class DraftsActivity : BaseActivity(), DraftActionListener { lifecycleScope.launch { bottomSheet.state = BottomSheetBehavior.STATE_COLLAPSED - viewModel.getStatus(draft.inReplyToId) + viewModel.getStatus(draft.inReplyToId!!) .fold( { status -> val composeOptions = ComposeActivity.ComposeOptions( diff --git a/app/src/main/java/app/pachli/components/drafts/DraftsAdapter.kt b/app/src/main/java/app/pachli/components/drafts/DraftsAdapter.kt index ec86d7f14..ce5d02edc 100644 --- a/app/src/main/java/app/pachli/components/drafts/DraftsAdapter.kt +++ b/app/src/main/java/app/pachli/components/drafts/DraftsAdapter.kt @@ -22,8 +22,8 @@ import androidx.paging.PagingDataAdapter import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView +import app.pachli.core.database.model.DraftEntity import app.pachli.databinding.ItemDraftBinding -import app.pachli.db.DraftEntity import app.pachli.util.BindingHolder import app.pachli.util.hide import app.pachli.util.show @@ -80,12 +80,10 @@ class DraftsAdapter( holder.binding.draftMediaPreview.visible(draft.attachments.isNotEmpty()) (holder.binding.draftMediaPreview.adapter as DraftMediaAdapter).submitList(draft.attachments) - if (draft.poll != null) { + draft.poll?.apply { holder.binding.draftPoll.show() - holder.binding.draftPoll.setPoll(draft.poll) - } else { - holder.binding.draftPoll.hide() - } + holder.binding.draftPoll.setPoll(this) + } ?: holder.binding.draftPoll.hide() } } } diff --git a/app/src/main/java/app/pachli/components/drafts/DraftsViewModel.kt b/app/src/main/java/app/pachli/components/drafts/DraftsViewModel.kt index 9eff53a90..f11e20add 100644 --- a/app/src/main/java/app/pachli/components/drafts/DraftsViewModel.kt +++ b/app/src/main/java/app/pachli/components/drafts/DraftsViewModel.kt @@ -21,11 +21,11 @@ import androidx.lifecycle.viewModelScope import androidx.paging.Pager import androidx.paging.PagingConfig import androidx.paging.cachedIn -import app.pachli.db.AccountManager -import app.pachli.db.DraftDao -import app.pachli.db.DraftEntity -import app.pachli.entity.Status -import app.pachli.network.MastodonApi +import app.pachli.core.accounts.AccountManager +import app.pachli.core.database.dao.DraftDao +import app.pachli.core.database.model.DraftEntity +import app.pachli.core.network.model.Status +import app.pachli.core.network.retrofit.MastodonApi import at.connyduck.calladapter.networkresult.NetworkResult import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch diff --git a/app/src/main/java/app/pachli/components/filters/EditFilterActivity.kt b/app/src/main/java/app/pachli/components/filters/EditFilterActivity.kt index e5169d19b..3e81c2fc4 100644 --- a/app/src/main/java/app/pachli/components/filters/EditFilterActivity.kt +++ b/app/src/main/java/app/pachli/components/filters/EditFilterActivity.kt @@ -15,11 +15,11 @@ import androidx.lifecycle.lifecycleScope import app.pachli.BaseActivity import app.pachli.R import app.pachli.appstore.EventHub +import app.pachli.core.network.model.Filter +import app.pachli.core.network.model.FilterKeyword +import app.pachli.core.network.retrofit.MastodonApi import app.pachli.databinding.ActivityEditFilterBinding import app.pachli.databinding.DialogFilterBinding -import app.pachli.entity.Filter -import app.pachli.entity.FilterKeyword -import app.pachli.network.MastodonApi import app.pachli.util.viewBinding import app.pachli.util.visible import at.connyduck.calladapter.networkresult.fold diff --git a/app/src/main/java/app/pachli/components/filters/EditFilterViewModel.kt b/app/src/main/java/app/pachli/components/filters/EditFilterViewModel.kt index ca8af2c4a..681986e4d 100644 --- a/app/src/main/java/app/pachli/components/filters/EditFilterViewModel.kt +++ b/app/src/main/java/app/pachli/components/filters/EditFilterViewModel.kt @@ -5,9 +5,9 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import app.pachli.appstore.EventHub import app.pachli.appstore.FilterChangedEvent -import app.pachli.entity.Filter -import app.pachli.entity.FilterKeyword -import app.pachli.network.MastodonApi +import app.pachli.core.network.model.Filter +import app.pachli.core.network.model.FilterKeyword +import app.pachli.core.network.retrofit.MastodonApi import at.connyduck.calladapter.networkresult.fold import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow diff --git a/app/src/main/java/app/pachli/components/filters/FiltersActivity.kt b/app/src/main/java/app/pachli/components/filters/FiltersActivity.kt index eafe19dea..0fb6365c1 100644 --- a/app/src/main/java/app/pachli/components/filters/FiltersActivity.kt +++ b/app/src/main/java/app/pachli/components/filters/FiltersActivity.kt @@ -7,8 +7,8 @@ import androidx.activity.viewModels import androidx.lifecycle.lifecycleScope import app.pachli.BaseActivity import app.pachli.R +import app.pachli.core.network.model.Filter import app.pachli.databinding.ActivityFiltersBinding -import app.pachli.entity.Filter import app.pachli.util.hide import app.pachli.util.show import app.pachli.util.viewBinding diff --git a/app/src/main/java/app/pachli/components/filters/FiltersAdapter.kt b/app/src/main/java/app/pachli/components/filters/FiltersAdapter.kt index 1415119f9..1c9c68536 100644 --- a/app/src/main/java/app/pachli/components/filters/FiltersAdapter.kt +++ b/app/src/main/java/app/pachli/components/filters/FiltersAdapter.kt @@ -4,8 +4,8 @@ import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import app.pachli.R +import app.pachli.core.network.model.Filter import app.pachli.databinding.ItemRemovableBinding -import app.pachli.entity.Filter import app.pachli.util.BindingHolder import app.pachli.util.getRelativeTimeSpanString @@ -26,15 +26,14 @@ class FiltersAdapter(val listener: FiltersListener, val filters: List) : val filter = filters[position] val context = binding.root.context - binding.textPrimary.text = if (filter.expiresAt == null) { - filter.title - } else { + binding.textPrimary.text = filter.expiresAt?.let { context.getString( R.string.filter_expiration_format, filter.title, - getRelativeTimeSpanString(binding.root.context, filter.expiresAt.time, System.currentTimeMillis()), + getRelativeTimeSpanString(binding.root.context, it.time, System.currentTimeMillis()), ) - } + } ?: filter.title + binding.textSecondary.text = context.getString( R.string.filter_description_format, actions.getOrNull(filter.action.ordinal - 1), diff --git a/app/src/main/java/app/pachli/components/filters/FiltersListener.kt b/app/src/main/java/app/pachli/components/filters/FiltersListener.kt index 4796c9917..3eb6953a1 100644 --- a/app/src/main/java/app/pachli/components/filters/FiltersListener.kt +++ b/app/src/main/java/app/pachli/components/filters/FiltersListener.kt @@ -1,6 +1,6 @@ package app.pachli.components.filters -import app.pachli.entity.Filter +import app.pachli.core.network.model.Filter interface FiltersListener { fun deleteFilter(filter: Filter) diff --git a/app/src/main/java/app/pachli/components/filters/FiltersViewModel.kt b/app/src/main/java/app/pachli/components/filters/FiltersViewModel.kt index 3c8200917..b10f567d2 100644 --- a/app/src/main/java/app/pachli/components/filters/FiltersViewModel.kt +++ b/app/src/main/java/app/pachli/components/filters/FiltersViewModel.kt @@ -5,8 +5,8 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import app.pachli.appstore.EventHub import app.pachli.appstore.FilterChangedEvent -import app.pachli.entity.Filter -import app.pachli.network.MastodonApi +import app.pachli.core.network.model.Filter +import app.pachli.core.network.retrofit.MastodonApi import at.connyduck.calladapter.networkresult.fold import com.google.android.material.snackbar.Snackbar import dagger.hilt.android.lifecycle.HiltViewModel diff --git a/app/src/main/java/app/pachli/components/followedtags/FollowedTagsActivity.kt b/app/src/main/java/app/pachli/components/followedtags/FollowedTagsActivity.kt index b47ba3cb6..0ab3b82d7 100644 --- a/app/src/main/java/app/pachli/components/followedtags/FollowedTagsActivity.kt +++ b/app/src/main/java/app/pachli/components/followedtags/FollowedTagsActivity.kt @@ -15,10 +15,10 @@ import androidx.recyclerview.widget.SimpleItemAnimator import app.pachli.BaseActivity import app.pachli.R import app.pachli.components.compose.ComposeAutoCompleteAdapter +import app.pachli.core.network.retrofit.MastodonApi +import app.pachli.core.preferences.PrefKeys import app.pachli.databinding.ActivityFollowedTagsBinding import app.pachli.interfaces.HashtagActionListener -import app.pachli.network.MastodonApi -import app.pachli.settings.PrefKeys import app.pachli.util.hide import app.pachli.util.show import app.pachli.util.viewBinding diff --git a/app/src/main/java/app/pachli/components/followedtags/FollowedTagsRemoteMediator.kt b/app/src/main/java/app/pachli/components/followedtags/FollowedTagsRemoteMediator.kt index 7b5be2c5f..073a98612 100644 --- a/app/src/main/java/app/pachli/components/followedtags/FollowedTagsRemoteMediator.kt +++ b/app/src/main/java/app/pachli/components/followedtags/FollowedTagsRemoteMediator.kt @@ -4,9 +4,9 @@ import androidx.paging.ExperimentalPagingApi import androidx.paging.LoadType import androidx.paging.PagingState import androidx.paging.RemoteMediator -import app.pachli.entity.HashTag -import app.pachli.network.MastodonApi -import app.pachli.util.HttpHeaderLink +import app.pachli.core.network.model.HashTag +import app.pachli.core.network.model.HttpHeaderLink +import app.pachli.core.network.retrofit.MastodonApi import retrofit2.HttpException import retrofit2.Response diff --git a/app/src/main/java/app/pachli/components/followedtags/FollowedTagsViewModel.kt b/app/src/main/java/app/pachli/components/followedtags/FollowedTagsViewModel.kt index 2a17f4f2f..6167b395b 100644 --- a/app/src/main/java/app/pachli/components/followedtags/FollowedTagsViewModel.kt +++ b/app/src/main/java/app/pachli/components/followedtags/FollowedTagsViewModel.kt @@ -8,8 +8,8 @@ import androidx.paging.PagingConfig import androidx.paging.cachedIn import app.pachli.components.compose.ComposeAutoCompleteAdapter import app.pachli.components.search.SearchType -import app.pachli.entity.HashTag -import app.pachli.network.MastodonApi +import app.pachli.core.network.model.HashTag +import app.pachli.core.network.retrofit.MastodonApi import at.connyduck.calladapter.networkresult.fold import dagger.hilt.android.lifecycle.HiltViewModel import timber.log.Timber diff --git a/app/src/main/java/app/pachli/components/instanceinfo/InstanceInfoRepository.kt b/app/src/main/java/app/pachli/components/instanceinfo/InstanceInfoRepository.kt index d3f5030f5..73215e7ed 100644 --- a/app/src/main/java/app/pachli/components/instanceinfo/InstanceInfoRepository.kt +++ b/app/src/main/java/app/pachli/components/instanceinfo/InstanceInfoRepository.kt @@ -16,12 +16,12 @@ package app.pachli.components.instanceinfo -import app.pachli.db.AccountManager -import app.pachli.db.EmojisEntity -import app.pachli.db.InstanceDao -import app.pachli.db.InstanceInfoEntity -import app.pachli.entity.Emoji -import app.pachli.network.MastodonApi +import app.pachli.core.accounts.AccountManager +import app.pachli.core.database.dao.InstanceDao +import app.pachli.core.database.model.EmojisEntity +import app.pachli.core.database.model.InstanceInfoEntity +import app.pachli.core.network.model.Emoji +import app.pachli.core.network.retrofit.MastodonApi import at.connyduck.calladapter.networkresult.fold import at.connyduck.calladapter.networkresult.getOrElse import at.connyduck.calladapter.networkresult.onSuccess diff --git a/app/src/main/java/app/pachli/components/instancemute/fragment/InstanceListFragment.kt b/app/src/main/java/app/pachli/components/instancemute/fragment/InstanceListFragment.kt index e552d8461..9e44fb4e4 100644 --- a/app/src/main/java/app/pachli/components/instancemute/fragment/InstanceListFragment.kt +++ b/app/src/main/java/app/pachli/components/instancemute/fragment/InstanceListFragment.kt @@ -9,9 +9,9 @@ import androidx.recyclerview.widget.RecyclerView import app.pachli.R import app.pachli.components.instancemute.adapter.DomainMutesAdapter import app.pachli.components.instancemute.interfaces.InstanceActionListener +import app.pachli.core.network.model.HttpHeaderLink +import app.pachli.core.network.retrofit.MastodonApi import app.pachli.databinding.FragmentInstanceListBinding -import app.pachli.network.MastodonApi -import app.pachli.util.HttpHeaderLink import app.pachli.util.hide import app.pachli.util.show import app.pachli.util.viewBinding diff --git a/app/src/main/java/app/pachli/components/login/LoginActivity.kt b/app/src/main/java/app/pachli/components/login/LoginActivity.kt index b06bcd24e..c38d5462c 100644 --- a/app/src/main/java/app/pachli/components/login/LoginActivity.kt +++ b/app/src/main/java/app/pachli/components/login/LoginActivity.kt @@ -32,10 +32,10 @@ import app.pachli.BaseActivity import app.pachli.BuildConfig import app.pachli.MainActivity import app.pachli.R +import app.pachli.core.network.model.AccessToken +import app.pachli.core.network.retrofit.MastodonApi +import app.pachli.core.preferences.getNonNullString import app.pachli.databinding.ActivityLoginBinding -import app.pachli.entity.AccessToken -import app.pachli.network.MastodonApi -import app.pachli.util.getNonNullString import app.pachli.util.openLinkInCustomTab import app.pachli.util.rickRoll import app.pachli.util.shouldRickRoll diff --git a/app/src/main/java/app/pachli/components/login/LoginWebViewViewModel.kt b/app/src/main/java/app/pachli/components/login/LoginWebViewViewModel.kt index 41b51f832..d05984ed9 100644 --- a/app/src/main/java/app/pachli/components/login/LoginWebViewViewModel.kt +++ b/app/src/main/java/app/pachli/components/login/LoginWebViewViewModel.kt @@ -18,7 +18,7 @@ package app.pachli.components.login import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import app.pachli.network.MastodonApi +import app.pachli.core.network.retrofit.MastodonApi import at.connyduck.calladapter.networkresult.fold import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow diff --git a/app/src/main/java/app/pachli/components/notifications/FollowViewHolder.kt b/app/src/main/java/app/pachli/components/notifications/FollowViewHolder.kt index 4b29b6f7f..5eb7cd373 100644 --- a/app/src/main/java/app/pachli/components/notifications/FollowViewHolder.kt +++ b/app/src/main/java/app/pachli/components/notifications/FollowViewHolder.kt @@ -19,16 +19,16 @@ package app.pachli.components.notifications import androidx.recyclerview.widget.RecyclerView import app.pachli.R +import app.pachli.core.common.string.unicodeWrap +import app.pachli.core.network.model.Notification +import app.pachli.core.network.model.TimelineAccount +import app.pachli.core.network.parseAsMastodonHtml import app.pachli.databinding.ItemFollowBinding -import app.pachli.entity.Notification -import app.pachli.entity.TimelineAccount import app.pachli.interfaces.LinkListener import app.pachli.util.StatusDisplayOptions import app.pachli.util.emojify import app.pachli.util.loadAvatar -import app.pachli.util.parseAsMastodonHtml import app.pachli.util.setClickableText -import app.pachli.util.unicodeWrap import app.pachli.viewdata.NotificationViewData class FollowViewHolder( diff --git a/app/src/main/java/app/pachli/components/notifications/NotificationFetcher.kt b/app/src/main/java/app/pachli/components/notifications/NotificationFetcher.kt index 3d6dc6a88..f17e11a75 100644 --- a/app/src/main/java/app/pachli/components/notifications/NotificationFetcher.kt +++ b/app/src/main/java/app/pachli/components/notifications/NotificationFetcher.kt @@ -20,13 +20,13 @@ package app.pachli.components.notifications import android.app.NotificationManager import android.content.Context import androidx.annotation.WorkerThread -import app.pachli.db.AccountEntity -import app.pachli.db.AccountManager -import app.pachli.entity.Marker -import app.pachli.entity.Notification -import app.pachli.network.Links -import app.pachli.network.MastodonApi -import app.pachli.util.isLessThan +import app.pachli.core.accounts.AccountManager +import app.pachli.core.common.string.isLessThan +import app.pachli.core.database.model.AccountEntity +import app.pachli.core.network.model.Links +import app.pachli.core.network.model.Marker +import app.pachli.core.network.model.Notification +import app.pachli.core.network.retrofit.MastodonApi import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.delay import timber.log.Timber diff --git a/app/src/main/java/app/pachli/components/notifications/NotificationHelper.kt b/app/src/main/java/app/pachli/components/notifications/NotificationHelper.kt index 896f57e24..f1a6f1c24 100644 --- a/app/src/main/java/app/pachli/components/notifications/NotificationHelper.kt +++ b/app/src/main/java/app/pachli/components/notifications/NotificationHelper.kt @@ -45,12 +45,12 @@ import app.pachli.MainActivity.Companion.composeIntent import app.pachli.MainActivity.Companion.openNotificationIntent import app.pachli.R import app.pachli.components.compose.ComposeActivity -import app.pachli.db.AccountEntity -import app.pachli.db.AccountManager -import app.pachli.entity.Notification +import app.pachli.core.accounts.AccountManager +import app.pachli.core.common.string.unicodeWrap +import app.pachli.core.database.model.AccountEntity +import app.pachli.core.network.model.Notification +import app.pachli.core.network.parseAsMastodonHtml import app.pachli.receiver.SendStatusBroadcastReceiver -import app.pachli.util.parseAsMastodonHtml -import app.pachli.util.unicodeWrap import app.pachli.viewdata.buildDescription import app.pachli.viewdata.calculatePercent import app.pachli.worker.NotificationWorker @@ -811,20 +811,20 @@ private fun bodyForType( Notification.Type.MENTION, Notification.Type.FAVOURITE, Notification.Type.REBLOG, Notification.Type.STATUS -> { val status = notification.status!! return if (!TextUtils.isEmpty(status.spoilerText) && !alwaysOpenSpoiler) { - notification.status.spoilerText + status.spoilerText } else { - notification.status.content.parseAsMastodonHtml().toString() + status.content.parseAsMastodonHtml().toString() } } Notification.Type.POLL -> { val status = notification.status!! return if (!TextUtils.isEmpty(status.spoilerText) && !alwaysOpenSpoiler) { - notification.status.spoilerText + status.spoilerText } else { - val builder = StringBuilder(notification.status.content.parseAsMastodonHtml()) + val builder = StringBuilder(status.content.parseAsMastodonHtml()) builder.append('\n') - val poll = notification.status.poll!! + val poll = status.poll!! val options = poll.options for (i in options.indices) { val (title, votesCount) = options[i] @@ -832,7 +832,7 @@ private fun bodyForType( buildDescription( title, calculatePercent(votesCount, poll.votersCount, poll.votesCount), - poll.ownVotes != null && poll.ownVotes.contains(i), + poll.ownVotes != null && poll.ownVotes!!.contains(i), context, ), ) diff --git a/app/src/main/java/app/pachli/components/notifications/NotificationsFragment.kt b/app/src/main/java/app/pachli/components/notifications/NotificationsFragment.kt index 802c1db49..fdaa60824 100644 --- a/app/src/main/java/app/pachli/components/notifications/NotificationsFragment.kt +++ b/app/src/main/java/app/pachli/components/notifications/NotificationsFragment.kt @@ -26,6 +26,7 @@ import android.view.MenuInflater import android.view.MenuItem import android.view.View import android.view.ViewGroup +import androidx.annotation.StringRes import androidx.appcompat.app.AlertDialog import androidx.core.view.MenuProvider import androidx.core.view.isVisible @@ -45,10 +46,10 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener import app.pachli.R import app.pachli.adapter.StatusBaseViewHolder import app.pachli.components.timeline.TimelineLoadStateAdapter +import app.pachli.core.network.model.Filter +import app.pachli.core.network.model.Notification +import app.pachli.core.network.model.Status import app.pachli.databinding.FragmentTimelineNotificationsBinding -import app.pachli.entity.Filter -import app.pachli.entity.Notification -import app.pachli.entity.Status import app.pachli.fragment.SFragment import app.pachli.interfaces.AccountActionListener import app.pachli.interfaces.ActionButtonActivity @@ -698,7 +699,7 @@ class FilterDialogFragment( override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { val context = requireContext() - val items = Notification.Type.visibleTypes.map { getString(it.uiString) }.toTypedArray() + val items = Notification.Type.visibleTypes.map { getString(it.uiString()) }.toTypedArray() val checkedItems = Notification.Type.visibleTypes.map { !activeFilter.contains(it) }.toBooleanArray() @@ -719,3 +720,18 @@ class FilterDialogFragment( return builder.create() } } + +@StringRes +fun Notification.Type.uiString(): Int = when (this) { + Notification.Type.UNKNOWN -> R.string.notification_unknown_name + Notification.Type.MENTION -> R.string.notification_mention_name + Notification.Type.REBLOG -> R.string.notification_boost_name + Notification.Type.FAVOURITE -> R.string.notification_favourite_name + Notification.Type.FOLLOW -> R.string.notification_follow_name + Notification.Type.FOLLOW_REQUEST -> R.string.notification_follow_request_name + Notification.Type.POLL -> R.string.notification_poll_name + Notification.Type.STATUS -> R.string.notification_subscription_name + Notification.Type.SIGN_UP -> R.string.notification_sign_up_name + Notification.Type.UPDATE -> R.string.notification_update_name + Notification.Type.REPORT -> R.string.notification_report_name +} diff --git a/app/src/main/java/app/pachli/components/notifications/NotificationsPagingAdapter.kt b/app/src/main/java/app/pachli/components/notifications/NotificationsPagingAdapter.kt index 6fbc46671..a8084168f 100644 --- a/app/src/main/java/app/pachli/components/notifications/NotificationsPagingAdapter.kt +++ b/app/src/main/java/app/pachli/components/notifications/NotificationsPagingAdapter.kt @@ -24,6 +24,10 @@ import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView import app.pachli.adapter.FollowRequestViewHolder import app.pachli.adapter.ReportNotificationViewHolder +import app.pachli.core.common.util.AbsoluteTimeFormatter +import app.pachli.core.network.model.Filter +import app.pachli.core.network.model.Notification +import app.pachli.core.network.model.Status import app.pachli.databinding.ItemFollowBinding import app.pachli.databinding.ItemFollowRequestBinding import app.pachli.databinding.ItemReportNotificationBinding @@ -31,12 +35,8 @@ import app.pachli.databinding.ItemStatusBinding import app.pachli.databinding.ItemStatusNotificationBinding import app.pachli.databinding.ItemStatusWrapperBinding import app.pachli.databinding.SimpleListItem1Binding -import app.pachli.entity.Filter -import app.pachli.entity.Notification -import app.pachli.entity.Status import app.pachli.interfaces.AccountActionListener import app.pachli.interfaces.StatusActionListener -import app.pachli.util.AbsoluteTimeFormatter import app.pachli.util.StatusDisplayOptions import app.pachli.viewdata.NotificationViewData diff --git a/app/src/main/java/app/pachli/components/notifications/NotificationsPagingSource.kt b/app/src/main/java/app/pachli/components/notifications/NotificationsPagingSource.kt index db9b8f4ab..a842efb26 100644 --- a/app/src/main/java/app/pachli/components/notifications/NotificationsPagingSource.kt +++ b/app/src/main/java/app/pachli/components/notifications/NotificationsPagingSource.kt @@ -20,10 +20,10 @@ package app.pachli.components.notifications import androidx.paging.PagingSource import androidx.paging.PagingSource.LoadResult import androidx.paging.PagingState -import app.pachli.entity.Error -import app.pachli.entity.Notification -import app.pachli.network.Links -import app.pachli.network.MastodonApi +import app.pachli.core.network.model.Error +import app.pachli.core.network.model.Links +import app.pachli.core.network.model.Notification +import app.pachli.core.network.retrofit.MastodonApi import com.google.gson.Gson import kotlinx.coroutines.async import kotlinx.coroutines.coroutineScope diff --git a/app/src/main/java/app/pachli/components/notifications/NotificationsRepository.kt b/app/src/main/java/app/pachli/components/notifications/NotificationsRepository.kt index 341db6b95..8bd117d06 100644 --- a/app/src/main/java/app/pachli/components/notifications/NotificationsRepository.kt +++ b/app/src/main/java/app/pachli/components/notifications/NotificationsRepository.kt @@ -22,9 +22,9 @@ import androidx.paging.Pager import androidx.paging.PagingConfig import androidx.paging.PagingData import androidx.paging.PagingSource -import app.pachli.di.ApplicationScope -import app.pachli.entity.Notification -import app.pachli.network.MastodonApi +import app.pachli.core.common.di.ApplicationScope +import app.pachli.core.network.model.Notification +import app.pachli.core.network.retrofit.MastodonApi import com.google.gson.Gson import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.async diff --git a/app/src/main/java/app/pachli/components/notifications/NotificationsViewModel.kt b/app/src/main/java/app/pachli/components/notifications/NotificationsViewModel.kt index b26057de3..4774103a1 100644 --- a/app/src/main/java/app/pachli/components/notifications/NotificationsViewModel.kt +++ b/app/src/main/java/app/pachli/components/notifications/NotificationsViewModel.kt @@ -33,14 +33,14 @@ import app.pachli.appstore.MuteEvent import app.pachli.components.timeline.FilterKind import app.pachli.components.timeline.FiltersRepository import app.pachli.components.timeline.util.ifExpected -import app.pachli.db.AccountManager -import app.pachli.entity.Filter -import app.pachli.entity.Notification -import app.pachli.entity.Poll +import app.pachli.core.accounts.AccountManager +import app.pachli.core.network.model.Filter +import app.pachli.core.network.model.Notification +import app.pachli.core.network.model.Poll +import app.pachli.core.preferences.PrefKeys +import app.pachli.core.preferences.SharedPreferencesRepository import app.pachli.network.FilterModel -import app.pachli.settings.PrefKeys import app.pachli.usecase.TimelineCases -import app.pachli.util.SharedPreferencesRepository import app.pachli.util.StatusDisplayOptionsRepository import app.pachli.util.deserialize import app.pachli.util.serialize diff --git a/app/src/main/java/app/pachli/components/notifications/PushNotificationHelper.kt b/app/src/main/java/app/pachli/components/notifications/PushNotificationHelper.kt index db8bd1604..528118d68 100644 --- a/app/src/main/java/app/pachli/components/notifications/PushNotificationHelper.kt +++ b/app/src/main/java/app/pachli/components/notifications/PushNotificationHelper.kt @@ -23,12 +23,12 @@ import android.view.View import androidx.appcompat.app.AlertDialog import app.pachli.R import app.pachli.components.login.LoginActivity -import app.pachli.db.AccountEntity -import app.pachli.db.AccountManager -import app.pachli.entity.Notification -import app.pachli.network.MastodonApi +import app.pachli.core.accounts.AccountManager +import app.pachli.core.database.model.AccountEntity +import app.pachli.core.network.model.Notification +import app.pachli.core.network.retrofit.MastodonApi +import app.pachli.core.preferences.SharedPreferencesRepository import app.pachli.util.CryptoUtil -import app.pachli.util.SharedPreferencesRepository import at.connyduck.calladapter.networkresult.onFailure import at.connyduck.calladapter.networkresult.onSuccess import com.google.android.material.snackbar.Snackbar diff --git a/app/src/main/java/app/pachli/components/notifications/StatusNotificationViewHolder.kt b/app/src/main/java/app/pachli/components/notifications/StatusNotificationViewHolder.kt index c05df528c..6d3d427e4 100644 --- a/app/src/main/java/app/pachli/components/notifications/StatusNotificationViewHolder.kt +++ b/app/src/main/java/app/pachli/components/notifications/StatusNotificationViewHolder.kt @@ -34,19 +34,19 @@ import androidx.core.content.ContextCompat import androidx.recyclerview.widget.RecyclerView import app.pachli.R import app.pachli.adapter.StatusBaseViewHolder +import app.pachli.core.common.string.unicodeWrap +import app.pachli.core.common.util.AbsoluteTimeFormatter +import app.pachli.core.network.model.Emoji +import app.pachli.core.network.model.Notification import app.pachli.databinding.ItemStatusNotificationBinding -import app.pachli.entity.Emoji -import app.pachli.entity.Notification import app.pachli.interfaces.LinkListener import app.pachli.interfaces.StatusActionListener -import app.pachli.util.AbsoluteTimeFormatter import app.pachli.util.SmartLengthInputFilter import app.pachli.util.StatusDisplayOptions import app.pachli.util.emojify import app.pachli.util.getRelativeTimeSpanString import app.pachli.util.loadAvatar import app.pachli.util.setClickableText -import app.pachli.util.unicodeWrap import app.pachli.viewdata.NotificationViewData import app.pachli.viewdata.StatusViewData import at.connyduck.sparkbutton.helpers.Utils diff --git a/app/src/main/java/app/pachli/components/notifications/StatusViewHolder.kt b/app/src/main/java/app/pachli/components/notifications/StatusViewHolder.kt index 61e7ab703..d8b64119e 100644 --- a/app/src/main/java/app/pachli/components/notifications/StatusViewHolder.kt +++ b/app/src/main/java/app/pachli/components/notifications/StatusViewHolder.kt @@ -19,9 +19,9 @@ package app.pachli.components.notifications import app.pachli.adapter.FilterableStatusViewHolder import app.pachli.adapter.StatusViewHolder +import app.pachli.core.network.model.Notification import app.pachli.databinding.ItemStatusBinding import app.pachli.databinding.ItemStatusWrapperBinding -import app.pachli.entity.Notification import app.pachli.interfaces.StatusActionListener import app.pachli.util.StatusDisplayOptions import app.pachli.viewdata.NotificationViewData diff --git a/app/src/main/java/app/pachli/components/preference/AccountPreferencesFragment.kt b/app/src/main/java/app/pachli/components/preference/AccountPreferencesFragment.kt index e4464f075..e7b31acb5 100644 --- a/app/src/main/java/app/pachli/components/preference/AccountPreferencesFragment.kt +++ b/app/src/main/java/app/pachli/components/preference/AccountPreferencesFragment.kt @@ -32,12 +32,12 @@ import app.pachli.components.followedtags.FollowedTagsActivity import app.pachli.components.instancemute.InstanceListActivity import app.pachli.components.login.LoginActivity import app.pachli.components.notifications.currentAccountNeedsMigration -import app.pachli.db.AccountManager -import app.pachli.entity.Account -import app.pachli.entity.Status -import app.pachli.network.MastodonApi +import app.pachli.core.accounts.AccountManager +import app.pachli.core.network.model.Account +import app.pachli.core.network.model.Status +import app.pachli.core.network.retrofit.MastodonApi +import app.pachli.core.preferences.PrefKeys import app.pachli.settings.AccountPreferenceDataStore -import app.pachli.settings.PrefKeys import app.pachli.settings.listPreference import app.pachli.settings.makePreferenceScreen import app.pachli.settings.preference diff --git a/app/src/main/java/app/pachli/components/preference/NotificationPreferencesFragment.kt b/app/src/main/java/app/pachli/components/preference/NotificationPreferencesFragment.kt index fa2269abb..d924c449f 100644 --- a/app/src/main/java/app/pachli/components/preference/NotificationPreferencesFragment.kt +++ b/app/src/main/java/app/pachli/components/preference/NotificationPreferencesFragment.kt @@ -22,9 +22,9 @@ import app.pachli.R import app.pachli.components.notifications.disablePullNotifications import app.pachli.components.notifications.enablePullNotifications import app.pachli.components.notifications.notificationsAreEnabled -import app.pachli.db.AccountEntity -import app.pachli.db.AccountManager -import app.pachli.settings.PrefKeys +import app.pachli.core.accounts.AccountManager +import app.pachli.core.database.model.AccountEntity +import app.pachli.core.preferences.PrefKeys import app.pachli.settings.makePreferenceScreen import app.pachli.settings.preferenceCategory import app.pachli.settings.switchPreference diff --git a/app/src/main/java/app/pachli/components/preference/PreferencesActivity.kt b/app/src/main/java/app/pachli/components/preference/PreferencesActivity.kt index 8719f5387..af44b01a0 100644 --- a/app/src/main/java/app/pachli/components/preference/PreferencesActivity.kt +++ b/app/src/main/java/app/pachli/components/preference/PreferencesActivity.kt @@ -29,11 +29,11 @@ import app.pachli.BaseActivity import app.pachli.MainActivity import app.pachli.R import app.pachli.appstore.EventHub +import app.pachli.core.preferences.PrefKeys +import app.pachli.core.preferences.PrefKeys.APP_THEME +import app.pachli.core.preferences.getNonNullString import app.pachli.databinding.ActivityPreferencesBinding -import app.pachli.settings.PrefKeys -import app.pachli.settings.PrefKeys.APP_THEME import app.pachli.util.APP_THEME_DEFAULT -import app.pachli.util.getNonNullString import app.pachli.util.setAppNightMode import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.flow.filterNotNull diff --git a/app/src/main/java/app/pachli/components/preference/PreferencesFragment.kt b/app/src/main/java/app/pachli/components/preference/PreferencesFragment.kt index 1436c7fd9..ad15c2087 100644 --- a/app/src/main/java/app/pachli/components/preference/PreferencesFragment.kt +++ b/app/src/main/java/app/pachli/components/preference/PreferencesFragment.kt @@ -20,10 +20,10 @@ import android.os.Bundle import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat import app.pachli.R -import app.pachli.db.AccountManager -import app.pachli.entity.Notification -import app.pachli.settings.AppTheme -import app.pachli.settings.PrefKeys +import app.pachli.core.accounts.AccountManager +import app.pachli.core.network.model.Notification +import app.pachli.core.preferences.AppTheme +import app.pachli.core.preferences.PrefKeys import app.pachli.settings.emojiPreference import app.pachli.settings.listPreference import app.pachli.settings.makePreferenceScreen diff --git a/app/src/main/java/app/pachli/components/preference/ProxyPreferencesFragment.kt b/app/src/main/java/app/pachli/components/preference/ProxyPreferencesFragment.kt index b03b638d5..834ecd85b 100644 --- a/app/src/main/java/app/pachli/components/preference/ProxyPreferencesFragment.kt +++ b/app/src/main/java/app/pachli/components/preference/ProxyPreferencesFragment.kt @@ -20,15 +20,15 @@ import android.os.Bundle import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat import app.pachli.R -import app.pachli.settings.PrefKeys -import app.pachli.settings.ProxyConfiguration -import app.pachli.settings.ProxyConfiguration.Companion.MAX_PROXY_PORT -import app.pachli.settings.ProxyConfiguration.Companion.MIN_PROXY_PORT +import app.pachli.core.preferences.PrefKeys +import app.pachli.core.preferences.ProxyConfiguration +import app.pachli.core.preferences.ProxyConfiguration.Companion.MAX_PROXY_PORT +import app.pachli.core.preferences.ProxyConfiguration.Companion.MIN_PROXY_PORT +import app.pachli.core.preferences.getNonNullString import app.pachli.settings.makePreferenceScreen import app.pachli.settings.preferenceCategory import app.pachli.settings.switchPreference import app.pachli.settings.validatedEditTextPreference -import app.pachli.util.getNonNullString import kotlin.system.exitProcess class ProxyPreferencesFragment : PreferenceFragmentCompat() { diff --git a/app/src/main/java/app/pachli/components/preference/TabFilterPreferencesFragment.kt b/app/src/main/java/app/pachli/components/preference/TabFilterPreferencesFragment.kt index caf1e7571..f23c6ee14 100644 --- a/app/src/main/java/app/pachli/components/preference/TabFilterPreferencesFragment.kt +++ b/app/src/main/java/app/pachli/components/preference/TabFilterPreferencesFragment.kt @@ -19,7 +19,7 @@ package app.pachli.components.preference import android.os.Bundle import androidx.preference.PreferenceFragmentCompat import app.pachli.R -import app.pachli.settings.PrefKeys +import app.pachli.core.preferences.PrefKeys import app.pachli.settings.makePreferenceScreen import app.pachli.settings.preferenceCategory import app.pachli.settings.switchPreference diff --git a/app/src/main/java/app/pachli/components/report/ReportViewModel.kt b/app/src/main/java/app/pachli/components/report/ReportViewModel.kt index ea15dd77a..d344049bc 100644 --- a/app/src/main/java/app/pachli/components/report/ReportViewModel.kt +++ b/app/src/main/java/app/pachli/components/report/ReportViewModel.kt @@ -29,9 +29,9 @@ import app.pachli.appstore.EventHub import app.pachli.appstore.MuteEvent import app.pachli.components.report.adapter.StatusesPagingSource import app.pachli.components.report.model.StatusViewState -import app.pachli.entity.Relationship -import app.pachli.entity.Status -import app.pachli.network.MastodonApi +import app.pachli.core.network.model.Relationship +import app.pachli.core.network.model.Status +import app.pachli.core.network.retrofit.MastodonApi import app.pachli.util.Error import app.pachli.util.Loading import app.pachli.util.Resource diff --git a/app/src/main/java/app/pachli/components/report/adapter/AdapterHandler.kt b/app/src/main/java/app/pachli/components/report/adapter/AdapterHandler.kt index 17e8fac1e..65b80f0d2 100644 --- a/app/src/main/java/app/pachli/components/report/adapter/AdapterHandler.kt +++ b/app/src/main/java/app/pachli/components/report/adapter/AdapterHandler.kt @@ -17,7 +17,7 @@ package app.pachli.components.report.adapter import android.view.View -import app.pachli.entity.Status +import app.pachli.core.network.model.Status import app.pachli.interfaces.LinkListener interface AdapterHandler : LinkListener { diff --git a/app/src/main/java/app/pachli/components/report/adapter/StatusViewHolder.kt b/app/src/main/java/app/pachli/components/report/adapter/StatusViewHolder.kt index cf15ee9d9..94b2e9b34 100644 --- a/app/src/main/java/app/pachli/components/report/adapter/StatusViewHolder.kt +++ b/app/src/main/java/app/pachli/components/report/adapter/StatusViewHolder.kt @@ -22,12 +22,12 @@ import android.view.View import androidx.recyclerview.widget.RecyclerView import app.pachli.R import app.pachli.components.report.model.StatusViewState +import app.pachli.core.common.util.AbsoluteTimeFormatter +import app.pachli.core.network.model.Emoji +import app.pachli.core.network.model.HashTag +import app.pachli.core.network.model.Status import app.pachli.databinding.ItemReportStatusBinding -import app.pachli.entity.Emoji -import app.pachli.entity.HashTag -import app.pachli.entity.Status import app.pachli.interfaces.LinkListener -import app.pachli.util.AbsoluteTimeFormatter import app.pachli.util.StatusDisplayOptions import app.pachli.util.StatusViewHelper import app.pachli.util.StatusViewHelper.Companion.COLLAPSE_INPUT_FILTER diff --git a/app/src/main/java/app/pachli/components/report/adapter/StatusesPagingSource.kt b/app/src/main/java/app/pachli/components/report/adapter/StatusesPagingSource.kt index dabc152f9..4c1a21a0c 100644 --- a/app/src/main/java/app/pachli/components/report/adapter/StatusesPagingSource.kt +++ b/app/src/main/java/app/pachli/components/report/adapter/StatusesPagingSource.kt @@ -18,8 +18,8 @@ package app.pachli.components.report.adapter import androidx.paging.PagingSource import androidx.paging.PagingState -import app.pachli.entity.Status -import app.pachli.network.MastodonApi +import app.pachli.core.network.model.Status +import app.pachli.core.network.retrofit.MastodonApi import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async import kotlinx.coroutines.withContext diff --git a/app/src/main/java/app/pachli/components/report/fragments/ReportStatusesFragment.kt b/app/src/main/java/app/pachli/components/report/fragments/ReportStatusesFragment.kt index bff02014c..4c5f708d9 100644 --- a/app/src/main/java/app/pachli/components/report/fragments/ReportStatusesFragment.kt +++ b/app/src/main/java/app/pachli/components/report/fragments/ReportStatusesFragment.kt @@ -40,10 +40,10 @@ import app.pachli.components.report.ReportViewModel import app.pachli.components.report.Screen import app.pachli.components.report.adapter.AdapterHandler import app.pachli.components.report.adapter.StatusesAdapter +import app.pachli.core.accounts.AccountManager +import app.pachli.core.network.model.Attachment +import app.pachli.core.network.model.Status import app.pachli.databinding.FragmentReportStatusesBinding -import app.pachli.db.AccountManager -import app.pachli.entity.Attachment -import app.pachli.entity.Status import app.pachli.util.viewBinding import app.pachli.util.visible import app.pachli.viewdata.AttachmentViewData diff --git a/app/src/main/java/app/pachli/components/scheduled/ScheduledStatusActivity.kt b/app/src/main/java/app/pachli/components/scheduled/ScheduledStatusActivity.kt index 5e0fbb5f2..8f4a15a71 100644 --- a/app/src/main/java/app/pachli/components/scheduled/ScheduledStatusActivity.kt +++ b/app/src/main/java/app/pachli/components/scheduled/ScheduledStatusActivity.kt @@ -33,8 +33,8 @@ import app.pachli.R import app.pachli.appstore.EventHub import app.pachli.appstore.StatusScheduledEvent import app.pachli.components.compose.ComposeActivity +import app.pachli.core.network.model.ScheduledStatus import app.pachli.databinding.ActivityScheduledStatusBinding -import app.pachli.entity.ScheduledStatus import app.pachli.util.hide import app.pachli.util.show import app.pachli.util.viewBinding diff --git a/app/src/main/java/app/pachli/components/scheduled/ScheduledStatusAdapter.kt b/app/src/main/java/app/pachli/components/scheduled/ScheduledStatusAdapter.kt index f58ed7d07..df0763e2e 100644 --- a/app/src/main/java/app/pachli/components/scheduled/ScheduledStatusAdapter.kt +++ b/app/src/main/java/app/pachli/components/scheduled/ScheduledStatusAdapter.kt @@ -20,8 +20,8 @@ import android.view.LayoutInflater import android.view.ViewGroup import androidx.paging.PagingDataAdapter import androidx.recyclerview.widget.DiffUtil +import app.pachli.core.network.model.ScheduledStatus import app.pachli.databinding.ItemScheduledStatusBinding -import app.pachli.entity.ScheduledStatus import app.pachli.util.BindingHolder interface ScheduledStatusActionListener { diff --git a/app/src/main/java/app/pachli/components/scheduled/ScheduledStatusPagingSource.kt b/app/src/main/java/app/pachli/components/scheduled/ScheduledStatusPagingSource.kt index 7a6940159..4502a5406 100644 --- a/app/src/main/java/app/pachli/components/scheduled/ScheduledStatusPagingSource.kt +++ b/app/src/main/java/app/pachli/components/scheduled/ScheduledStatusPagingSource.kt @@ -18,8 +18,8 @@ package app.pachli.components.scheduled import androidx.paging.PagingSource import androidx.paging.PagingState -import app.pachli.entity.ScheduledStatus -import app.pachli.network.MastodonApi +import app.pachli.core.network.model.ScheduledStatus +import app.pachli.core.network.retrofit.MastodonApi import at.connyduck.calladapter.networkresult.getOrElse class ScheduledStatusPagingSourceFactory( diff --git a/app/src/main/java/app/pachli/components/scheduled/ScheduledStatusViewModel.kt b/app/src/main/java/app/pachli/components/scheduled/ScheduledStatusViewModel.kt index 8b5cb1f74..03f85ccec 100644 --- a/app/src/main/java/app/pachli/components/scheduled/ScheduledStatusViewModel.kt +++ b/app/src/main/java/app/pachli/components/scheduled/ScheduledStatusViewModel.kt @@ -22,8 +22,8 @@ import androidx.paging.Pager import androidx.paging.PagingConfig import androidx.paging.cachedIn import app.pachli.appstore.EventHub -import app.pachli.entity.ScheduledStatus -import app.pachli.network.MastodonApi +import app.pachli.core.network.model.ScheduledStatus +import app.pachli.core.network.retrofit.MastodonApi import at.connyduck.calladapter.networkresult.fold import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch diff --git a/app/src/main/java/app/pachli/components/search/SearchActivity.kt b/app/src/main/java/app/pachli/components/search/SearchActivity.kt index 25657cd87..c94699e93 100644 --- a/app/src/main/java/app/pachli/components/search/SearchActivity.kt +++ b/app/src/main/java/app/pachli/components/search/SearchActivity.kt @@ -29,8 +29,8 @@ import androidx.core.view.MenuProvider import app.pachli.BottomSheetActivity import app.pachli.R import app.pachli.components.search.adapter.SearchPagerAdapter +import app.pachli.core.preferences.PrefKeys import app.pachli.databinding.ActivitySearchBinding -import app.pachli.settings.PrefKeys import app.pachli.util.reduceSwipeSensitivity import app.pachli.util.viewBinding import com.google.android.material.tabs.TabLayoutMediator diff --git a/app/src/main/java/app/pachli/components/search/SearchViewModel.kt b/app/src/main/java/app/pachli/components/search/SearchViewModel.kt index 310f47197..f9b6630e3 100644 --- a/app/src/main/java/app/pachli/components/search/SearchViewModel.kt +++ b/app/src/main/java/app/pachli/components/search/SearchViewModel.kt @@ -22,11 +22,11 @@ import androidx.paging.Pager import androidx.paging.PagingConfig import androidx.paging.cachedIn import app.pachli.components.search.adapter.SearchPagingSourceFactory -import app.pachli.db.AccountEntity -import app.pachli.db.AccountManager -import app.pachli.entity.DeletedStatus -import app.pachli.entity.Status -import app.pachli.network.MastodonApi +import app.pachli.core.accounts.AccountManager +import app.pachli.core.database.model.AccountEntity +import app.pachli.core.network.model.DeletedStatus +import app.pachli.core.network.model.Status +import app.pachli.core.network.retrofit.MastodonApi import app.pachli.usecase.TimelineCases import app.pachli.viewdata.StatusViewData import at.connyduck.calladapter.networkresult.NetworkResult diff --git a/app/src/main/java/app/pachli/components/search/adapter/SearchAccountsAdapter.kt b/app/src/main/java/app/pachli/components/search/adapter/SearchAccountsAdapter.kt index 249c8e64e..07104bf9b 100644 --- a/app/src/main/java/app/pachli/components/search/adapter/SearchAccountsAdapter.kt +++ b/app/src/main/java/app/pachli/components/search/adapter/SearchAccountsAdapter.kt @@ -21,8 +21,8 @@ import android.view.ViewGroup import androidx.paging.PagingDataAdapter import androidx.recyclerview.widget.DiffUtil import app.pachli.adapter.AccountViewHolder +import app.pachli.core.network.model.TimelineAccount import app.pachli.databinding.ItemAccountBinding -import app.pachli.entity.TimelineAccount import app.pachli.interfaces.LinkListener class SearchAccountsAdapter(private val linkListener: LinkListener, private val animateAvatars: Boolean, private val animateEmojis: Boolean, private val showBotOverlay: Boolean) : diff --git a/app/src/main/java/app/pachli/components/search/adapter/SearchHashtagsAdapter.kt b/app/src/main/java/app/pachli/components/search/adapter/SearchHashtagsAdapter.kt index a089e84b1..10f8f7809 100644 --- a/app/src/main/java/app/pachli/components/search/adapter/SearchHashtagsAdapter.kt +++ b/app/src/main/java/app/pachli/components/search/adapter/SearchHashtagsAdapter.kt @@ -20,8 +20,8 @@ import android.view.LayoutInflater import android.view.ViewGroup import androidx.paging.PagingDataAdapter import androidx.recyclerview.widget.DiffUtil +import app.pachli.core.network.model.HashTag import app.pachli.databinding.ItemHashtagBinding -import app.pachli.entity.HashTag import app.pachli.interfaces.LinkListener import app.pachli.util.BindingHolder diff --git a/app/src/main/java/app/pachli/components/search/adapter/SearchPagingSource.kt b/app/src/main/java/app/pachli/components/search/adapter/SearchPagingSource.kt index 67470f205..abe3312c7 100644 --- a/app/src/main/java/app/pachli/components/search/adapter/SearchPagingSource.kt +++ b/app/src/main/java/app/pachli/components/search/adapter/SearchPagingSource.kt @@ -19,8 +19,8 @@ package app.pachli.components.search.adapter import androidx.paging.PagingSource import androidx.paging.PagingState import app.pachli.components.search.SearchType -import app.pachli.entity.SearchResult -import app.pachli.network.MastodonApi +import app.pachli.core.network.model.SearchResult +import app.pachli.core.network.retrofit.MastodonApi import at.connyduck.calladapter.networkresult.getOrElse class SearchPagingSource( diff --git a/app/src/main/java/app/pachli/components/search/adapter/SearchPagingSourceFactory.kt b/app/src/main/java/app/pachli/components/search/adapter/SearchPagingSourceFactory.kt index 0ec5b3864..93de3f8d9 100644 --- a/app/src/main/java/app/pachli/components/search/adapter/SearchPagingSourceFactory.kt +++ b/app/src/main/java/app/pachli/components/search/adapter/SearchPagingSourceFactory.kt @@ -17,8 +17,8 @@ package app.pachli.components.search.adapter import app.pachli.components.search.SearchType -import app.pachli.entity.SearchResult -import app.pachli.network.MastodonApi +import app.pachli.core.network.model.SearchResult +import app.pachli.core.network.retrofit.MastodonApi class SearchPagingSourceFactory( private val mastodonApi: MastodonApi, diff --git a/app/src/main/java/app/pachli/components/search/fragments/SearchAccountsFragment.kt b/app/src/main/java/app/pachli/components/search/fragments/SearchAccountsFragment.kt index 376f5d5a3..251d4d723 100644 --- a/app/src/main/java/app/pachli/components/search/fragments/SearchAccountsFragment.kt +++ b/app/src/main/java/app/pachli/components/search/fragments/SearchAccountsFragment.kt @@ -21,9 +21,9 @@ import android.view.View import androidx.paging.PagingData import androidx.paging.PagingDataAdapter import app.pachli.components.search.adapter.SearchAccountsAdapter -import app.pachli.entity.TimelineAccount -import app.pachli.settings.PrefKeys -import app.pachli.util.SharedPreferencesRepository +import app.pachli.core.network.model.TimelineAccount +import app.pachli.core.preferences.PrefKeys +import app.pachli.core.preferences.SharedPreferencesRepository import com.google.android.material.divider.MaterialDividerItemDecoration import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.flow.Flow diff --git a/app/src/main/java/app/pachli/components/search/fragments/SearchFragment.kt b/app/src/main/java/app/pachli/components/search/fragments/SearchFragment.kt index 81c49a5f3..b295ebe82 100644 --- a/app/src/main/java/app/pachli/components/search/fragments/SearchFragment.kt +++ b/app/src/main/java/app/pachli/components/search/fragments/SearchFragment.kt @@ -21,9 +21,9 @@ import app.pachli.R import app.pachli.StatusListActivity import app.pachli.components.account.AccountActivity import app.pachli.components.search.SearchViewModel +import app.pachli.core.network.retrofit.MastodonApi import app.pachli.databinding.FragmentSearchBinding import app.pachli.interfaces.LinkListener -import app.pachli.network.MastodonApi import app.pachli.util.viewBinding import app.pachli.util.visible import com.google.android.material.color.MaterialColors diff --git a/app/src/main/java/app/pachli/components/search/fragments/SearchHashtagsFragment.kt b/app/src/main/java/app/pachli/components/search/fragments/SearchHashtagsFragment.kt index c371e41fa..f1c4398a3 100644 --- a/app/src/main/java/app/pachli/components/search/fragments/SearchHashtagsFragment.kt +++ b/app/src/main/java/app/pachli/components/search/fragments/SearchHashtagsFragment.kt @@ -21,7 +21,7 @@ import android.view.View import androidx.paging.PagingData import androidx.paging.PagingDataAdapter import app.pachli.components.search.adapter.SearchHashtagsAdapter -import app.pachli.entity.HashTag +import app.pachli.core.network.model.HashTag import com.google.android.material.divider.MaterialDividerItemDecoration import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.flow.Flow diff --git a/app/src/main/java/app/pachli/components/search/fragments/SearchStatusesFragment.kt b/app/src/main/java/app/pachli/components/search/fragments/SearchStatusesFragment.kt index 16ee3b5ec..1168f34bf 100644 --- a/app/src/main/java/app/pachli/components/search/fragments/SearchStatusesFragment.kt +++ b/app/src/main/java/app/pachli/components/search/fragments/SearchStatusesFragment.kt @@ -43,10 +43,10 @@ import app.pachli.components.compose.ComposeActivity import app.pachli.components.compose.ComposeActivity.ComposeOptions import app.pachli.components.report.ReportActivity import app.pachli.components.search.adapter.SearchStatusesAdapter -import app.pachli.db.AccountEntity -import app.pachli.entity.Attachment -import app.pachli.entity.Status -import app.pachli.entity.Status.Mention +import app.pachli.core.database.model.AccountEntity +import app.pachli.core.network.model.Attachment +import app.pachli.core.network.model.Status +import app.pachli.core.network.model.Status.Mention import app.pachli.interfaces.AccountSelectionListener import app.pachli.interfaces.StatusActionListener import app.pachli.util.StatusDisplayOptionsRepository @@ -239,7 +239,7 @@ class SearchStatusesFragment : SearchFragment(), StatusActionLis } Status.Visibility.PRIVATE -> { var reblogged = status.reblogged - if (status.reblog != null) reblogged = status.reblog.reblogged + status.reblog?.apply { reblogged = this.reblogged } menu.findItem(R.id.status_reblog_private).isVisible = !reblogged menu.findItem(R.id.status_unreblog_private).isVisible = reblogged } diff --git a/app/src/main/java/app/pachli/components/timeline/CachedTimelineRepository.kt b/app/src/main/java/app/pachli/components/timeline/CachedTimelineRepository.kt index 296338e24..a65b28a18 100644 --- a/app/src/main/java/app/pachli/components/timeline/CachedTimelineRepository.kt +++ b/app/src/main/java/app/pachli/components/timeline/CachedTimelineRepository.kt @@ -23,20 +23,20 @@ import androidx.paging.Pager import androidx.paging.PagingConfig import androidx.paging.PagingData import app.pachli.components.timeline.viewmodel.CachedTimelineRemoteMediator -import app.pachli.db.AccountManager -import app.pachli.db.RemoteKeyDao -import app.pachli.db.StatusViewDataEntity -import app.pachli.db.TimelineDao -import app.pachli.db.TimelineStatusWithAccount -import app.pachli.db.TranslatedStatusDao -import app.pachli.db.TranslatedStatusEntity -import app.pachli.di.ApplicationScope -import app.pachli.di.TransactionProvider -import app.pachli.entity.Translation -import app.pachli.network.MastodonApi +import app.pachli.core.accounts.AccountManager +import app.pachli.core.common.di.ApplicationScope +import app.pachli.core.database.dao.RemoteKeyDao +import app.pachli.core.database.dao.TimelineDao +import app.pachli.core.database.dao.TranslatedStatusDao +import app.pachli.core.database.di.TransactionProvider +import app.pachli.core.database.model.StatusViewDataEntity +import app.pachli.core.database.model.TimelineStatusWithAccount +import app.pachli.core.database.model.TranslatedStatusEntity +import app.pachli.core.database.model.TranslationState +import app.pachli.core.network.model.Translation +import app.pachli.core.network.retrofit.MastodonApi import app.pachli.util.EmptyPagingSource import app.pachli.viewdata.StatusViewData -import app.pachli.viewdata.TranslationState import at.connyduck.calladapter.networkresult.NetworkResult import at.connyduck.calladapter.networkresult.fold import com.google.gson.Gson diff --git a/app/src/main/java/app/pachli/components/timeline/FiltersRepository.kt b/app/src/main/java/app/pachli/components/timeline/FiltersRepository.kt index 16dc061e7..9d9c24d8c 100644 --- a/app/src/main/java/app/pachli/components/timeline/FiltersRepository.kt +++ b/app/src/main/java/app/pachli/components/timeline/FiltersRepository.kt @@ -17,9 +17,9 @@ package app.pachli.components.timeline -import app.pachli.entity.Filter -import app.pachli.entity.FilterV1 -import app.pachli.network.MastodonApi +import app.pachli.core.network.model.Filter +import app.pachli.core.network.model.FilterV1 +import app.pachli.core.network.retrofit.MastodonApi import at.connyduck.calladapter.networkresult.fold import at.connyduck.calladapter.networkresult.getOrThrow import retrofit2.HttpException diff --git a/app/src/main/java/app/pachli/components/timeline/NetworkTimelineRepository.kt b/app/src/main/java/app/pachli/components/timeline/NetworkTimelineRepository.kt index 60f63701d..39fc98053 100644 --- a/app/src/main/java/app/pachli/components/timeline/NetworkTimelineRepository.kt +++ b/app/src/main/java/app/pachli/components/timeline/NetworkTimelineRepository.kt @@ -26,9 +26,9 @@ import androidx.paging.PagingSource import app.pachli.components.timeline.viewmodel.NetworkTimelinePagingSource import app.pachli.components.timeline.viewmodel.NetworkTimelineRemoteMediator import app.pachli.components.timeline.viewmodel.PageCache -import app.pachli.db.AccountManager -import app.pachli.entity.Status -import app.pachli.network.MastodonApi +import app.pachli.core.accounts.AccountManager +import app.pachli.core.network.model.Status +import app.pachli.core.network.retrofit.MastodonApi import app.pachli.util.getDomain import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.Flow @@ -156,11 +156,9 @@ class NetworkTimelineRepository @Inject constructor( val index = page.data.indexOfFirst { it.id == statusId } if (index != -1) { val status = page.data[index] - if (status.reblog != null) { - page.data[index] = status.copy(reblog = updater(status.reblog)) - } else { - page.data[index] = updater(status) - } + page.data[index] = status.reblog?.let { + status.copy(reblog = it) + } ?: updater(status) } } } diff --git a/app/src/main/java/app/pachli/components/timeline/TimelineFragment.kt b/app/src/main/java/app/pachli/components/timeline/TimelineFragment.kt index 1f4c41c7d..0c973d6e5 100644 --- a/app/src/main/java/app/pachli/components/timeline/TimelineFragment.kt +++ b/app/src/main/java/app/pachli/components/timeline/TimelineFragment.kt @@ -51,8 +51,9 @@ import app.pachli.components.timeline.viewmodel.StatusAction import app.pachli.components.timeline.viewmodel.StatusActionSuccess import app.pachli.components.timeline.viewmodel.TimelineViewModel import app.pachli.components.timeline.viewmodel.UiSuccess +import app.pachli.core.database.model.TranslationState +import app.pachli.core.network.model.Status import app.pachli.databinding.FragmentTimelineBinding -import app.pachli.entity.Status import app.pachli.fragment.SFragment import app.pachli.interfaces.ActionButtonActivity import app.pachli.interfaces.AppBarLayoutHost @@ -72,7 +73,6 @@ import app.pachli.util.visible import app.pachli.util.withPresentationState import app.pachli.viewdata.AttachmentViewData import app.pachli.viewdata.StatusViewData -import app.pachli.viewdata.TranslationState import at.connyduck.sparkbutton.helpers.Utils import com.google.android.material.color.MaterialColors import com.google.android.material.divider.MaterialDividerItemDecoration diff --git a/app/src/main/java/app/pachli/components/timeline/TimelinePagingAdapter.kt b/app/src/main/java/app/pachli/components/timeline/TimelinePagingAdapter.kt index ea16826d4..abad4f4f6 100644 --- a/app/src/main/java/app/pachli/components/timeline/TimelinePagingAdapter.kt +++ b/app/src/main/java/app/pachli/components/timeline/TimelinePagingAdapter.kt @@ -25,9 +25,9 @@ import app.pachli.R import app.pachli.adapter.FilterableStatusViewHolder import app.pachli.adapter.StatusBaseViewHolder import app.pachli.adapter.StatusViewHolder +import app.pachli.core.network.model.Filter import app.pachli.databinding.ItemStatusBinding import app.pachli.databinding.ItemStatusWrapperBinding -import app.pachli.entity.Filter import app.pachli.interfaces.StatusActionListener import app.pachli.util.StatusDisplayOptions import app.pachli.viewdata.StatusViewData diff --git a/app/src/main/java/app/pachli/components/timeline/viewmodel/CachedTimelineRemoteMediator.kt b/app/src/main/java/app/pachli/components/timeline/viewmodel/CachedTimelineRemoteMediator.kt index b47c7d522..8e44728c9 100644 --- a/app/src/main/java/app/pachli/components/timeline/viewmodel/CachedTimelineRemoteMediator.kt +++ b/app/src/main/java/app/pachli/components/timeline/viewmodel/CachedTimelineRemoteMediator.kt @@ -24,18 +24,18 @@ import androidx.paging.LoadType import androidx.paging.PagingState import androidx.paging.RemoteMediator import androidx.room.Transaction -import app.pachli.db.AccountManager -import app.pachli.db.RemoteKeyDao -import app.pachli.db.RemoteKeyEntity -import app.pachli.db.RemoteKeyKind -import app.pachli.db.TimelineAccountEntity -import app.pachli.db.TimelineDao -import app.pachli.db.TimelineStatusEntity -import app.pachli.db.TimelineStatusWithAccount -import app.pachli.di.TransactionProvider -import app.pachli.entity.Status -import app.pachli.network.Links -import app.pachli.network.MastodonApi +import app.pachli.core.accounts.AccountManager +import app.pachli.core.database.dao.RemoteKeyDao +import app.pachli.core.database.dao.TimelineDao +import app.pachli.core.database.di.TransactionProvider +import app.pachli.core.database.model.RemoteKeyEntity +import app.pachli.core.database.model.RemoteKeyKind +import app.pachli.core.database.model.TimelineAccountEntity +import app.pachli.core.database.model.TimelineStatusEntity +import app.pachli.core.database.model.TimelineStatusWithAccount +import app.pachli.core.network.model.Links +import app.pachli.core.network.model.Status +import app.pachli.core.network.retrofit.MastodonApi import com.google.gson.Gson import kotlinx.coroutines.async import kotlinx.coroutines.coroutineScope diff --git a/app/src/main/java/app/pachli/components/timeline/viewmodel/CachedTimelineViewModel.kt b/app/src/main/java/app/pachli/components/timeline/viewmodel/CachedTimelineViewModel.kt index 59cb7b2b9..e93618012 100644 --- a/app/src/main/java/app/pachli/components/timeline/viewmodel/CachedTimelineViewModel.kt +++ b/app/src/main/java/app/pachli/components/timeline/viewmodel/CachedTimelineViewModel.kt @@ -30,11 +30,11 @@ import app.pachli.appstore.PinEvent import app.pachli.appstore.ReblogEvent import app.pachli.components.timeline.CachedTimelineRepository import app.pachli.components.timeline.FiltersRepository -import app.pachli.db.AccountManager -import app.pachli.entity.Filter -import app.pachli.entity.Poll +import app.pachli.core.accounts.AccountManager +import app.pachli.core.network.model.Filter +import app.pachli.core.network.model.Poll +import app.pachli.core.preferences.SharedPreferencesRepository import app.pachli.usecase.TimelineCases -import app.pachli.util.SharedPreferencesRepository import app.pachli.util.StatusDisplayOptionsRepository import app.pachli.viewdata.StatusViewData import com.google.gson.Gson diff --git a/app/src/main/java/app/pachli/components/timeline/viewmodel/NetworkTimelinePagingSource.kt b/app/src/main/java/app/pachli/components/timeline/viewmodel/NetworkTimelinePagingSource.kt index 4465ab79e..2e448c5a6 100644 --- a/app/src/main/java/app/pachli/components/timeline/viewmodel/NetworkTimelinePagingSource.kt +++ b/app/src/main/java/app/pachli/components/timeline/viewmodel/NetworkTimelinePagingSource.kt @@ -20,7 +20,7 @@ package app.pachli.components.timeline.viewmodel import androidx.paging.PagingSource import androidx.paging.PagingSource.LoadResult import androidx.paging.PagingState -import app.pachli.entity.Status +import app.pachli.core.network.model.Status import timber.log.Timber import javax.inject.Inject diff --git a/app/src/main/java/app/pachli/components/timeline/viewmodel/NetworkTimelineRemoteMediator.kt b/app/src/main/java/app/pachli/components/timeline/viewmodel/NetworkTimelineRemoteMediator.kt index 40c50a797..f0e0057b5 100644 --- a/app/src/main/java/app/pachli/components/timeline/viewmodel/NetworkTimelineRemoteMediator.kt +++ b/app/src/main/java/app/pachli/components/timeline/viewmodel/NetworkTimelineRemoteMediator.kt @@ -24,9 +24,9 @@ import androidx.paging.PagingState import androidx.paging.RemoteMediator import app.pachli.BuildConfig import app.pachli.components.timeline.TimelineKind -import app.pachli.db.AccountManager -import app.pachli.entity.Status -import app.pachli.network.MastodonApi +import app.pachli.core.accounts.AccountManager +import app.pachli.core.network.model.Status +import app.pachli.core.network.retrofit.MastodonApi import kotlinx.coroutines.CoroutineScope import retrofit2.HttpException import retrofit2.Response diff --git a/app/src/main/java/app/pachli/components/timeline/viewmodel/NetworkTimelineViewModel.kt b/app/src/main/java/app/pachli/components/timeline/viewmodel/NetworkTimelineViewModel.kt index 3a826eb66..d279d9ac0 100644 --- a/app/src/main/java/app/pachli/components/timeline/viewmodel/NetworkTimelineViewModel.kt +++ b/app/src/main/java/app/pachli/components/timeline/viewmodel/NetworkTimelineViewModel.kt @@ -30,11 +30,11 @@ import app.pachli.appstore.PinEvent import app.pachli.appstore.ReblogEvent import app.pachli.components.timeline.FiltersRepository import app.pachli.components.timeline.NetworkTimelineRepository -import app.pachli.db.AccountManager -import app.pachli.entity.Filter -import app.pachli.entity.Poll +import app.pachli.core.accounts.AccountManager +import app.pachli.core.network.model.Filter +import app.pachli.core.network.model.Poll +import app.pachli.core.preferences.SharedPreferencesRepository import app.pachli.usecase.TimelineCases -import app.pachli.util.SharedPreferencesRepository import app.pachli.util.StatusDisplayOptionsRepository import app.pachli.viewdata.StatusViewData import dagger.hilt.android.lifecycle.HiltViewModel diff --git a/app/src/main/java/app/pachli/components/timeline/viewmodel/PageCache.kt b/app/src/main/java/app/pachli/components/timeline/viewmodel/PageCache.kt index 62af468fe..8d5c1ff2c 100644 --- a/app/src/main/java/app/pachli/components/timeline/viewmodel/PageCache.kt +++ b/app/src/main/java/app/pachli/components/timeline/viewmodel/PageCache.kt @@ -18,9 +18,9 @@ package app.pachli.components.timeline.viewmodel import app.pachli.BuildConfig -import app.pachli.entity.Status -import app.pachli.network.Links -import app.pachli.util.isLessThan +import app.pachli.core.common.string.isLessThan +import app.pachli.core.network.model.Links +import app.pachli.core.network.model.Status import retrofit2.HttpException import retrofit2.Response import timber.log.Timber diff --git a/app/src/main/java/app/pachli/components/timeline/viewmodel/TimelineViewModel.kt b/app/src/main/java/app/pachli/components/timeline/viewmodel/TimelineViewModel.kt index 30fbfcf95..358c2ac4e 100644 --- a/app/src/main/java/app/pachli/components/timeline/viewmodel/TimelineViewModel.kt +++ b/app/src/main/java/app/pachli/components/timeline/viewmodel/TimelineViewModel.kt @@ -45,14 +45,14 @@ import app.pachli.components.timeline.FilterKind import app.pachli.components.timeline.FiltersRepository import app.pachli.components.timeline.TimelineKind import app.pachli.components.timeline.util.ifExpected -import app.pachli.db.AccountManager -import app.pachli.entity.Filter -import app.pachli.entity.Poll -import app.pachli.entity.Status +import app.pachli.core.accounts.AccountManager +import app.pachli.core.network.model.Filter +import app.pachli.core.network.model.Poll +import app.pachli.core.network.model.Status +import app.pachli.core.preferences.PrefKeys +import app.pachli.core.preferences.SharedPreferencesRepository import app.pachli.network.FilterModel -import app.pachli.settings.PrefKeys import app.pachli.usecase.TimelineCases -import app.pachli.util.SharedPreferencesRepository import app.pachli.util.StatusDisplayOptionsRepository import app.pachli.util.throttleFirst import app.pachli.viewdata.StatusViewData diff --git a/app/src/main/java/app/pachli/components/trending/TrendingLinkViewHolder.kt b/app/src/main/java/app/pachli/components/trending/TrendingLinkViewHolder.kt index e1e7f2216..dd535da4d 100644 --- a/app/src/main/java/app/pachli/components/trending/TrendingLinkViewHolder.kt +++ b/app/src/main/java/app/pachli/components/trending/TrendingLinkViewHolder.kt @@ -18,8 +18,8 @@ package app.pachli.components.trending import androidx.recyclerview.widget.RecyclerView +import app.pachli.core.network.model.TrendsLink import app.pachli.databinding.ItemTrendingLinkBinding -import app.pachli.entity.TrendsLink import app.pachli.util.StatusDisplayOptions class TrendingLinkViewHolder( diff --git a/app/src/main/java/app/pachli/components/trending/TrendingLinksAdapter.kt b/app/src/main/java/app/pachli/components/trending/TrendingLinksAdapter.kt index f0f3112ad..471fa02f2 100644 --- a/app/src/main/java/app/pachli/components/trending/TrendingLinksAdapter.kt +++ b/app/src/main/java/app/pachli/components/trending/TrendingLinksAdapter.kt @@ -22,8 +22,8 @@ import android.view.ViewGroup import androidx.recyclerview.widget.DiffUtil.ItemCallback import androidx.recyclerview.widget.ListAdapter import app.pachli.R +import app.pachli.core.network.model.TrendsLink import app.pachli.databinding.ItemTrendingLinkBinding -import app.pachli.entity.TrendsLink import app.pachli.util.StatusDisplayOptions class TrendingLinksAdapter( diff --git a/app/src/main/java/app/pachli/components/trending/TrendingLinksRepository.kt b/app/src/main/java/app/pachli/components/trending/TrendingLinksRepository.kt index 72ee89b32..7aea9310b 100644 --- a/app/src/main/java/app/pachli/components/trending/TrendingLinksRepository.kt +++ b/app/src/main/java/app/pachli/components/trending/TrendingLinksRepository.kt @@ -17,7 +17,7 @@ package app.pachli.components.trending -import app.pachli.network.MastodonApi +import app.pachli.core.network.retrofit.MastodonApi import javax.inject.Inject class TrendingLinksRepository @Inject constructor( diff --git a/app/src/main/java/app/pachli/components/trending/TrendingTagViewHolder.kt b/app/src/main/java/app/pachli/components/trending/TrendingTagViewHolder.kt index d5736aac4..f2e7cad95 100644 --- a/app/src/main/java/app/pachli/components/trending/TrendingTagViewHolder.kt +++ b/app/src/main/java/app/pachli/components/trending/TrendingTagViewHolder.kt @@ -18,8 +18,8 @@ package app.pachli.components.trending import androidx.recyclerview.widget.RecyclerView import app.pachli.R +import app.pachli.core.common.util.formatNumber import app.pachli.databinding.ItemTrendingCellBinding -import app.pachli.util.formatNumber import app.pachli.viewdata.TrendingViewData class TrendingTagViewHolder( diff --git a/app/src/main/java/app/pachli/components/trending/viewmodel/TrendingLinksViewModel.kt b/app/src/main/java/app/pachli/components/trending/viewmodel/TrendingLinksViewModel.kt index ecd564dc7..199ebc502 100644 --- a/app/src/main/java/app/pachli/components/trending/viewmodel/TrendingLinksViewModel.kt +++ b/app/src/main/java/app/pachli/components/trending/viewmodel/TrendingLinksViewModel.kt @@ -20,8 +20,8 @@ package app.pachli.components.trending.viewmodel import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import app.pachli.components.trending.TrendingLinksRepository -import app.pachli.db.AccountManager -import app.pachli.entity.TrendsLink +import app.pachli.core.accounts.AccountManager +import app.pachli.core.network.model.TrendsLink import app.pachli.util.StatusDisplayOptionsRepository import app.pachli.util.throttleFirst import at.connyduck.calladapter.networkresult.fold diff --git a/app/src/main/java/app/pachli/components/trending/viewmodel/TrendingTagsViewModel.kt b/app/src/main/java/app/pachli/components/trending/viewmodel/TrendingTagsViewModel.kt index ef19aad62..81b29eda4 100644 --- a/app/src/main/java/app/pachli/components/trending/viewmodel/TrendingTagsViewModel.kt +++ b/app/src/main/java/app/pachli/components/trending/viewmodel/TrendingTagsViewModel.kt @@ -20,11 +20,11 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import app.pachli.appstore.EventHub import app.pachli.appstore.FilterChangedEvent -import app.pachli.entity.Filter -import app.pachli.entity.TrendingTag -import app.pachli.entity.end -import app.pachli.entity.start -import app.pachli.network.MastodonApi +import app.pachli.core.network.model.Filter +import app.pachli.core.network.model.TrendingTag +import app.pachli.core.network.model.end +import app.pachli.core.network.model.start +import app.pachli.core.network.retrofit.MastodonApi import app.pachli.viewdata.TrendingViewData import at.connyduck.calladapter.networkresult.fold import dagger.hilt.android.lifecycle.HiltViewModel diff --git a/app/src/main/java/app/pachli/components/viewthread/ThreadAdapter.kt b/app/src/main/java/app/pachli/components/viewthread/ThreadAdapter.kt index 5ab2e701e..75624bc43 100644 --- a/app/src/main/java/app/pachli/components/viewthread/ThreadAdapter.kt +++ b/app/src/main/java/app/pachli/components/viewthread/ThreadAdapter.kt @@ -24,10 +24,10 @@ import app.pachli.adapter.FilterableStatusViewHolder import app.pachli.adapter.StatusBaseViewHolder import app.pachli.adapter.StatusDetailedViewHolder import app.pachli.adapter.StatusViewHolder +import app.pachli.core.network.model.Filter import app.pachli.databinding.ItemStatusBinding import app.pachli.databinding.ItemStatusDetailedBinding import app.pachli.databinding.ItemStatusWrapperBinding -import app.pachli.entity.Filter import app.pachli.interfaces.StatusActionListener import app.pachli.util.StatusDisplayOptions import app.pachli.viewdata.StatusViewData diff --git a/app/src/main/java/app/pachli/components/viewthread/ViewThreadViewModel.kt b/app/src/main/java/app/pachli/components/viewthread/ViewThreadViewModel.kt index fb8fbd718..7b60a924d 100644 --- a/app/src/main/java/app/pachli/components/viewthread/ViewThreadViewModel.kt +++ b/app/src/main/java/app/pachli/components/viewthread/ViewThreadViewModel.kt @@ -32,18 +32,18 @@ import app.pachli.components.timeline.CachedTimelineRepository import app.pachli.components.timeline.FilterKind import app.pachli.components.timeline.FiltersRepository import app.pachli.components.timeline.util.ifExpected -import app.pachli.db.AccountEntity -import app.pachli.db.AccountManager -import app.pachli.db.TimelineDao -import app.pachli.db.TranslatedStatusEntity -import app.pachli.entity.Filter -import app.pachli.entity.Status +import app.pachli.core.accounts.AccountManager +import app.pachli.core.database.dao.TimelineDao +import app.pachli.core.database.model.AccountEntity +import app.pachli.core.database.model.TranslatedStatusEntity +import app.pachli.core.database.model.TranslationState +import app.pachli.core.network.model.Filter +import app.pachli.core.network.model.Status +import app.pachli.core.network.retrofit.MastodonApi import app.pachli.network.FilterModel -import app.pachli.network.MastodonApi import app.pachli.usecase.TimelineCases import app.pachli.util.StatusDisplayOptionsRepository import app.pachli.viewdata.StatusViewData -import app.pachli.viewdata.TranslationState import at.connyduck.calladapter.networkresult.fold import at.connyduck.calladapter.networkresult.getOrElse import at.connyduck.calladapter.networkresult.getOrThrow diff --git a/app/src/main/java/app/pachli/components/viewthread/edits/ViewEditsAdapter.kt b/app/src/main/java/app/pachli/components/viewthread/edits/ViewEditsAdapter.kt index 3838ea132..e7f497f69 100644 --- a/app/src/main/java/app/pachli/components/viewthread/edits/ViewEditsAdapter.kt +++ b/app/src/main/java/app/pachli/components/viewthread/edits/ViewEditsAdapter.kt @@ -20,17 +20,16 @@ import androidx.recyclerview.widget.RecyclerView import app.pachli.R import app.pachli.adapter.PollAdapter import app.pachli.adapter.PollAdapter.DisplayMode +import app.pachli.core.common.util.AbsoluteTimeFormatter +import app.pachli.core.network.model.StatusEdit +import app.pachli.core.network.parseAsMastodonHtml import app.pachli.databinding.ItemStatusEditBinding -import app.pachli.entity.Attachment.Focus -import app.pachli.entity.StatusEdit import app.pachli.interfaces.LinkListener -import app.pachli.util.AbsoluteTimeFormatter import app.pachli.util.BindingHolder import app.pachli.util.aspectRatios import app.pachli.util.decodeBlurHash import app.pachli.util.emojify import app.pachli.util.hide -import app.pachli.util.parseAsMastodonHtml import app.pachli.util.setClickableText import app.pachli.util.show import app.pachli.util.visible @@ -122,7 +121,8 @@ class ViewEditsAdapter( setClickableText(binding.statusEditContent, emojifiedText, emptyList(), emptyList(), listener) - if (edit.poll == null) { + val poll = edit.poll + if (poll == null) { binding.statusEditPollOptions.hide() binding.statusEditPollDescription.hide() } else { @@ -133,12 +133,12 @@ class ViewEditsAdapter( // binding.statusEditPollDescription.show() val pollAdapter = PollAdapter( - options = edit.poll.options.map { PollOptionViewData.from(it, false) }, + options = poll.options.map { PollOptionViewData.from(it, false) }, votesCount = 0, votersCount = null, edit.emojis, animateEmojis = animateEmojis, - displayMode = if (edit.poll.multiple) DisplayMode.MULTIPLE_CHOICE else DisplayMode.SINGLE_CHOICE, + displayMode = if (poll.multiple) DisplayMode.MULTIPLE_CHOICE else DisplayMode.SINGLE_CHOICE, enabled = false, resultClickListener = null, pollOptionClickListener = null, @@ -183,7 +183,7 @@ class ViewEditsAdapter( .centerInside() .into(imageView) } else { - val focus: Focus? = attachment.meta?.focus + val focus = attachment.meta?.focus if (focus != null) { imageView.setFocalPoint(focus) diff --git a/app/src/main/java/app/pachli/components/viewthread/edits/ViewEditsFragment.kt b/app/src/main/java/app/pachli/components/viewthread/edits/ViewEditsFragment.kt index ea321be83..01baf3b24 100644 --- a/app/src/main/java/app/pachli/components/viewthread/edits/ViewEditsFragment.kt +++ b/app/src/main/java/app/pachli/components/viewthread/edits/ViewEditsFragment.kt @@ -33,15 +33,15 @@ import app.pachli.BottomSheetActivity import app.pachli.R import app.pachli.StatusListActivity import app.pachli.components.account.AccountActivity +import app.pachli.core.common.string.unicodeWrap +import app.pachli.core.preferences.PrefKeys +import app.pachli.core.preferences.SharedPreferencesRepository import app.pachli.databinding.FragmentViewEditsBinding import app.pachli.interfaces.LinkListener -import app.pachli.settings.PrefKeys -import app.pachli.util.SharedPreferencesRepository import app.pachli.util.emojify import app.pachli.util.hide import app.pachli.util.loadAvatar import app.pachli.util.show -import app.pachli.util.unicodeWrap import app.pachli.util.viewBinding import com.google.android.material.color.MaterialColors import com.google.android.material.divider.MaterialDividerItemDecoration diff --git a/app/src/main/java/app/pachli/components/viewthread/edits/ViewEditsViewModel.kt b/app/src/main/java/app/pachli/components/viewthread/edits/ViewEditsViewModel.kt index 67c08f68b..788143e4c 100644 --- a/app/src/main/java/app/pachli/components/viewthread/edits/ViewEditsViewModel.kt +++ b/app/src/main/java/app/pachli/components/viewthread/edits/ViewEditsViewModel.kt @@ -21,8 +21,8 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import app.pachli.components.viewthread.edits.PachliTagHandler.Companion.DELETED_TEXT_EL import app.pachli.components.viewthread.edits.PachliTagHandler.Companion.INSERTED_TEXT_EL -import app.pachli.entity.StatusEdit -import app.pachli.network.MastodonApi +import app.pachli.core.network.model.StatusEdit +import app.pachli.core.network.retrofit.MastodonApi import at.connyduck.calladapter.networkresult.getOrElse import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers diff --git a/app/src/main/java/app/pachli/db/DraftsAlert.kt b/app/src/main/java/app/pachli/db/DraftsAlert.kt index a1fa0c0ee..960653760 100644 --- a/app/src/main/java/app/pachli/db/DraftsAlert.kt +++ b/app/src/main/java/app/pachli/db/DraftsAlert.kt @@ -24,6 +24,8 @@ import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.lifecycleScope import app.pachli.R import app.pachli.components.drafts.DraftsActivity +import app.pachli.core.accounts.AccountManager +import app.pachli.core.database.dao.DraftDao import kotlinx.coroutines.launch import timber.log.Timber import javax.inject.Inject diff --git a/app/src/main/java/app/pachli/entity/Report.kt b/app/src/main/java/app/pachli/entity/Report.kt deleted file mode 100644 index ad195a105..000000000 --- a/app/src/main/java/app/pachli/entity/Report.kt +++ /dev/null @@ -1,12 +0,0 @@ -package app.pachli.entity - -import com.google.gson.annotations.SerializedName -import java.util.Date - -data class Report( - val id: String, - val category: String, - val status_ids: List?, - @SerializedName("created_at") val createdAt: Date, - @SerializedName("target_account") val targetAccount: TimelineAccount, -) diff --git a/app/src/main/java/app/pachli/fragment/SFragment.kt b/app/src/main/java/app/pachli/fragment/SFragment.kt index b405c2e3e..499faf860 100644 --- a/app/src/main/java/app/pachli/fragment/SFragment.kt +++ b/app/src/main/java/app/pachli/fragment/SFragment.kt @@ -48,21 +48,21 @@ import app.pachli.components.compose.ComposeActivity import app.pachli.components.compose.ComposeActivity.Companion.startIntent import app.pachli.components.compose.ComposeActivity.ComposeOptions import app.pachli.components.report.ReportActivity.Companion.getIntent -import app.pachli.db.AccountEntity -import app.pachli.db.AccountManager -import app.pachli.entity.Attachment -import app.pachli.entity.Status +import app.pachli.core.accounts.AccountManager +import app.pachli.core.database.model.AccountEntity +import app.pachli.core.database.model.TranslationState +import app.pachli.core.network.ServerOperation +import app.pachli.core.network.model.Attachment +import app.pachli.core.network.model.Status +import app.pachli.core.network.parseAsMastodonHtml +import app.pachli.core.network.retrofit.MastodonApi import app.pachli.interfaces.AccountSelectionListener -import app.pachli.network.MastodonApi import app.pachli.network.ServerCapabilitiesRepository -import app.pachli.network.ServerOperation import app.pachli.usecase.TimelineCases import app.pachli.util.openLink -import app.pachli.util.parseAsMastodonHtml import app.pachli.view.showMuteAccountDialog import app.pachli.viewdata.AttachmentViewData import app.pachli.viewdata.StatusViewData -import app.pachli.viewdata.TranslationState import at.connyduck.calladapter.networkresult.fold import at.connyduck.calladapter.networkresult.onFailure import com.google.android.material.snackbar.Snackbar diff --git a/app/src/main/java/app/pachli/fragment/ViewMediaFragment.kt b/app/src/main/java/app/pachli/fragment/ViewMediaFragment.kt index 5c7e46db2..7a228a06c 100644 --- a/app/src/main/java/app/pachli/fragment/ViewMediaFragment.kt +++ b/app/src/main/java/app/pachli/fragment/ViewMediaFragment.kt @@ -23,7 +23,7 @@ import androidx.annotation.OptIn import androidx.fragment.app.Fragment import androidx.media3.common.util.UnstableApi import app.pachli.ViewMediaActivity -import app.pachli.entity.Attachment +import app.pachli.core.network.model.Attachment abstract class ViewMediaFragment : Fragment() { private var toolbarVisibilityDisposable: Function0? = null diff --git a/app/src/main/java/app/pachli/fragment/ViewVideoFragment.kt b/app/src/main/java/app/pachli/fragment/ViewVideoFragment.kt index 6ba6c3402..5b43a7d36 100644 --- a/app/src/main/java/app/pachli/fragment/ViewVideoFragment.kt +++ b/app/src/main/java/app/pachli/fragment/ViewVideoFragment.kt @@ -49,8 +49,8 @@ import androidx.media3.ui.AspectRatioFrameLayout import app.pachli.BuildConfig import app.pachli.R import app.pachli.ViewMediaActivity +import app.pachli.core.network.model.Attachment import app.pachli.databinding.FragmentViewVideoBinding -import app.pachli.entity.Attachment import app.pachli.util.hide import app.pachli.util.viewBinding import app.pachli.util.visible diff --git a/app/src/main/java/app/pachli/interfaces/AccountSelectionListener.kt b/app/src/main/java/app/pachli/interfaces/AccountSelectionListener.kt index 384160bb4..1e7c6b97d 100644 --- a/app/src/main/java/app/pachli/interfaces/AccountSelectionListener.kt +++ b/app/src/main/java/app/pachli/interfaces/AccountSelectionListener.kt @@ -16,7 +16,7 @@ package app.pachli.interfaces -import app.pachli.db.AccountEntity +import app.pachli.core.database.model.AccountEntity interface AccountSelectionListener { fun onAccountSelected(account: AccountEntity) diff --git a/app/src/main/java/app/pachli/network/FilterModel.kt b/app/src/main/java/app/pachli/network/FilterModel.kt index e459c979f..3d563a216 100644 --- a/app/src/main/java/app/pachli/network/FilterModel.kt +++ b/app/src/main/java/app/pachli/network/FilterModel.kt @@ -1,9 +1,9 @@ package app.pachli.network -import app.pachli.entity.Filter -import app.pachli.entity.FilterV1 -import app.pachli.entity.Status -import app.pachli.util.parseAsMastodonHtml +import app.pachli.core.network.model.Filter +import app.pachli.core.network.model.FilterV1 +import app.pachli.core.network.model.Status +import app.pachli.core.network.parseAsMastodonHtml import java.util.Date import java.util.regex.Pattern diff --git a/app/src/main/java/app/pachli/network/MediaUploadApi.kt b/app/src/main/java/app/pachli/network/MediaUploadApi.kt deleted file mode 100644 index 1b5d409e6..000000000 --- a/app/src/main/java/app/pachli/network/MediaUploadApi.kt +++ /dev/null @@ -1,21 +0,0 @@ -package app.pachli.network - -import app.pachli.entity.MediaUploadResult -import okhttp3.MultipartBody -import retrofit2.Response -import retrofit2.http.Multipart -import retrofit2.http.POST -import retrofit2.http.Part - -/** endpoints defined in this interface will be called with a higher timeout than usual - * which is necessary for media uploads to succeed on some servers - */ -interface MediaUploadApi { - @Multipart - @POST("api/v2/media") - suspend fun uploadMedia( - @Part file: MultipartBody.Part, - @Part description: MultipartBody.Part? = null, - @Part focus: MultipartBody.Part? = null, - ): Response -} diff --git a/app/src/main/java/app/pachli/network/ServerCapabilitiesRepository.kt b/app/src/main/java/app/pachli/network/ServerCapabilitiesRepository.kt index 02c61c03a..61c898e3f 100644 --- a/app/src/main/java/app/pachli/network/ServerCapabilitiesRepository.kt +++ b/app/src/main/java/app/pachli/network/ServerCapabilitiesRepository.kt @@ -17,8 +17,10 @@ package app.pachli.network -import app.pachli.db.AccountManager -import app.pachli.di.ApplicationScope +import app.pachli.core.accounts.AccountManager +import app.pachli.core.common.di.ApplicationScope +import app.pachli.core.network.ServerCapabilities +import app.pachli.core.network.retrofit.MastodonApi import at.connyduck.calladapter.networkresult.fold import com.github.michaelbull.result.getOr import kotlinx.coroutines.CoroutineScope diff --git a/app/src/main/java/app/pachli/pager/ImagePagerAdapter.kt b/app/src/main/java/app/pachli/pager/ImagePagerAdapter.kt index 574f4574c..8cdb8baa9 100644 --- a/app/src/main/java/app/pachli/pager/ImagePagerAdapter.kt +++ b/app/src/main/java/app/pachli/pager/ImagePagerAdapter.kt @@ -3,7 +3,7 @@ package app.pachli.pager import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentActivity import app.pachli.ViewMediaAdapter -import app.pachli.entity.Attachment +import app.pachli.core.network.model.Attachment import app.pachli.fragment.ViewMediaFragment import java.lang.ref.WeakReference diff --git a/app/src/main/java/app/pachli/pager/MainPagerAdapter.kt b/app/src/main/java/app/pachli/pager/MainPagerAdapter.kt index 6af7d3662..b6809de1d 100644 --- a/app/src/main/java/app/pachli/pager/MainPagerAdapter.kt +++ b/app/src/main/java/app/pachli/pager/MainPagerAdapter.kt @@ -18,10 +18,10 @@ package app.pachli.pager import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentActivity -import app.pachli.TabData +import app.pachli.TabViewData import app.pachli.util.CustomFragmentStateAdapter -class MainPagerAdapter(var tabs: List, activity: FragmentActivity) : CustomFragmentStateAdapter(activity) { +class MainPagerAdapter(var tabs: List, activity: FragmentActivity) : CustomFragmentStateAdapter(activity) { override fun createFragment(position: Int): Fragment { val tab = tabs[position] diff --git a/app/src/main/java/app/pachli/receiver/NotificationBlockStateBroadcastReceiver.kt b/app/src/main/java/app/pachli/receiver/NotificationBlockStateBroadcastReceiver.kt index 0eb44ae41..e8f6a372b 100644 --- a/app/src/main/java/app/pachli/receiver/NotificationBlockStateBroadcastReceiver.kt +++ b/app/src/main/java/app/pachli/receiver/NotificationBlockStateBroadcastReceiver.kt @@ -24,8 +24,8 @@ import android.os.Build import app.pachli.components.notifications.canEnablePushNotifications import app.pachli.components.notifications.isUnifiedPushNotificationEnabledForAccount import app.pachli.components.notifications.updateUnifiedPushSubscription -import app.pachli.db.AccountManager -import app.pachli.network.MastodonApi +import app.pachli.core.accounts.AccountManager +import app.pachli.core.network.retrofit.MastodonApi import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.GlobalScope diff --git a/app/src/main/java/app/pachli/receiver/SendStatusBroadcastReceiver.kt b/app/src/main/java/app/pachli/receiver/SendStatusBroadcastReceiver.kt index 96f7ad968..e0c1c5f27 100644 --- a/app/src/main/java/app/pachli/receiver/SendStatusBroadcastReceiver.kt +++ b/app/src/main/java/app/pachli/receiver/SendStatusBroadcastReceiver.kt @@ -37,11 +37,11 @@ import app.pachli.components.notifications.KEY_SENDER_ACCOUNT_IDENTIFIER import app.pachli.components.notifications.KEY_SPOILER import app.pachli.components.notifications.KEY_VISIBILITY import app.pachli.components.notifications.REPLY_ACTION -import app.pachli.db.AccountManager -import app.pachli.entity.Status +import app.pachli.core.accounts.AccountManager +import app.pachli.core.common.string.randomAlphanumericString +import app.pachli.core.network.model.Status import app.pachli.service.SendStatusService import app.pachli.service.StatusToSend -import app.pachli.util.randomAlphanumericString import dagger.hilt.android.AndroidEntryPoint import timber.log.Timber import javax.inject.Inject diff --git a/app/src/main/java/app/pachli/receiver/UnifiedPushBroadcastReceiver.kt b/app/src/main/java/app/pachli/receiver/UnifiedPushBroadcastReceiver.kt index c3c1ebf72..e0bada521 100644 --- a/app/src/main/java/app/pachli/receiver/UnifiedPushBroadcastReceiver.kt +++ b/app/src/main/java/app/pachli/receiver/UnifiedPushBroadcastReceiver.kt @@ -21,8 +21,8 @@ import androidx.work.OneTimeWorkRequest import androidx.work.WorkManager import app.pachli.components.notifications.registerUnifiedPushEndpoint import app.pachli.components.notifications.unregisterUnifiedPushEndpoint -import app.pachli.db.AccountManager -import app.pachli.network.MastodonApi +import app.pachli.core.accounts.AccountManager +import app.pachli.core.network.retrofit.MastodonApi import app.pachli.worker.NotificationWorker import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.DelicateCoroutinesApi diff --git a/app/src/main/java/app/pachli/service/SendStatusService.kt b/app/src/main/java/app/pachli/service/SendStatusService.kt index 01ec7cac4..300243d3e 100644 --- a/app/src/main/java/app/pachli/service/SendStatusService.kt +++ b/app/src/main/java/app/pachli/service/SendStatusService.kt @@ -27,13 +27,13 @@ import app.pachli.components.compose.MediaUploader import app.pachli.components.compose.UploadEvent import app.pachli.components.drafts.DraftHelper import app.pachli.components.notifications.pendingIntentFlags -import app.pachli.db.AccountManager -import app.pachli.entity.Attachment -import app.pachli.entity.MediaAttribute -import app.pachli.entity.NewPoll -import app.pachli.entity.NewStatus -import app.pachli.entity.Status -import app.pachli.network.MastodonApi +import app.pachli.core.accounts.AccountManager +import app.pachli.core.network.model.Attachment +import app.pachli.core.network.model.MediaAttribute +import app.pachli.core.network.model.NewPoll +import app.pachli.core.network.model.NewStatus +import app.pachli.core.network.model.Status +import app.pachli.core.network.retrofit.MastodonApi import app.pachli.util.unsafeLazy import at.connyduck.calladapter.networkresult.fold import dagger.hilt.android.AndroidEntryPoint diff --git a/app/src/main/java/app/pachli/settings/AccountPreferenceDataStore.kt b/app/src/main/java/app/pachli/settings/AccountPreferenceDataStore.kt index c5fb5aa4f..714f617f5 100644 --- a/app/src/main/java/app/pachli/settings/AccountPreferenceDataStore.kt +++ b/app/src/main/java/app/pachli/settings/AccountPreferenceDataStore.kt @@ -1,9 +1,10 @@ package app.pachli.settings import androidx.preference.PreferenceDataStore -import app.pachli.db.AccountEntity -import app.pachli.db.AccountManager -import app.pachli.di.ApplicationScope +import app.pachli.core.accounts.AccountManager +import app.pachli.core.common.di.ApplicationScope +import app.pachli.core.database.model.AccountEntity +import app.pachli.core.preferences.PrefKeys import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.launch diff --git a/app/src/main/java/app/pachli/updatecheck/UpdateCheck.kt b/app/src/main/java/app/pachli/updatecheck/UpdateCheck.kt index f790d42f5..97877a114 100644 --- a/app/src/main/java/app/pachli/updatecheck/UpdateCheck.kt +++ b/app/src/main/java/app/pachli/updatecheck/UpdateCheck.kt @@ -20,8 +20,8 @@ package app.pachli.updatecheck import android.content.Intent import androidx.core.content.edit import app.pachli.BuildConfig -import app.pachli.settings.PrefKeys -import app.pachli.util.SharedPreferencesRepository +import app.pachli.core.preferences.PrefKeys +import app.pachli.core.preferences.SharedPreferencesRepository import javax.inject.Singleton import kotlin.time.Duration.Companion.hours diff --git a/app/src/main/java/app/pachli/usecase/DeveloperToolsUseCase.kt b/app/src/main/java/app/pachli/usecase/DeveloperToolsUseCase.kt index 4903968e5..64c973fac 100644 --- a/app/src/main/java/app/pachli/usecase/DeveloperToolsUseCase.kt +++ b/app/src/main/java/app/pachli/usecase/DeveloperToolsUseCase.kt @@ -18,10 +18,10 @@ package app.pachli.usecase import androidx.core.content.edit -import app.pachli.db.TimelineDao -import app.pachli.di.TransactionProvider -import app.pachli.settings.PrefKeys -import app.pachli.util.SharedPreferencesRepository +import app.pachli.core.database.dao.TimelineDao +import app.pachli.core.database.di.TransactionProvider +import app.pachli.core.preferences.PrefKeys +import app.pachli.core.preferences.SharedPreferencesRepository import javax.inject.Inject /** diff --git a/app/src/main/java/app/pachli/usecase/LogoutUsecase.kt b/app/src/main/java/app/pachli/usecase/LogoutUsecase.kt index 9e2d7d43b..cdcb40cfc 100644 --- a/app/src/main/java/app/pachli/usecase/LogoutUsecase.kt +++ b/app/src/main/java/app/pachli/usecase/LogoutUsecase.kt @@ -6,11 +6,11 @@ import app.pachli.components.notifications.deleteNotificationChannelsForAccount import app.pachli.components.notifications.disablePullNotifications import app.pachli.components.notifications.disableUnifiedPushNotificationsForAccount import app.pachli.components.notifications.notificationsAreEnabled -import app.pachli.db.AccountManager -import app.pachli.db.ConversationsDao -import app.pachli.db.RemoteKeyDao -import app.pachli.db.TimelineDao -import app.pachli.network.MastodonApi +import app.pachli.core.accounts.AccountManager +import app.pachli.core.database.dao.ConversationsDao +import app.pachli.core.database.dao.RemoteKeyDao +import app.pachli.core.database.dao.TimelineDao +import app.pachli.core.network.retrofit.MastodonApi import app.pachli.util.removeShortcut import dagger.hilt.android.qualifiers.ApplicationContext import javax.inject.Inject diff --git a/app/src/main/java/app/pachli/usecase/TimelineCases.kt b/app/src/main/java/app/pachli/usecase/TimelineCases.kt index aa82ad6ec..65c5c433a 100644 --- a/app/src/main/java/app/pachli/usecase/TimelineCases.kt +++ b/app/src/main/java/app/pachli/usecase/TimelineCases.kt @@ -27,12 +27,12 @@ import app.pachli.appstore.PollVoteEvent import app.pachli.appstore.ReblogEvent import app.pachli.appstore.StatusDeletedEvent import app.pachli.components.timeline.CachedTimelineRepository -import app.pachli.entity.DeletedStatus -import app.pachli.entity.Poll -import app.pachli.entity.Relationship -import app.pachli.entity.Status -import app.pachli.entity.Translation -import app.pachli.network.MastodonApi +import app.pachli.core.network.model.DeletedStatus +import app.pachli.core.network.model.Poll +import app.pachli.core.network.model.Relationship +import app.pachli.core.network.model.Status +import app.pachli.core.network.model.Translation +import app.pachli.core.network.retrofit.MastodonApi import app.pachli.util.getServerErrorMessage import app.pachli.viewdata.StatusViewData import at.connyduck.calladapter.networkresult.NetworkResult diff --git a/app/src/main/java/app/pachli/util/AttachmentExtensions.kt b/app/src/main/java/app/pachli/util/AttachmentExtensions.kt new file mode 100644 index 000000000..201342043 --- /dev/null +++ b/app/src/main/java/app/pachli/util/AttachmentExtensions.kt @@ -0,0 +1,31 @@ +/* + * Copyright 2023 Pachli Association + * + * This file is a part of Pachli. + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Pachli; if not, + * see . + */ + +package app.pachli.util + +import androidx.annotation.DrawableRes +import app.pachli.R +import app.pachli.core.network.model.Attachment + +/** @return a drawable resource for an icon to indicate the attachment type */ +@DrawableRes +fun Attachment.iconResource() = when (this.type) { + Attachment.Type.IMAGE -> R.drawable.ic_photo_24dp + Attachment.Type.GIFV, Attachment.Type.VIDEO -> R.drawable.ic_videocam_24dp + Attachment.Type.AUDIO -> R.drawable.ic_music_box_24dp + Attachment.Type.UNKNOWN -> R.drawable.ic_attach_file_24dp +} diff --git a/app/src/main/java/app/pachli/util/AttachmentHelper.kt b/app/src/main/java/app/pachli/util/AttachmentHelper.kt index 86b4a4166..feed3375e 100644 --- a/app/src/main/java/app/pachli/util/AttachmentHelper.kt +++ b/app/src/main/java/app/pachli/util/AttachmentHelper.kt @@ -2,13 +2,13 @@ package app.pachli.util import android.content.Context import app.pachli.R -import app.pachli.entity.Attachment +import app.pachli.core.network.model.Attachment import kotlin.math.roundToInt fun Attachment.getFormattedDescription(context: Context): CharSequence { var duration = "" - if (meta?.duration != null && meta.duration > 0) { - duration = formatDuration(meta.duration.toDouble()) + " " + if (meta?.duration != null && meta!!.duration!! > 0) { + duration = meta!!.duration?.let { formatDuration(it.toDouble()) } + " " } return if (description.isNullOrEmpty()) { duration + context.getString(R.string.description_post_media_no_description_placeholder) diff --git a/app/src/main/java/app/pachli/util/CustomEmojiHelper.kt b/app/src/main/java/app/pachli/util/CustomEmojiHelper.kt index a9d6187fd..e4eb006c2 100644 --- a/app/src/main/java/app/pachli/util/CustomEmojiHelper.kt +++ b/app/src/main/java/app/pachli/util/CustomEmojiHelper.kt @@ -23,7 +23,7 @@ import android.graphics.drawable.Drawable import android.text.SpannableStringBuilder import android.text.style.ReplacementSpan import android.view.View -import app.pachli.entity.Emoji +import app.pachli.core.network.model.Emoji import com.bumptech.glide.Glide import com.bumptech.glide.request.target.CustomTarget import com.bumptech.glide.request.target.Target diff --git a/app/src/main/java/app/pachli/util/FocalPointUtil.kt b/app/src/main/java/app/pachli/util/FocalPointUtil.kt index 44f416983..55bbd1f28 100644 --- a/app/src/main/java/app/pachli/util/FocalPointUtil.kt +++ b/app/src/main/java/app/pachli/util/FocalPointUtil.kt @@ -17,7 +17,7 @@ package app.pachli.util import android.graphics.Matrix -import app.pachli.entity.Attachment.Focus +import app.pachli.core.network.model.Attachment.Focus /** * Calculates the image matrix needed to maintain the correct cropping for image views based on diff --git a/app/src/main/java/app/pachli/util/LinkHelper.kt b/app/src/main/java/app/pachli/util/LinkHelper.kt index 9ff48c3a8..d87e4ab69 100644 --- a/app/src/main/java/app/pachli/util/LinkHelper.kt +++ b/app/src/main/java/app/pachli/util/LinkHelper.kt @@ -37,10 +37,10 @@ import androidx.browser.customtabs.CustomTabsIntent import androidx.core.net.toUri import androidx.preference.PreferenceManager import app.pachli.R -import app.pachli.entity.HashTag -import app.pachli.entity.Status.Mention +import app.pachli.core.network.model.HashTag +import app.pachli.core.network.model.Status.Mention +import app.pachli.core.preferences.PrefKeys import app.pachli.interfaces.LinkListener -import app.pachli.settings.PrefKeys import com.google.android.material.color.MaterialColors import com.mikepenz.iconics.IconicsColor import com.mikepenz.iconics.IconicsDrawable diff --git a/app/src/main/java/app/pachli/util/ListStatusAccessibilityDelegate.kt b/app/src/main/java/app/pachli/util/ListStatusAccessibilityDelegate.kt index 3c41cb60b..e89a8c099 100644 --- a/app/src/main/java/app/pachli/util/ListStatusAccessibilityDelegate.kt +++ b/app/src/main/java/app/pachli/util/ListStatusAccessibilityDelegate.kt @@ -16,7 +16,7 @@ import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate import app.pachli.R import app.pachli.adapter.StatusBaseViewHolder -import app.pachli.entity.Status.Companion.MAX_MEDIA_ATTACHMENTS +import app.pachli.core.network.model.Status.Companion.MAX_MEDIA_ATTACHMENTS import app.pachli.interfaces.StatusActionListener import app.pachli.viewdata.StatusViewData import kotlin.math.min diff --git a/app/src/main/java/app/pachli/util/LocaleManager.kt b/app/src/main/java/app/pachli/util/LocaleManager.kt index bd3288091..0ea74093c 100644 --- a/app/src/main/java/app/pachli/util/LocaleManager.kt +++ b/app/src/main/java/app/pachli/util/LocaleManager.kt @@ -22,7 +22,9 @@ import androidx.appcompat.app.AppCompatDelegate import androidx.core.os.LocaleListCompat import androidx.preference.PreferenceDataStore import app.pachli.R -import app.pachli.settings.PrefKeys +import app.pachli.core.preferences.PrefKeys +import app.pachli.core.preferences.SharedPreferencesRepository +import app.pachli.core.preferences.getNonNullString import dagger.hilt.android.qualifiers.ApplicationContext import javax.inject.Inject import javax.inject.Singleton diff --git a/app/src/main/java/app/pachli/util/LocaleUtils.kt b/app/src/main/java/app/pachli/util/LocaleUtils.kt index e251e657b..d1a6bb421 100644 --- a/app/src/main/java/app/pachli/util/LocaleUtils.kt +++ b/app/src/main/java/app/pachli/util/LocaleUtils.kt @@ -18,7 +18,7 @@ package app.pachli.util import androidx.appcompat.app.AppCompatDelegate import androidx.core.os.LocaleListCompat -import app.pachli.db.AccountEntity +import app.pachli.core.database.model.AccountEntity import timber.log.Timber import java.util.Locale diff --git a/app/src/main/java/app/pachli/util/NotificationTypeConverter.kt b/app/src/main/java/app/pachli/util/NotificationTypeConverter.kt index 9a5c94dfe..b49f6ecf8 100644 --- a/app/src/main/java/app/pachli/util/NotificationTypeConverter.kt +++ b/app/src/main/java/app/pachli/util/NotificationTypeConverter.kt @@ -16,7 +16,7 @@ package app.pachli.util -import app.pachli.entity.Notification +import app.pachli.core.network.model.Notification import org.json.JSONArray /** diff --git a/app/src/main/java/app/pachli/util/ShareShortcutHelper.kt b/app/src/main/java/app/pachli/util/ShareShortcutHelper.kt index 8b6ac1d16..403d991ca 100644 --- a/app/src/main/java/app/pachli/util/ShareShortcutHelper.kt +++ b/app/src/main/java/app/pachli/util/ShareShortcutHelper.kt @@ -27,7 +27,7 @@ import androidx.core.content.pm.ShortcutManagerCompat import androidx.core.graphics.drawable.IconCompat import app.pachli.MainActivity import app.pachli.R -import app.pachli.db.AccountEntity +import app.pachli.core.database.model.AccountEntity import com.bumptech.glide.Glide import io.reactivex.rxjava3.core.Single import io.reactivex.rxjava3.schedulers.Schedulers diff --git a/app/src/main/java/app/pachli/util/StatusDisplayOptionsRepository.kt b/app/src/main/java/app/pachli/util/StatusDisplayOptionsRepository.kt index c31cda604..44b6399ea 100644 --- a/app/src/main/java/app/pachli/util/StatusDisplayOptionsRepository.kt +++ b/app/src/main/java/app/pachli/util/StatusDisplayOptionsRepository.kt @@ -19,13 +19,14 @@ package app.pachli.util import androidx.annotation.VisibleForTesting import androidx.annotation.VisibleForTesting.Companion.PRIVATE -import app.pachli.db.AccountEntity -import app.pachli.db.AccountManager -import app.pachli.di.ApplicationScope +import app.pachli.core.accounts.AccountManager +import app.pachli.core.common.di.ApplicationScope +import app.pachli.core.database.model.AccountEntity +import app.pachli.core.network.ServerOperation +import app.pachli.core.preferences.PrefKeys +import app.pachli.core.preferences.SharedPreferencesRepository import app.pachli.network.ServerCapabilitiesRepository -import app.pachli.network.ServerOperation import app.pachli.settings.AccountPreferenceDataStore -import app.pachli.settings.PrefKeys import io.github.z4kn4fein.semver.constraints.toConstraint import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.MutableStateFlow diff --git a/app/src/main/java/app/pachli/util/StatusExtensions.kt b/app/src/main/java/app/pachli/util/StatusExtensions.kt new file mode 100644 index 000000000..0618a2abc --- /dev/null +++ b/app/src/main/java/app/pachli/util/StatusExtensions.kt @@ -0,0 +1,68 @@ +/* + * Copyright 2023 Pachli Association + * + * This file is a part of Pachli. + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Pachli; if not, + * see . + */ + +package app.pachli.util + +import android.content.Context +import android.graphics.drawable.Drawable +import android.widget.TextView +import androidx.appcompat.content.res.AppCompatResources +import app.pachli.R +import app.pachli.core.network.model.Status + +// TODO: Not part of the [Status] implementation because that module doesn't +// store resources (yet). + +/** + * @return A description for this visibility, or "" if it's null or [Status.Visibility.UNKNOWN]. + */ +fun Status.Visibility?.description(context: Context): CharSequence { + this ?: return "" + + val resource: Int = when (this) { + Status.Visibility.PUBLIC -> R.string.description_visibility_public + Status.Visibility.UNLISTED -> R.string.description_visibility_unlisted + Status.Visibility.PRIVATE -> R.string.description_visibility_private + Status.Visibility.DIRECT -> R.string.description_visibility_direct + Status.Visibility.UNKNOWN -> return "" + } + return context.getString(resource) +} + +/** + * @return An icon for this visibility scaled and coloured to match the text on [textView]. + * Returns null if visibility is [Status.Visibility.UNKNOWN]. + */ +fun Status.Visibility?.icon(textView: TextView): Drawable? { + this ?: return null + + val resource: Int = when (this) { + Status.Visibility.PUBLIC -> R.drawable.ic_public_24dp + Status.Visibility.UNLISTED -> R.drawable.ic_lock_open_24dp + Status.Visibility.PRIVATE -> R.drawable.ic_lock_outline_24dp + Status.Visibility.DIRECT -> R.drawable.ic_email_24dp + Status.Visibility.UNKNOWN -> return null + } + val visibilityDrawable = AppCompatResources.getDrawable( + textView.context, + resource, + ) ?: return null + val size = textView.textSize.toInt() + visibilityDrawable.setBounds(0, 0, size, size) + visibilityDrawable.setTint(textView.currentTextColor) + return visibilityDrawable +} diff --git a/app/src/main/java/app/pachli/util/StatusViewHelper.kt b/app/src/main/java/app/pachli/util/StatusViewHelper.kt index 4c71674cd..1f8286d59 100644 --- a/app/src/main/java/app/pachli/util/StatusViewHelper.kt +++ b/app/src/main/java/app/pachli/util/StatusViewHelper.kt @@ -23,11 +23,11 @@ import android.text.TextUtils import android.view.View import android.widget.ImageView import android.widget.TextView -import androidx.annotation.DrawableRes import app.pachli.R -import app.pachli.entity.Attachment -import app.pachli.entity.Emoji -import app.pachli.entity.Status +import app.pachli.core.common.util.AbsoluteTimeFormatter +import app.pachli.core.network.model.Attachment +import app.pachli.core.network.model.Emoji +import app.pachli.core.network.model.Status import app.pachli.view.MediaPreviewImageView import app.pachli.viewdata.PollViewData import app.pachli.viewdata.buildDescription @@ -109,11 +109,9 @@ class StatusViewHelper(private val itemView: View) { .centerInside() .into(mediaPreviews[i]) } else { - val placeholder = if (attachment.blurhash != null) { - decodeBlurHash(context, attachment.blurhash) - } else { - mediaPreviewUnloaded - } + val placeholder = attachment.blurhash?.let { + decodeBlurHash(context, it) + } ?: mediaPreviewUnloaded val meta = attachment.meta val focus = meta?.focus if (showingContent) { @@ -138,7 +136,7 @@ class StatusViewHelper(private val itemView: View) { } else { mediaPreviews[i].removeFocalPoint() if (statusDisplayOptions.useBlurhash && attachment.blurhash != null) { - val blurhashBitmap = decodeBlurHash(context, attachment.blurhash) + val blurhashBitmap = decodeBlurHash(context, attachment.blurhash!!) mediaPreviews[i].setImageDrawable(blurhashBitmap) } else { mediaPreviews[i].setImageDrawable(mediaPreviewUnloaded) @@ -237,7 +235,7 @@ class StatusViewHelper(private val itemView: View) { mediaLabel.text = labelText // Set the icon next to the label. - val drawableId = getLabelIcon(attachments[0].type) + val drawableId = attachments[0].iconResource() mediaLabel.setCompoundDrawablesWithIntrinsicBounds(drawableId, 0, 0, 0) mediaLabel.setOnClickListener { listener.onViewMedia(null, 0) } @@ -252,16 +250,6 @@ class StatusViewHelper(private val itemView: View) { } } - @DrawableRes - private fun getLabelIcon(type: Attachment.Type): Int { - return when (type) { - Attachment.Type.IMAGE -> R.drawable.ic_photo_24dp - Attachment.Type.GIFV, Attachment.Type.VIDEO -> R.drawable.ic_videocam_24dp - Attachment.Type.AUDIO -> R.drawable.ic_music_box_24dp - else -> R.drawable.ic_attach_file_24dp - } - } - /** * Configures and shows poll views based on [poll]. */ diff --git a/app/src/main/java/app/pachli/view/MediaPreviewImageView.kt b/app/src/main/java/app/pachli/view/MediaPreviewImageView.kt index 081696df0..a01ccc032 100644 --- a/app/src/main/java/app/pachli/view/MediaPreviewImageView.kt +++ b/app/src/main/java/app/pachli/view/MediaPreviewImageView.kt @@ -20,7 +20,7 @@ import android.graphics.Matrix import android.graphics.drawable.Drawable import android.util.AttributeSet import androidx.appcompat.widget.AppCompatImageView -import app.pachli.entity.Attachment +import app.pachli.core.network.model.Attachment import app.pachli.util.FocalPointUtil import com.bumptech.glide.load.DataSource import com.bumptech.glide.load.engine.GlideException diff --git a/app/src/main/java/app/pachli/view/PollView.kt b/app/src/main/java/app/pachli/view/PollView.kt index 07a5abe55..e213bf1f4 100644 --- a/app/src/main/java/app/pachli/view/PollView.kt +++ b/app/src/main/java/app/pachli/view/PollView.kt @@ -27,9 +27,9 @@ import androidx.recyclerview.widget.DefaultItemAnimator import androidx.recyclerview.widget.LinearLayoutManager import app.pachli.R import app.pachli.adapter.PollAdapter +import app.pachli.core.common.util.AbsoluteTimeFormatter +import app.pachli.core.network.model.Emoji import app.pachli.databinding.StatusPollBinding -import app.pachli.entity.Emoji -import app.pachli.util.AbsoluteTimeFormatter import app.pachli.util.StatusDisplayOptions import app.pachli.util.formatPollDuration import app.pachli.util.hide diff --git a/app/src/main/java/app/pachli/view/PreviewCardView.kt b/app/src/main/java/app/pachli/view/PreviewCardView.kt index 7c5fe8cd7..9bdb3116a 100644 --- a/app/src/main/java/app/pachli/view/PreviewCardView.kt +++ b/app/src/main/java/app/pachli/view/PreviewCardView.kt @@ -24,8 +24,8 @@ import android.view.ViewGroup import android.widget.ImageView import android.widget.LinearLayout import app.pachli.R +import app.pachli.core.network.model.PreviewCard import app.pachli.databinding.PreviewCardBinding -import app.pachli.entity.PreviewCard import app.pachli.util.StatusDisplayOptions import app.pachli.util.decodeBlurHash import app.pachli.util.hide diff --git a/app/src/main/java/app/pachli/viewdata/AttachmentViewData.kt b/app/src/main/java/app/pachli/viewdata/AttachmentViewData.kt index a558ea722..504c074fd 100644 --- a/app/src/main/java/app/pachli/viewdata/AttachmentViewData.kt +++ b/app/src/main/java/app/pachli/viewdata/AttachmentViewData.kt @@ -17,8 +17,8 @@ package app.pachli.viewdata import android.os.Parcelable -import app.pachli.entity.Attachment -import app.pachli.entity.Status +import app.pachli.core.network.model.Attachment +import app.pachli.core.network.model.Status import kotlinx.parcelize.IgnoredOnParcel import kotlinx.parcelize.Parcelize diff --git a/app/src/main/java/app/pachli/viewdata/NotificationViewData.kt b/app/src/main/java/app/pachli/viewdata/NotificationViewData.kt index 983200ef5..a58e51bfa 100644 --- a/app/src/main/java/app/pachli/viewdata/NotificationViewData.kt +++ b/app/src/main/java/app/pachli/viewdata/NotificationViewData.kt @@ -17,10 +17,10 @@ package app.pachli.viewdata -import app.pachli.entity.Filter -import app.pachli.entity.Notification -import app.pachli.entity.Report -import app.pachli.entity.TimelineAccount +import app.pachli.core.network.model.Filter +import app.pachli.core.network.model.Notification +import app.pachli.core.network.model.Report +import app.pachli.core.network.model.TimelineAccount data class NotificationViewData( val type: Notification.Type, diff --git a/app/src/main/java/app/pachli/viewdata/PollViewData.kt b/app/src/main/java/app/pachli/viewdata/PollViewData.kt index 09e76bfe0..9e04f8ce5 100644 --- a/app/src/main/java/app/pachli/viewdata/PollViewData.kt +++ b/app/src/main/java/app/pachli/viewdata/PollViewData.kt @@ -21,9 +21,9 @@ import android.text.SpannableStringBuilder import android.text.Spanned import androidx.core.text.parseAsHtml import app.pachli.R -import app.pachli.entity.Poll -import app.pachli.entity.PollOption -import app.pachli.entity.TranslatedPoll +import app.pachli.core.network.model.Poll +import app.pachli.core.network.model.PollOption +import app.pachli.core.network.model.TranslatedPoll import java.util.Date import kotlin.math.roundToInt diff --git a/app/src/main/java/app/pachli/viewdata/StatusViewData.kt b/app/src/main/java/app/pachli/viewdata/StatusViewData.kt index b6bffc455..bbd5feab0 100644 --- a/app/src/main/java/app/pachli/viewdata/StatusViewData.kt +++ b/app/src/main/java/app/pachli/viewdata/StatusViewData.kt @@ -18,29 +18,19 @@ package app.pachli.viewdata import android.os.Build import android.text.Spanned import android.text.SpannedString -import app.pachli.components.conversation.ConversationAccountEntity -import app.pachli.components.conversation.ConversationStatusEntity -import app.pachli.db.TimelineStatusWithAccount -import app.pachli.db.TranslatedStatusEntity -import app.pachli.entity.Filter -import app.pachli.entity.Poll -import app.pachli.entity.Status -import app.pachli.util.parseAsMastodonHtml -import app.pachli.util.replaceCrashingCharacters +import app.pachli.core.database.model.ConversationAccountEntity +import app.pachli.core.database.model.ConversationStatusEntity +import app.pachli.core.database.model.TimelineStatusWithAccount +import app.pachli.core.database.model.TranslatedStatusEntity +import app.pachli.core.database.model.TranslationState +import app.pachli.core.network.model.Filter +import app.pachli.core.network.model.Poll +import app.pachli.core.network.model.Status +import app.pachli.core.network.parseAsMastodonHtml +import app.pachli.core.network.replaceCrashingCharacters import app.pachli.util.shouldTrimStatus import com.google.gson.Gson -enum class TranslationState { - /** Show the original, untranslated status */ - SHOW_ORIGINAL, - - /** Show the original, untranslated status, but translation is happening */ - TRANSLATING, - - /** Show the translated status */ - SHOW_TRANSLATION, -} - /** * Data required to display a status. */ diff --git a/app/src/main/java/app/pachli/viewdata/TrendingViewData.kt b/app/src/main/java/app/pachli/viewdata/TrendingViewData.kt index 90b0bc024..9b75acbab 100644 --- a/app/src/main/java/app/pachli/viewdata/TrendingViewData.kt +++ b/app/src/main/java/app/pachli/viewdata/TrendingViewData.kt @@ -16,7 +16,7 @@ package app.pachli.viewdata -import app.pachli.entity.TrendingTag +import app.pachli.core.network.model.TrendingTag import java.util.Date sealed interface TrendingViewData { diff --git a/app/src/main/java/app/pachli/viewmodel/AccountsInListViewModel.kt b/app/src/main/java/app/pachli/viewmodel/AccountsInListViewModel.kt index 23a96d7ac..9a0f46029 100644 --- a/app/src/main/java/app/pachli/viewmodel/AccountsInListViewModel.kt +++ b/app/src/main/java/app/pachli/viewmodel/AccountsInListViewModel.kt @@ -18,8 +18,8 @@ package app.pachli.viewmodel import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import app.pachli.entity.TimelineAccount -import app.pachli.network.MastodonApi +import app.pachli.core.network.model.TimelineAccount +import app.pachli.core.network.retrofit.MastodonApi import app.pachli.util.Either import app.pachli.util.Either.Left import app.pachli.util.Either.Right diff --git a/app/src/main/java/app/pachli/viewmodel/EditProfileViewModel.kt b/app/src/main/java/app/pachli/viewmodel/EditProfileViewModel.kt index ab5bffed8..0eba36735 100644 --- a/app/src/main/java/app/pachli/viewmodel/EditProfileViewModel.kt +++ b/app/src/main/java/app/pachli/viewmodel/EditProfileViewModel.kt @@ -26,15 +26,15 @@ import app.pachli.appstore.EventHub import app.pachli.appstore.ProfileEditedEvent import app.pachli.components.instanceinfo.InstanceInfo import app.pachli.components.instanceinfo.InstanceInfoRepository -import app.pachli.entity.Account -import app.pachli.entity.StringField -import app.pachli.network.MastodonApi +import app.pachli.core.common.string.randomAlphanumericString +import app.pachli.core.network.model.Account +import app.pachli.core.network.model.StringField +import app.pachli.core.network.retrofit.MastodonApi import app.pachli.util.Error import app.pachli.util.Loading import app.pachli.util.Resource import app.pachli.util.Success import app.pachli.util.getServerErrorMessage -import app.pachli.util.randomAlphanumericString import at.connyduck.calladapter.networkresult.fold import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.Flow diff --git a/app/src/main/java/app/pachli/viewmodel/ListsViewModel.kt b/app/src/main/java/app/pachli/viewmodel/ListsViewModel.kt index a75bd36ea..ade1253a8 100644 --- a/app/src/main/java/app/pachli/viewmodel/ListsViewModel.kt +++ b/app/src/main/java/app/pachli/viewmodel/ListsViewModel.kt @@ -18,8 +18,8 @@ package app.pachli.viewmodel import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import app.pachli.entity.MastoList -import app.pachli.network.MastodonApi +import app.pachli.core.network.model.MastoList +import app.pachli.core.network.retrofit.MastodonApi import app.pachli.util.replacedFirstWhich import app.pachli.util.withoutFirstWhich import at.connyduck.calladapter.networkresult.fold diff --git a/app/src/main/java/app/pachli/worker/PruneCacheWorker.kt b/app/src/main/java/app/pachli/worker/PruneCacheWorker.kt index d68abaa40..085bc8a01 100644 --- a/app/src/main/java/app/pachli/worker/PruneCacheWorker.kt +++ b/app/src/main/java/app/pachli/worker/PruneCacheWorker.kt @@ -26,8 +26,8 @@ import androidx.work.WorkerParameters import app.pachli.R import app.pachli.components.notifications.NOTIFICATION_ID_PRUNE_CACHE import app.pachli.components.notifications.createWorkerNotification -import app.pachli.db.AccountManager -import app.pachli.db.TimelineDao +import app.pachli.core.accounts.AccountManager +import app.pachli.core.database.dao.TimelineDao import timber.log.Timber import javax.inject.Inject diff --git a/app/src/test/java/app/pachli/BottomSheetActivityTest.kt b/app/src/test/java/app/pachli/BottomSheetActivityTest.kt index 9b7cf9ae2..844b1d656 100644 --- a/app/src/test/java/app/pachli/BottomSheetActivityTest.kt +++ b/app/src/test/java/app/pachli/BottomSheetActivityTest.kt @@ -18,11 +18,11 @@ package app.pachli import androidx.arch.core.executor.testing.InstantTaskExecutorRule -import app.pachli.components.timeline.MainCoroutineRule -import app.pachli.entity.SearchResult -import app.pachli.entity.Status -import app.pachli.entity.TimelineAccount -import app.pachli.network.MastodonApi +import app.pachli.core.network.model.SearchResult +import app.pachli.core.network.model.Status +import app.pachli.core.network.model.TimelineAccount +import app.pachli.core.network.retrofit.MastodonApi +import app.pachli.core.testing.rules.MainCoroutineRule import at.connyduck.calladapter.networkresult.NetworkResult import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.StandardTestDispatcher diff --git a/app/src/test/java/app/pachli/FilterV1Test.kt b/app/src/test/java/app/pachli/FilterV1Test.kt index 47317fcd3..3c3914ee5 100644 --- a/app/src/test/java/app/pachli/FilterV1Test.kt +++ b/app/src/test/java/app/pachli/FilterV1Test.kt @@ -19,12 +19,12 @@ package app.pachli import androidx.test.ext.junit.runners.AndroidJUnit4 import app.pachli.components.filters.EditFilterActivity -import app.pachli.entity.Attachment -import app.pachli.entity.Filter -import app.pachli.entity.FilterV1 -import app.pachli.entity.Poll -import app.pachli.entity.PollOption -import app.pachli.entity.Status +import app.pachli.core.network.model.Attachment +import app.pachli.core.network.model.Filter +import app.pachli.core.network.model.FilterV1 +import app.pachli.core.network.model.Poll +import app.pachli.core.network.model.PollOption +import app.pachli.core.network.model.Status import app.pachli.network.FilterModel import org.junit.Assert.assertEquals import org.junit.Before diff --git a/app/src/test/java/app/pachli/MainActivityTest.kt b/app/src/test/java/app/pachli/MainActivityTest.kt index 3e75a6e27..feb3a9d55 100644 --- a/app/src/test/java/app/pachli/MainActivityTest.kt +++ b/app/src/test/java/app/pachli/MainActivityTest.kt @@ -29,14 +29,16 @@ import app.pachli.components.accountlist.AccountListActivity import app.pachli.components.compose.HiltTestApplication_Application import app.pachli.components.notifications.createNotificationChannelsForAccount import app.pachli.components.notifications.makeNotification -import app.pachli.db.AccountEntity -import app.pachli.db.AccountManager +import app.pachli.core.accounts.AccountManager +import app.pachli.core.database.model.AccountEntity +import app.pachli.core.database.model.TabKind +import app.pachli.core.database.model.defaultTabs +import app.pachli.core.network.model.Account +import app.pachli.core.network.model.Notification +import app.pachli.core.network.model.TimelineAccount +import app.pachli.core.network.retrofit.MastodonApi +import app.pachli.core.testing.rules.lazyActivityScenarioRule import app.pachli.db.DraftsAlert -import app.pachli.entity.Account -import app.pachli.entity.Notification -import app.pachli.entity.TimelineAccount -import app.pachli.network.MastodonApi -import app.pachli.rules.lazyActivityScenarioRule import at.connyduck.calladapter.networkresult.NetworkResult import dagger.hilt.android.testing.BindValue import dagger.hilt.android.testing.CustomTestApplication @@ -151,7 +153,7 @@ class MainActivityTest { rule.launch(intent) rule.getScenario().onActivity { val currentTab = it.findViewById(R.id.viewPager).currentItem - val notificationTab = defaultTabs().indexOfFirst { it.id == NOTIFICATIONS } + val notificationTab = defaultTabs().indexOfFirst { it.kind == TabKind.NOTIFICATIONS } assertEquals(currentTab, notificationTab) } } diff --git a/app/src/test/java/app/pachli/StatusComparisonTest.kt b/app/src/test/java/app/pachli/StatusComparisonTest.kt index f1ac63270..3fb6b7680 100644 --- a/app/src/test/java/app/pachli/StatusComparisonTest.kt +++ b/app/src/test/java/app/pachli/StatusComparisonTest.kt @@ -1,9 +1,9 @@ package app.pachli import androidx.test.ext.junit.runners.AndroidJUnit4 -import app.pachli.entity.Status +import app.pachli.core.database.model.TranslationState +import app.pachli.core.network.model.Status import app.pachli.viewdata.StatusViewData -import app.pachli.viewdata.TranslationState import com.google.gson.Gson import org.junit.Assert.assertEquals import org.junit.Assert.assertNotEquals diff --git a/app/src/test/java/app/pachli/components/compose/ComposeActivityTest.kt b/app/src/test/java/app/pachli/components/compose/ComposeActivityTest.kt index a954f5719..a227f9f0b 100644 --- a/app/src/test/java/app/pachli/components/compose/ComposeActivityTest.kt +++ b/app/src/test/java/app/pachli/components/compose/ComposeActivityTest.kt @@ -23,13 +23,13 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import app.pachli.PachliApplication import app.pachli.R import app.pachli.components.instanceinfo.InstanceInfoRepository -import app.pachli.db.AccountManager -import app.pachli.entity.Account -import app.pachli.entity.InstanceConfiguration -import app.pachli.entity.InstanceV1 -import app.pachli.entity.StatusConfiguration -import app.pachli.network.MastodonApi -import app.pachli.rules.lazyActivityScenarioRule +import app.pachli.core.accounts.AccountManager +import app.pachli.core.network.model.Account +import app.pachli.core.network.model.InstanceConfiguration +import app.pachli.core.network.model.InstanceV1 +import app.pachli.core.network.model.StatusConfiguration +import app.pachli.core.network.retrofit.MastodonApi +import app.pachli.core.testing.rules.lazyActivityScenarioRule import at.connyduck.calladapter.networkresult.NetworkResult import dagger.hilt.android.testing.CustomTestApplication import dagger.hilt.android.testing.HiltAndroidRule diff --git a/app/src/test/java/app/pachli/components/instanceinfo/InstanceInfoRepositoryTest.kt b/app/src/test/java/app/pachli/components/instanceinfo/InstanceInfoRepositoryTest.kt index d78eb8c4f..7c3bdaed7 100644 --- a/app/src/test/java/app/pachli/components/instanceinfo/InstanceInfoRepositoryTest.kt +++ b/app/src/test/java/app/pachli/components/instanceinfo/InstanceInfoRepositoryTest.kt @@ -17,13 +17,13 @@ package app.pachli.components.instanceinfo -import app.pachli.db.AccountEntity -import app.pachli.db.AccountManager -import app.pachli.db.InstanceDao -import app.pachli.entity.InstanceConfiguration -import app.pachli.entity.InstanceV1 -import app.pachli.entity.StatusConfiguration -import app.pachli.network.MastodonApi +import app.pachli.core.accounts.AccountManager +import app.pachli.core.database.dao.InstanceDao +import app.pachli.core.database.model.AccountEntity +import app.pachli.core.network.model.InstanceConfiguration +import app.pachli.core.network.model.InstanceV1 +import app.pachli.core.network.model.StatusConfiguration +import app.pachli.core.network.retrofit.MastodonApi import at.connyduck.calladapter.networkresult.NetworkResult import kotlinx.coroutines.test.runTest import org.junit.Assert.assertEquals diff --git a/app/src/test/java/app/pachli/components/notifications/NotificationsPagingSourceTest.kt b/app/src/test/java/app/pachli/components/notifications/NotificationsPagingSourceTest.kt index 260a24d0e..04395ef94 100644 --- a/app/src/test/java/app/pachli/components/notifications/NotificationsPagingSourceTest.kt +++ b/app/src/test/java/app/pachli/components/notifications/NotificationsPagingSourceTest.kt @@ -19,8 +19,8 @@ package app.pachli.components.notifications import androidx.paging.PagingSource import androidx.test.ext.junit.runners.AndroidJUnit4 -import app.pachli.entity.Notification -import app.pachli.network.MastodonApi +import app.pachli.core.network.model.Notification +import app.pachli.core.network.retrofit.MastodonApi import com.google.gson.Gson import kotlinx.coroutines.test.runTest import okhttp3.ResponseBody.Companion.toResponseBody diff --git a/app/src/test/java/app/pachli/components/notifications/NotificationsViewModelTestBase.kt b/app/src/test/java/app/pachli/components/notifications/NotificationsViewModelTestBase.kt index 61098f99f..32ffccc32 100644 --- a/app/src/test/java/app/pachli/components/notifications/NotificationsViewModelTestBase.kt +++ b/app/src/test/java/app/pachli/components/notifications/NotificationsViewModelTestBase.kt @@ -21,15 +21,15 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import app.pachli.appstore.EventHub import app.pachli.components.timeline.FilterKind import app.pachli.components.timeline.FiltersRepository -import app.pachli.components.timeline.MainCoroutineRule -import app.pachli.db.AccountEntity -import app.pachli.db.AccountManager -import app.pachli.fakes.InMemorySharedPreferences -import app.pachli.network.MastodonApi +import app.pachli.core.accounts.AccountManager +import app.pachli.core.database.model.AccountEntity +import app.pachli.core.network.retrofit.MastodonApi +import app.pachli.core.preferences.SharedPreferencesRepository +import app.pachli.core.testing.fakes.InMemorySharedPreferences +import app.pachli.core.testing.rules.MainCoroutineRule import app.pachli.network.ServerCapabilitiesRepository import app.pachli.settings.AccountPreferenceDataStore import app.pachli.usecase.TimelineCases -import app.pachli.util.SharedPreferencesRepository import app.pachli.util.StatusDisplayOptionsRepository import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.test.TestScope diff --git a/app/src/test/java/app/pachli/components/notifications/NotificationsViewModelTestFilter.kt b/app/src/test/java/app/pachli/components/notifications/NotificationsViewModelTestFilter.kt index d0295f858..06bfa813d 100644 --- a/app/src/test/java/app/pachli/components/notifications/NotificationsViewModelTestFilter.kt +++ b/app/src/test/java/app/pachli/components/notifications/NotificationsViewModelTestFilter.kt @@ -18,8 +18,8 @@ package app.pachli.components.notifications import app.cash.turbine.test -import app.pachli.db.AccountEntity -import app.pachli.entity.Notification +import app.pachli.core.database.model.AccountEntity +import app.pachli.core.network.model.Notification import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runTest import org.junit.Test diff --git a/app/src/test/java/app/pachli/components/notifications/NotificationsViewModelTestNotificationAction.kt b/app/src/test/java/app/pachli/components/notifications/NotificationsViewModelTestNotificationAction.kt index 6dced25a4..3233d74fe 100644 --- a/app/src/test/java/app/pachli/components/notifications/NotificationsViewModelTestNotificationAction.kt +++ b/app/src/test/java/app/pachli/components/notifications/NotificationsViewModelTestNotificationAction.kt @@ -18,7 +18,7 @@ package app.pachli.components.notifications import app.cash.turbine.test -import app.pachli.entity.Relationship +import app.pachli.core.network.model.Relationship import at.connyduck.calladapter.networkresult.NetworkResult import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runTest diff --git a/app/src/test/java/app/pachli/components/notifications/NotificationsViewModelTestStatusAction.kt b/app/src/test/java/app/pachli/components/notifications/NotificationsViewModelTestStatusAction.kt index 111f8e992..2f2f64782 100644 --- a/app/src/test/java/app/pachli/components/notifications/NotificationsViewModelTestStatusAction.kt +++ b/app/src/test/java/app/pachli/components/notifications/NotificationsViewModelTestStatusAction.kt @@ -19,8 +19,8 @@ package app.pachli.components.notifications import app.cash.turbine.test import app.pachli.FilterV1Test.Companion.mockStatus +import app.pachli.core.database.model.TranslationState import app.pachli.viewdata.StatusViewData -import app.pachli.viewdata.TranslationState import at.connyduck.calladapter.networkresult.NetworkResult import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runTest diff --git a/app/src/test/java/app/pachli/components/notifications/NotificationsViewModelTestStatusDisplayOptions.kt b/app/src/test/java/app/pachli/components/notifications/NotificationsViewModelTestStatusDisplayOptions.kt index 836cfec93..36b6c4ab6 100644 --- a/app/src/test/java/app/pachli/components/notifications/NotificationsViewModelTestStatusDisplayOptions.kt +++ b/app/src/test/java/app/pachli/components/notifications/NotificationsViewModelTestStatusDisplayOptions.kt @@ -19,7 +19,7 @@ package app.pachli.components.notifications import androidx.core.content.edit import app.cash.turbine.test -import app.pachli.settings.PrefKeys +import app.pachli.core.preferences.PrefKeys import app.pachli.util.StatusDisplayOptions import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runTest diff --git a/app/src/test/java/app/pachli/components/notifications/NotificationsViewModelTestUiState.kt b/app/src/test/java/app/pachli/components/notifications/NotificationsViewModelTestUiState.kt index f6e9b1e4a..d51e8241f 100644 --- a/app/src/test/java/app/pachli/components/notifications/NotificationsViewModelTestUiState.kt +++ b/app/src/test/java/app/pachli/components/notifications/NotificationsViewModelTestUiState.kt @@ -19,8 +19,8 @@ package app.pachli.components.notifications import androidx.core.content.edit import app.cash.turbine.test -import app.pachli.entity.Notification -import app.pachli.settings.PrefKeys +import app.pachli.core.network.model.Notification +import app.pachli.core.preferences.PrefKeys import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runTest import org.junit.Test diff --git a/app/src/test/java/app/pachli/components/notifications/NotificationsViewModelTestVisibleId.kt b/app/src/test/java/app/pachli/components/notifications/NotificationsViewModelTestVisibleId.kt index fcd2a0380..85c95b4ad 100644 --- a/app/src/test/java/app/pachli/components/notifications/NotificationsViewModelTestVisibleId.kt +++ b/app/src/test/java/app/pachli/components/notifications/NotificationsViewModelTestVisibleId.kt @@ -17,7 +17,7 @@ package app.pachli.components.notifications -import app.pachli.db.AccountEntity +import app.pachli.core.database.model.AccountEntity import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runTest import org.junit.Test diff --git a/app/src/test/java/app/pachli/components/timeline/CachedTimelineRemoteMediatorTest.kt b/app/src/test/java/app/pachli/components/timeline/CachedTimelineRemoteMediatorTest.kt index dbc3bdc6b..3d9a02518 100644 --- a/app/src/test/java/app/pachli/components/timeline/CachedTimelineRemoteMediatorTest.kt +++ b/app/src/test/java/app/pachli/components/timeline/CachedTimelineRemoteMediatorTest.kt @@ -12,14 +12,14 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.platform.app.InstrumentationRegistry import app.pachli.components.timeline.viewmodel.CachedTimelineRemoteMediator import app.pachli.components.timeline.viewmodel.CachedTimelineRemoteMediator.Companion.TIMELINE_ID -import app.pachli.db.AccountEntity -import app.pachli.db.AccountManager -import app.pachli.db.AppDatabase -import app.pachli.db.Converters -import app.pachli.db.RemoteKeyEntity -import app.pachli.db.RemoteKeyKind -import app.pachli.db.TimelineStatusWithAccount -import app.pachli.di.TransactionProvider +import app.pachli.core.accounts.AccountManager +import app.pachli.core.database.AppDatabase +import app.pachli.core.database.Converters +import app.pachli.core.database.di.TransactionProvider +import app.pachli.core.database.model.AccountEntity +import app.pachli.core.database.model.RemoteKeyEntity +import app.pachli.core.database.model.RemoteKeyKind +import app.pachli.core.database.model.TimelineStatusWithAccount import com.google.common.truth.Truth.assertThat import com.google.gson.Gson import kotlinx.coroutines.ExperimentalCoroutinesApi diff --git a/app/src/test/java/app/pachli/components/timeline/CachedTimelineViewModelTestBase.kt b/app/src/test/java/app/pachli/components/timeline/CachedTimelineViewModelTestBase.kt index 0ca0ef4a0..312f9e84d 100644 --- a/app/src/test/java/app/pachli/components/timeline/CachedTimelineViewModelTestBase.kt +++ b/app/src/test/java/app/pachli/components/timeline/CachedTimelineViewModelTestBase.kt @@ -23,13 +23,14 @@ import app.pachli.PachliApplication import app.pachli.appstore.EventHub import app.pachli.components.timeline.viewmodel.CachedTimelineViewModel import app.pachli.components.timeline.viewmodel.TimelineViewModel -import app.pachli.db.AccountManager -import app.pachli.entity.Account -import app.pachli.network.MastodonApi +import app.pachli.core.accounts.AccountManager +import app.pachli.core.network.model.Account +import app.pachli.core.network.retrofit.MastodonApi +import app.pachli.core.preferences.SharedPreferencesRepository +import app.pachli.core.testing.rules.MainCoroutineRule import app.pachli.network.ServerCapabilitiesRepository import app.pachli.settings.AccountPreferenceDataStore import app.pachli.usecase.TimelineCases -import app.pachli.util.SharedPreferencesRepository import app.pachli.util.StatusDisplayOptionsRepository import at.connyduck.calladapter.networkresult.NetworkResult import com.google.gson.Gson diff --git a/app/src/test/java/app/pachli/components/timeline/CachedTimelineViewModelTestStatusAction.kt b/app/src/test/java/app/pachli/components/timeline/CachedTimelineViewModelTestStatusAction.kt index 9628f7e7a..fef3ab569 100644 --- a/app/src/test/java/app/pachli/components/timeline/CachedTimelineViewModelTestStatusAction.kt +++ b/app/src/test/java/app/pachli/components/timeline/CachedTimelineViewModelTestStatusAction.kt @@ -22,8 +22,8 @@ import app.pachli.FilterV1Test.Companion.mockStatus import app.pachli.components.timeline.viewmodel.StatusAction import app.pachli.components.timeline.viewmodel.StatusActionSuccess import app.pachli.components.timeline.viewmodel.UiError +import app.pachli.core.database.model.TranslationState import app.pachli.viewdata.StatusViewData -import app.pachli.viewdata.TranslationState import at.connyduck.calladapter.networkresult.NetworkResult import com.google.common.truth.Truth.assertThat import dagger.hilt.android.testing.HiltAndroidTest diff --git a/app/src/test/java/app/pachli/components/timeline/CachedTimelineViewModelTestStatusDisplayOptions.kt b/app/src/test/java/app/pachli/components/timeline/CachedTimelineViewModelTestStatusDisplayOptions.kt index 7b68d84f1..c22c83f5f 100644 --- a/app/src/test/java/app/pachli/components/timeline/CachedTimelineViewModelTestStatusDisplayOptions.kt +++ b/app/src/test/java/app/pachli/components/timeline/CachedTimelineViewModelTestStatusDisplayOptions.kt @@ -19,7 +19,7 @@ package app.pachli.components.timeline import androidx.core.content.edit import app.cash.turbine.test -import app.pachli.settings.PrefKeys +import app.pachli.core.preferences.PrefKeys import app.pachli.util.StatusDisplayOptions import com.google.common.truth.Truth.assertThat import dagger.hilt.android.testing.HiltAndroidTest diff --git a/app/src/test/java/app/pachli/components/timeline/CachedTimelineViewModelTestUiState.kt b/app/src/test/java/app/pachli/components/timeline/CachedTimelineViewModelTestUiState.kt index f484f2c57..a6358c95b 100644 --- a/app/src/test/java/app/pachli/components/timeline/CachedTimelineViewModelTestUiState.kt +++ b/app/src/test/java/app/pachli/components/timeline/CachedTimelineViewModelTestUiState.kt @@ -20,7 +20,7 @@ package app.pachli.components.timeline import androidx.core.content.edit import app.cash.turbine.test import app.pachli.components.timeline.viewmodel.UiState -import app.pachli.settings.PrefKeys +import app.pachli.core.preferences.PrefKeys import com.google.common.truth.Truth.assertThat import dagger.hilt.android.testing.HiltAndroidTest import kotlinx.coroutines.test.runTest diff --git a/app/src/test/java/app/pachli/components/timeline/NetworkTimelinePagingSourceTest.kt b/app/src/test/java/app/pachli/components/timeline/NetworkTimelinePagingSourceTest.kt index e3b5ea176..1e6326ee2 100644 --- a/app/src/test/java/app/pachli/components/timeline/NetworkTimelinePagingSourceTest.kt +++ b/app/src/test/java/app/pachli/components/timeline/NetworkTimelinePagingSourceTest.kt @@ -23,7 +23,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import app.pachli.components.timeline.viewmodel.NetworkTimelinePagingSource import app.pachli.components.timeline.viewmodel.Page import app.pachli.components.timeline.viewmodel.PageCache -import app.pachli.entity.Status +import app.pachli.core.network.model.Status import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runTest import org.junit.Test diff --git a/app/src/test/java/app/pachli/components/timeline/NetworkTimelineRemoteMediatorTest.kt b/app/src/test/java/app/pachli/components/timeline/NetworkTimelineRemoteMediatorTest.kt index 3b8419d9f..46d8118f9 100644 --- a/app/src/test/java/app/pachli/components/timeline/NetworkTimelineRemoteMediatorTest.kt +++ b/app/src/test/java/app/pachli/components/timeline/NetworkTimelineRemoteMediatorTest.kt @@ -28,9 +28,9 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import app.pachli.components.timeline.viewmodel.NetworkTimelineRemoteMediator import app.pachli.components.timeline.viewmodel.Page import app.pachli.components.timeline.viewmodel.PageCache -import app.pachli.db.AccountEntity -import app.pachli.db.AccountManager -import app.pachli.entity.Status +import app.pachli.core.accounts.AccountManager +import app.pachli.core.database.model.AccountEntity +import app.pachli.core.network.model.Status import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runTest import okhttp3.Headers diff --git a/app/src/test/java/app/pachli/components/timeline/NetworkTimelineViewModelTestBase.kt b/app/src/test/java/app/pachli/components/timeline/NetworkTimelineViewModelTestBase.kt index 7da8beee7..5405cf54f 100644 --- a/app/src/test/java/app/pachli/components/timeline/NetworkTimelineViewModelTestBase.kt +++ b/app/src/test/java/app/pachli/components/timeline/NetworkTimelineViewModelTestBase.kt @@ -22,13 +22,14 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import app.pachli.appstore.EventHub import app.pachli.components.timeline.viewmodel.NetworkTimelineViewModel import app.pachli.components.timeline.viewmodel.TimelineViewModel -import app.pachli.db.AccountManager -import app.pachli.entity.Account -import app.pachli.network.MastodonApi +import app.pachli.core.accounts.AccountManager +import app.pachli.core.network.model.Account +import app.pachli.core.network.retrofit.MastodonApi +import app.pachli.core.preferences.SharedPreferencesRepository +import app.pachli.core.testing.rules.MainCoroutineRule import app.pachli.network.ServerCapabilitiesRepository import app.pachli.settings.AccountPreferenceDataStore import app.pachli.usecase.TimelineCases -import app.pachli.util.SharedPreferencesRepository import app.pachli.util.StatusDisplayOptionsRepository import at.connyduck.calladapter.networkresult.NetworkResult import dagger.hilt.android.testing.HiltAndroidRule diff --git a/app/src/test/java/app/pachli/components/timeline/NetworkTimelineViewModelTestStatusAction.kt b/app/src/test/java/app/pachli/components/timeline/NetworkTimelineViewModelTestStatusAction.kt index eeb5d0778..9fdddf52c 100644 --- a/app/src/test/java/app/pachli/components/timeline/NetworkTimelineViewModelTestStatusAction.kt +++ b/app/src/test/java/app/pachli/components/timeline/NetworkTimelineViewModelTestStatusAction.kt @@ -22,8 +22,8 @@ import app.pachli.FilterV1Test.Companion.mockStatus import app.pachli.components.timeline.viewmodel.StatusAction import app.pachli.components.timeline.viewmodel.StatusActionSuccess import app.pachli.components.timeline.viewmodel.UiError +import app.pachli.core.database.model.TranslationState import app.pachli.viewdata.StatusViewData -import app.pachli.viewdata.TranslationState import at.connyduck.calladapter.networkresult.NetworkResult import com.google.common.truth.Truth.assertThat import dagger.hilt.android.testing.HiltAndroidTest diff --git a/app/src/test/java/app/pachli/components/timeline/NetworkTimelineViewModelTestStatusDisplayOptions.kt b/app/src/test/java/app/pachli/components/timeline/NetworkTimelineViewModelTestStatusDisplayOptions.kt index 5ab9164ab..0af7b8205 100644 --- a/app/src/test/java/app/pachli/components/timeline/NetworkTimelineViewModelTestStatusDisplayOptions.kt +++ b/app/src/test/java/app/pachli/components/timeline/NetworkTimelineViewModelTestStatusDisplayOptions.kt @@ -19,7 +19,7 @@ package app.pachli.components.timeline import androidx.core.content.edit import app.cash.turbine.test -import app.pachli.settings.PrefKeys +import app.pachli.core.preferences.PrefKeys import app.pachli.util.StatusDisplayOptions import com.google.common.truth.Truth.assertThat import dagger.hilt.android.testing.HiltAndroidTest diff --git a/app/src/test/java/app/pachli/components/timeline/NetworkTimelineViewModelTestUiState.kt b/app/src/test/java/app/pachli/components/timeline/NetworkTimelineViewModelTestUiState.kt index fa510a275..43a99b333 100644 --- a/app/src/test/java/app/pachli/components/timeline/NetworkTimelineViewModelTestUiState.kt +++ b/app/src/test/java/app/pachli/components/timeline/NetworkTimelineViewModelTestUiState.kt @@ -20,7 +20,7 @@ package app.pachli.components.timeline import androidx.core.content.edit import app.cash.turbine.test import app.pachli.components.timeline.viewmodel.UiState -import app.pachli.settings.PrefKeys +import app.pachli.core.preferences.PrefKeys import com.google.common.truth.Truth.assertThat import dagger.hilt.android.testing.HiltAndroidTest import kotlinx.coroutines.test.runTest diff --git a/app/src/test/java/app/pachli/components/timeline/StatusMocker.kt b/app/src/test/java/app/pachli/components/timeline/StatusMocker.kt index c38643b26..ccc1833c6 100644 --- a/app/src/test/java/app/pachli/components/timeline/StatusMocker.kt +++ b/app/src/test/java/app/pachli/components/timeline/StatusMocker.kt @@ -1,13 +1,13 @@ package app.pachli.components.timeline -import app.pachli.db.StatusViewDataEntity -import app.pachli.db.TimelineAccountEntity -import app.pachli.db.TimelineStatusEntity -import app.pachli.db.TimelineStatusWithAccount -import app.pachli.entity.Status -import app.pachli.entity.TimelineAccount +import app.pachli.core.database.model.StatusViewDataEntity +import app.pachli.core.database.model.TimelineAccountEntity +import app.pachli.core.database.model.TimelineStatusEntity +import app.pachli.core.database.model.TimelineStatusWithAccount +import app.pachli.core.database.model.TranslationState +import app.pachli.core.network.model.Status +import app.pachli.core.network.model.TimelineAccount import app.pachli.viewdata.StatusViewData -import app.pachli.viewdata.TranslationState import com.google.gson.Gson import java.util.Date diff --git a/app/src/test/java/app/pachli/components/viewthread/ViewThreadViewModelTest.kt b/app/src/test/java/app/pachli/components/viewthread/ViewThreadViewModelTest.kt index b46eefd24..7c48c3e3b 100644 --- a/app/src/test/java/app/pachli/components/viewthread/ViewThreadViewModelTest.kt +++ b/app/src/test/java/app/pachli/components/viewthread/ViewThreadViewModelTest.kt @@ -13,16 +13,16 @@ import app.pachli.components.timeline.FilterKind import app.pachli.components.timeline.FiltersRepository import app.pachli.components.timeline.mockStatus import app.pachli.components.timeline.mockStatusViewData -import app.pachli.db.AccountEntity -import app.pachli.db.AccountManager -import app.pachli.db.TimelineDao -import app.pachli.entity.Account -import app.pachli.entity.StatusContext -import app.pachli.network.MastodonApi +import app.pachli.core.accounts.AccountManager +import app.pachli.core.database.dao.TimelineDao +import app.pachli.core.database.model.AccountEntity +import app.pachli.core.network.model.Account +import app.pachli.core.network.model.StatusContext +import app.pachli.core.network.retrofit.MastodonApi +import app.pachli.core.preferences.SharedPreferencesRepository import app.pachli.network.ServerCapabilitiesRepository import app.pachli.settings.AccountPreferenceDataStore import app.pachli.usecase.TimelineCases -import app.pachli.util.SharedPreferencesRepository import app.pachli.util.StatusDisplayOptionsRepository import at.connyduck.calladapter.networkresult.NetworkResult import com.google.gson.Gson diff --git a/app/src/test/java/app/pachli/di/FakeMastodonApiModule.kt b/app/src/test/java/app/pachli/di/FakeMastodonApiModule.kt index 726c4abd0..0d1372073 100644 --- a/app/src/test/java/app/pachli/di/FakeMastodonApiModule.kt +++ b/app/src/test/java/app/pachli/di/FakeMastodonApiModule.kt @@ -17,7 +17,8 @@ package app.pachli.di -import app.pachli.network.MastodonApi +import app.pachli.core.network.di.MastodonApiModule +import app.pachli.core.network.retrofit.MastodonApi import dagger.Module import dagger.Provides import dagger.hilt.components.SingletonComponent diff --git a/app/src/test/java/app/pachli/di/FakeNetworkModule.kt b/app/src/test/java/app/pachli/di/FakeNetworkModule.kt index 6b57f4b87..8e4d34b36 100644 --- a/app/src/test/java/app/pachli/di/FakeNetworkModule.kt +++ b/app/src/test/java/app/pachli/di/FakeNetworkModule.kt @@ -18,7 +18,8 @@ package app.pachli.di import app.pachli.components.compose.MediaUploader -import app.pachli.json.Rfc3339DateJsonAdapter +import app.pachli.core.network.di.NetworkModule +import app.pachli.core.network.json.Rfc3339DateJsonAdapter import com.google.gson.Gson import com.google.gson.GsonBuilder import dagger.Module diff --git a/app/src/test/java/app/pachli/di/FakePreferencesModule.kt b/app/src/test/java/app/pachli/di/FakePreferencesModule.kt index b087e9973..3c954cf3e 100644 --- a/app/src/test/java/app/pachli/di/FakePreferencesModule.kt +++ b/app/src/test/java/app/pachli/di/FakePreferencesModule.kt @@ -18,7 +18,8 @@ package app.pachli.di import android.content.SharedPreferences -import app.pachli.fakes.InMemorySharedPreferences +import app.pachli.core.preferences.di.PreferencesModule +import app.pachli.core.testing.fakes.InMemorySharedPreferences import dagger.Module import dagger.Provides import dagger.hilt.components.SingletonComponent diff --git a/app/src/test/java/app/pachli/usecase/TimelineCasesTest.kt b/app/src/test/java/app/pachli/usecase/TimelineCasesTest.kt index 9bb5a9448..6a339a4e5 100644 --- a/app/src/test/java/app/pachli/usecase/TimelineCasesTest.kt +++ b/app/src/test/java/app/pachli/usecase/TimelineCasesTest.kt @@ -5,8 +5,8 @@ import app.cash.turbine.test import app.pachli.appstore.EventHub import app.pachli.appstore.PinEvent import app.pachli.components.timeline.CachedTimelineRepository -import app.pachli.entity.Status -import app.pachli.network.MastodonApi +import app.pachli.core.network.model.Status +import app.pachli.core.network.retrofit.MastodonApi import at.connyduck.calladapter.networkresult.NetworkResult import kotlinx.coroutines.runBlocking import okhttp3.ResponseBody.Companion.toResponseBody diff --git a/app/src/test/java/app/pachli/util/LinkHelperTest.kt b/app/src/test/java/app/pachli/util/LinkHelperTest.kt index 1b6b7e79b..e139a5157 100644 --- a/app/src/test/java/app/pachli/util/LinkHelperTest.kt +++ b/app/src/test/java/app/pachli/util/LinkHelperTest.kt @@ -7,8 +7,8 @@ import android.widget.TextView import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.platform.app.InstrumentationRegistry import app.pachli.R -import app.pachli.entity.HashTag -import app.pachli.entity.Status +import app.pachli.core.network.model.HashTag +import app.pachli.core.network.model.Status import app.pachli.interfaces.LinkListener import org.junit.Assert import org.junit.Test diff --git a/app/src/test/java/app/pachli/util/LocaleUtilsTest.kt b/app/src/test/java/app/pachli/util/LocaleUtilsTest.kt index ccaef260a..59aca8928 100644 --- a/app/src/test/java/app/pachli/util/LocaleUtilsTest.kt +++ b/app/src/test/java/app/pachli/util/LocaleUtilsTest.kt @@ -3,7 +3,7 @@ package app.pachli.util import androidx.appcompat.app.AppCompatDelegate import androidx.core.os.LocaleListCompat import androidx.test.ext.junit.runners.AndroidJUnit4 -import app.pachli.db.AccountEntity +import app.pachli.core.database.model.AccountEntity import org.junit.Assert import org.junit.Test import org.junit.runner.RunWith diff --git a/app/src/test/java/app/pachli/util/StatusDisplayOptionsRepositoryTest.kt b/app/src/test/java/app/pachli/util/StatusDisplayOptionsRepositoryTest.kt index d66a72f01..ebadfefdf 100644 --- a/app/src/test/java/app/pachli/util/StatusDisplayOptionsRepositoryTest.kt +++ b/app/src/test/java/app/pachli/util/StatusDisplayOptionsRepositoryTest.kt @@ -22,13 +22,14 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import app.cash.turbine.test import app.pachli.PachliApplication import app.pachli.components.compose.HiltTestApplication_Application -import app.pachli.components.timeline.MainCoroutineRule -import app.pachli.db.AccountManager -import app.pachli.entity.Account -import app.pachli.network.MastodonApi +import app.pachli.core.accounts.AccountManager +import app.pachli.core.network.model.Account +import app.pachli.core.network.retrofit.MastodonApi +import app.pachli.core.preferences.PrefKeys +import app.pachli.core.preferences.SharedPreferencesRepository +import app.pachli.core.testing.rules.MainCoroutineRule import app.pachli.network.ServerCapabilitiesRepository import app.pachli.settings.AccountPreferenceDataStore -import app.pachli.settings.PrefKeys import com.google.common.truth.Truth.assertThat import dagger.hilt.android.testing.CustomTestApplication import dagger.hilt.android.testing.HiltAndroidRule diff --git a/build-logic/convention/build.gradle.kts b/build-logic/convention/build.gradle.kts new file mode 100644 index 000000000..80e7019b3 --- /dev/null +++ b/build-logic/convention/build.gradle.kts @@ -0,0 +1,67 @@ +/* + * Copyright 2023 Pachli Association + * + * This file is a part of Pachli. + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Pachli; if not, + * see . + */ + +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + `kotlin-dsl` +} + +group = "app.pachli.buildlogic" + +// Configure the build-logic plugins to target JDK 17 +// This matches the JDK used to build the project, and is not related to what is running on device. +java { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 +} +tasks.withType().configureEach { + kotlinOptions { + jvmTarget = JavaVersion.VERSION_17.toString() + } +} + +dependencies { + compileOnly(libs.android.gradlePlugin) + compileOnly(libs.kotlin.gradlePlugin) + compileOnly(libs.ksp.gradlePlugin) +} + +gradlePlugin { + plugins { + register("androidApplication") { + id = "pachli.android.application" + implementationClass = "AndroidApplicationConventionPlugin" + } + register("androidLibrary") { + id = "pachli.android.library" + implementationClass = "AndroidLibraryConventionPlugin" + } + register("androidHilt") { + id = "pachli.android.hilt" + implementationClass = "AndroidHiltConventionPlugin" + } + register("androidRoom") { + id = "pachli.android.room" + implementationClass = "AndroidRoomConventionPlugin" + } + register("androidLint") { + id = "pachli.android.lint" + implementationClass = "AndroidLintConventionPlugin" + } + } +} diff --git a/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt new file mode 100644 index 000000000..0ebff4d90 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt @@ -0,0 +1,46 @@ +/* + * Copyright 2023 Pachli Association + * + * This file is a part of Pachli. + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Pachli; if not, + * see . + */ + +import app.pachli.configureFlavors +import app.pachli.libs +import com.android.build.api.dsl.ApplicationExtension +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.dependencies + +class AndroidApplicationConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + with(pluginManager) { + apply("com.android.application") + apply("org.jetbrains.kotlin.android") + apply("pachli.android.lint") + } + + extensions.configure { + configureKotlinAndroid(this) + defaultConfig.targetSdk = 34 + configureFlavors(this) + } + + dependencies { + add("implementation", libs.findLibrary("timber").get()) + } + } + } +} diff --git a/build-logic/convention/src/main/kotlin/AndroidHiltConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidHiltConventionPlugin.kt new file mode 100644 index 000000000..d06740a7b --- /dev/null +++ b/build-logic/convention/src/main/kotlin/AndroidHiltConventionPlugin.kt @@ -0,0 +1,41 @@ +/* + * Copyright 2023 Pachli Association + * + * This file is a part of Pachli. + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Pachli; if not, + * see . + */ + +import app.pachli.libs +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.dependencies + +class AndroidHiltConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + with(pluginManager) { + apply("dagger.hilt.android.plugin") + apply("com.google.devtools.ksp") + } + + dependencies { + add("implementation", libs.findLibrary("hilt.android").get()) + add("ksp", libs.findLibrary("hilt.compiler").get()) + add("testImplementation", libs.findLibrary("hilt.android.testing").get()) + add("testImplementation", libs.findLibrary("hilt.android.testing").get()) + add("kspTest", (libs.findLibrary("hilt.compiler").get())) + add("kspAndroidTest", libs.findLibrary("hilt.compiler").get()) + } + } + } +} diff --git a/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt new file mode 100644 index 000000000..545c0ad1d --- /dev/null +++ b/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt @@ -0,0 +1,59 @@ + + +/* + * Copyright 2023 Pachli Association + * + * This file is a part of Pachli. + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Pachli; if not, + * see . + */ + +import app.pachli.configureFlavors +import app.pachli.disableUnnecessaryAndroidTests +import app.pachli.libs +import com.android.build.api.variant.LibraryAndroidComponentsExtension +import com.android.build.gradle.LibraryExtension +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.dependencies +import org.gradle.kotlin.dsl.kotlin + +class AndroidLibraryConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + with(pluginManager) { + apply("com.android.library") + apply("org.jetbrains.kotlin.android") + apply("pachli.android.lint") + } + + extensions.configure { + configureKotlinAndroid(this) + defaultConfig.targetSdk = 34 + configureFlavors(this) + } + + extensions.configure { + disableUnnecessaryAndroidTests(target) + } + + dependencies { + add("implementation", libs.findLibrary("timber").get()) + add("testImplementation", kotlin("test")) + add("testImplementation", project(":core:testing")) + add("androidTestImplementation", kotlin("test")) + add("androidTestImplementation", project(":core:testing")) + } + } + } +} diff --git a/build-logic/convention/src/main/kotlin/AndroidLintConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidLintConventionPlugin.kt new file mode 100644 index 000000000..9b72e6b59 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/AndroidLintConventionPlugin.kt @@ -0,0 +1,49 @@ +/* + * Copyright 2023 Pachli Association + * + * This file is a part of Pachli. + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Pachli; if not, + * see . + */ + + +import com.android.build.api.dsl.ApplicationExtension +import com.android.build.api.dsl.LibraryExtension +import com.android.build.api.dsl.Lint +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.configure +import java.io.File + +class AndroidLintConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + when { + pluginManager.hasPlugin("com.android.application") -> + configure { lint { configure(this@with) } } + + pluginManager.hasPlugin("com.android.library") -> + configure { lint { configure(this@with) } } + + else -> { + pluginManager.apply("com.android.lint") + configure { configure(this@with) } + } + } + } + } +} + +private fun Lint.configure(project: Project) { + lintConfig = File(project.findProject(":app")?.projectDir, "lint.xml") + baseline = File("lint-baseline.xml") +} diff --git a/build-logic/convention/src/main/kotlin/AndroidRoomConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidRoomConventionPlugin.kt new file mode 100644 index 000000000..ad71db657 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/AndroidRoomConventionPlugin.kt @@ -0,0 +1,61 @@ +/* + * Copyright 2023 Pachli Association + * + * This file is a part of Pachli. + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Pachli; if not, + * see . + */ + +import app.pachli.libs +import com.google.devtools.ksp.gradle.KspExtension +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.tasks.InputDirectory +import org.gradle.api.tasks.PathSensitive +import org.gradle.api.tasks.PathSensitivity +import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.dependencies +import org.gradle.process.CommandLineArgumentProvider +import java.io.File + +class AndroidRoomConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + pluginManager.apply("com.google.devtools.ksp") + + extensions.configure { + // The schemas directory contains a schema file for each version of the Room database. + // This is required to enable Room auto migrations. + // See https://developer.android.com/reference/kotlin/androidx/room/AutoMigration. + arg(RoomSchemaArgProvider(File(projectDir, "schemas"))) + arg("room.incremental", "true") + } + + dependencies { + add("implementation", libs.findBundle("room").get()) + add("ksp", libs.findLibrary("androidx.room.compiler").get()) + } + } + } + + /** + * https://issuetracker.google.com/issues/132245929 + * [Export schemas](https://developer.android.com/training/data-storage/room/migrating-db-versions#export-schemas) + */ + class RoomSchemaArgProvider( + @get:InputDirectory + @get:PathSensitive(PathSensitivity.RELATIVE) + val schemaDir: File, + ) : CommandLineArgumentProvider { + override fun asArguments() = listOf("room.schemaLocation=${schemaDir.path}") + } +} diff --git a/build-logic/convention/src/main/kotlin/app/pachli/AndroidInstrumentedTests.kt b/build-logic/convention/src/main/kotlin/app/pachli/AndroidInstrumentedTests.kt new file mode 100644 index 000000000..e665abea6 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/app/pachli/AndroidInstrumentedTests.kt @@ -0,0 +1,35 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package app.pachli + +import com.android.build.api.variant.LibraryAndroidComponentsExtension +import org.gradle.api.Project + +/** + * Disable unnecessary Android instrumented tests for the [project] if there is no `androidTest` folder. + * Otherwise, these projects would be compiled, packaged, installed and ran only to end-up with the following message: + * + * > Starting 0 tests on AVD + * + * Note: this could be improved by checking other potential sourceSets based on buildTypes and flavors. + */ +internal fun LibraryAndroidComponentsExtension.disableUnnecessaryAndroidTests( + project: Project, +) = beforeVariants { + it.enableAndroidTest = it.enableAndroidTest + && project.projectDir.resolve("src/androidTest").exists() +} diff --git a/build-logic/convention/src/main/kotlin/app/pachli/KotlinAndroid.kt b/build-logic/convention/src/main/kotlin/app/pachli/KotlinAndroid.kt new file mode 100644 index 000000000..be85807b7 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/app/pachli/KotlinAndroid.kt @@ -0,0 +1,83 @@ +/* + * Copyright 2023 Pachli Association + * + * This file is a part of Pachli. + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Pachli; if not, + * see . + */ + +import com.android.build.api.dsl.CommonExtension +import org.gradle.api.JavaVersion +import org.gradle.api.Project +import org.gradle.kotlin.dsl.provideDelegate +import org.gradle.kotlin.dsl.withType +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +/** + * Configure base Kotlin with Android options + */ +internal fun Project.configureKotlinAndroid( + commonExtension: CommonExtension<*, *, *, *, *>, +) { + commonExtension.apply { + compileSdk = 34 + + defaultConfig { + minSdk = 23 + } + + testOptions { + unitTests { + // Without this Robolectric skips some tests with "doesn't support legacy + // resources mode after P" message + isIncludeAndroidResources = true + } + } + + buildFeatures { + buildConfig = true + resValues = true + viewBinding = true + } + } + + configureKotlin() +} + +/** + * Configure base Kotlin options for JVM (non-Android) + */ +internal fun Project.configureKotlinJvm() { + configureKotlin() +} + +/** + * Configure base Kotlin options + */ +private fun Project.configureKotlin() { + // Use withType to workaround https://youtrack.jetbrains.com/issue/KT-55947 + tasks.withType().configureEach { + kotlinOptions { + jvmTarget = JavaVersion.VERSION_17.toString() + // Treat all Kotlin warnings as errors (disabled by default) + // Override by setting warningsAsErrors=true in your ~/.gradle/gradle.properties + val warningsAsErrors: String? by project + allWarningsAsErrors = warningsAsErrors.toBoolean() + freeCompilerArgs = freeCompilerArgs + listOf( + "-opt-in=kotlin.RequiresOptIn", + // Enable experimental coroutines APIs, including Flow + "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", + "-opt-in=kotlinx.coroutines.FlowPreview", + ) + } + } +} diff --git a/build-logic/convention/src/main/kotlin/app/pachli/PachliFlavor.kt b/build-logic/convention/src/main/kotlin/app/pachli/PachliFlavor.kt new file mode 100644 index 000000000..1d0565714 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/app/pachli/PachliFlavor.kt @@ -0,0 +1,80 @@ +/* + * Copyright 2023 Pachli Association + * + * This file is a part of Pachli. + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Pachli; if not, + * see . + */ + +package app.pachli + +import com.android.build.api.dsl.ApplicationExtension +import com.android.build.api.dsl.ApplicationProductFlavor +import com.android.build.api.dsl.CommonExtension +import com.android.build.api.dsl.ProductFlavor + +@Suppress("EnumEntryName") +enum class FlavorDimension { + color, + store +} + +@Suppress("EnumEntryName") +enum class PachliFlavor( + val dimension: FlavorDimension, + val applicationIdSuffix: String? = null, + val versionNameSuffix: String? = null, + val appName: String = "Pachli", + val customLogoUrl: String = "", + val customInstance: String = "", + val supportAccountUrl: String = "https://mastodon.social/@Pachli" +) { + blue(FlavorDimension.color), + orange( + FlavorDimension.color, + applicationIdSuffix = ".current", + appName = "Pachli Current", + ), + fdroid(FlavorDimension.store), + github(FlavorDimension.store), + google(FlavorDimension.store) +} + +fun configureFlavors( + commonExtension: CommonExtension<*, *, *, *, *>, + flavorConfigurationBlock: ProductFlavor.(flavor: PachliFlavor) -> Unit = {} +) { + commonExtension.apply { + flavorDimensions += FlavorDimension.color.name + flavorDimensions += FlavorDimension.store.name + productFlavors { + PachliFlavor.values().forEach { flavor -> + create(flavor.name) { + dimension = flavor.dimension.name + flavorConfigurationBlock(this, flavor) + if (this@apply is ApplicationExtension && this is ApplicationProductFlavor) { + flavor.applicationIdSuffix?.let { + applicationIdSuffix = it + } + flavor.versionNameSuffix?.let { + versionNameSuffix = it + } + } + resValue("string", "app_name", flavor.appName) + buildConfigField("String", "CUSTOM_LOGO_URL", "\"${flavor.customLogoUrl}\"") + buildConfigField("String", "CUSTOM_INSTANCE", "\"${flavor.customInstance}\"") + buildConfigField("String", "SUPPORT_ACCOUNT_URL", "\"${flavor.supportAccountUrl}\"") + } + } + } + } +} diff --git a/build-logic/convention/src/main/kotlin/app/pachli/ProjectExtensions.kt b/build-logic/convention/src/main/kotlin/app/pachli/ProjectExtensions.kt new file mode 100644 index 000000000..fd63b83bf --- /dev/null +++ b/build-logic/convention/src/main/kotlin/app/pachli/ProjectExtensions.kt @@ -0,0 +1,26 @@ +/* + * Copyright 2023 Pachli Association + * + * This file is a part of Pachli. + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Pachli; if not, + * see . + */ + +package app.pachli + +import org.gradle.api.Project +import org.gradle.api.artifacts.VersionCatalog +import org.gradle.api.artifacts.VersionCatalogsExtension +import org.gradle.kotlin.dsl.getByType + +val Project.libs + get(): VersionCatalog = extensions.getByType().named("libs") diff --git a/build-logic/gradle.properties b/build-logic/gradle.properties new file mode 100644 index 000000000..328a2a1fa --- /dev/null +++ b/build-logic/gradle.properties @@ -0,0 +1,21 @@ +# +# Copyright 2023 Pachli Association +# +# This file is a part of Pachli. +# +# This program is free software; you can redistribute it and/or modify it under the terms of the +# GNU General Public License as published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even +# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along with Pachli; if not, +# see . +# + +# Gradle properties are not passed to included builds https://github.com/gradle/gradle/issues/2534 +org.gradle.parallel=true +org.gradle.caching=true +org.gradle.configureondemand=true diff --git a/build-logic/settings.gradle.kts b/build-logic/settings.gradle.kts new file mode 100644 index 000000000..89bd2d0f8 --- /dev/null +++ b/build-logic/settings.gradle.kts @@ -0,0 +1,31 @@ +/* + * Copyright 2023 Pachli Association + * + * This file is a part of Pachli. + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Pachli; if not, + * see . + */ + +dependencyResolutionManagement { + repositories { + google() + mavenCentral() + } + versionCatalogs { + create("libs") { + from(files("../gradle/libs.versions.toml")) + } + } +} + +rootProject.name = "build-logic" +include(":convention") diff --git a/build.gradle b/build.gradle index 38bb44eb9..67b38bf3f 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,10 @@ plugins { alias(libs.plugins.android.application) apply false + alias(libs.plugins.android.library) apply false + alias(libs.plugins.android.lint) apply false alias(libs.plugins.google.ksp) apply false alias(libs.plugins.kotlin.android) apply false + alias(libs.plugins.kotlin.jvm) apply false alias(libs.plugins.kotlin.parcelize) apply false alias(libs.plugins.ktlint) apply false alias(libs.plugins.aboutlibraries) apply false diff --git a/checks/build.gradle b/checks/build.gradle deleted file mode 100644 index dfcca36ec..000000000 --- a/checks/build.gradle +++ /dev/null @@ -1,36 +0,0 @@ -plugins { - id "java-library" - id "kotlin" - id "com.android.lint" -} - -lintOptions { - htmlReport(true) - htmlOutput(file("lint-report.html")) - textReport(true) - absolutePaths(false) - ignoreTestSources(true) -} - -jar { - manifest { - attributes("Lint-Registry-v2": "app.pachli.lint.checks.LintRegistry") - } -} - -dependencies { - compileOnly("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.20") - - // Derived from the AGP version. If the AGP version is X.Y.Z the version - // here must by X+23.Y.Z. - // See https://github.com/googlesamples/android-custom-lint-rules#lint-version - def lintVersion = "31.2.0" // = AGP 8.2.0 - - // For a description of the below dependencies, see the main project README - compileOnly("com.android.tools.lint:lint-api:$lintVersion") - compileOnly("com.android.tools.lint:lint-checks:$lintVersion") - testImplementation("com.android.tools.lint:lint:$lintVersion") - testImplementation("com.android.tools.lint:lint-tests:$lintVersion") - - testImplementation("junit:junit:4.13.2") -} diff --git a/checks/build.gradle.kts b/checks/build.gradle.kts new file mode 100644 index 000000000..354c700c6 --- /dev/null +++ b/checks/build.gradle.kts @@ -0,0 +1,38 @@ +/* + * Copyright 2023 Pachli Association + * + * This file is a part of Pachli. + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Pachli; if not, + * see . + */ + +plugins { + id("java-library") + alias(libs.plugins.kotlin.jvm) + alias(libs.plugins.android.lint) +} + +java { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 +} + +tasks.jar { + manifest { + attributes["Lint-Registry-v2"] = "app.pachli.lint.checks.LintRegistry" + } +} + +dependencies { + compileOnly(libs.bundles.lint.api) + testImplementation(libs.bundles.lint.tests) +} diff --git a/checks/gradle.properties b/checks/gradle.properties new file mode 100644 index 000000000..328a2a1fa --- /dev/null +++ b/checks/gradle.properties @@ -0,0 +1,21 @@ +# +# Copyright 2023 Pachli Association +# +# This file is a part of Pachli. +# +# This program is free software; you can redistribute it and/or modify it under the terms of the +# GNU General Public License as published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even +# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along with Pachli; if not, +# see . +# + +# Gradle properties are not passed to included builds https://github.com/gradle/gradle/issues/2534 +org.gradle.parallel=true +org.gradle.caching=true +org.gradle.configureondemand=true diff --git a/checks/settings.gradle.kts b/checks/settings.gradle.kts new file mode 100644 index 000000000..76e19bb85 --- /dev/null +++ b/checks/settings.gradle.kts @@ -0,0 +1,30 @@ +/* + * Copyright 2023 Pachli Association + * + * This file is a part of Pachli. + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Pachli; if not, + * see . + */ + +dependencyResolutionManagement { + repositories { + google() + mavenCentral() + } + versionCatalogs { + create("libs") { + from(files("../gradle/libs.versions.toml")) + } + } +} + +rootProject.name = "checks" diff --git a/core/AndroidManifest.xml b/core/AndroidManifest.xml new file mode 100644 index 000000000..76e9ba6e7 --- /dev/null +++ b/core/AndroidManifest.xml @@ -0,0 +1,21 @@ + + + + + + diff --git a/core/accounts/build.gradle.kts b/core/accounts/build.gradle.kts new file mode 100644 index 000000000..5fd7c39b0 --- /dev/null +++ b/core/accounts/build.gradle.kts @@ -0,0 +1,41 @@ +/* + * Copyright 2023 Pachli Association + * + * This file is a part of Pachli. + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Pachli; if not, + * see . + */ + +plugins { + alias(libs.plugins.pachli.android.library) + alias(libs.plugins.pachli.android.hilt) + alias(libs.plugins.kotlin.parcelize) +} + +android { + namespace = "app.pachli.core.accounts" + + defaultConfig { + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } +} + +dependencies { + // Depends on the okhttp3.Interceptor type + // class app.pachli.core.network.retrofit.InstanceSwitchAuthInterceptor, unresolved supertypes: okhttp3.Interceptor + compileOnly(libs.bundles.okhttp) + + implementation(projects.core.common) + implementation(projects.core.database) + implementation(projects.core.network) + implementation(projects.core.preferences) +} diff --git a/core/accounts/lint-baseline.xml b/core/accounts/lint-baseline.xml new file mode 100644 index 000000000..f32fed49a --- /dev/null +++ b/core/accounts/lint-baseline.xml @@ -0,0 +1,4 @@ + + + + diff --git a/core/accounts/src/main/kotlin/AndroidManifest.xml b/core/accounts/src/main/kotlin/AndroidManifest.xml new file mode 100644 index 000000000..76e9ba6e7 --- /dev/null +++ b/core/accounts/src/main/kotlin/AndroidManifest.xml @@ -0,0 +1,21 @@ + + + + + + diff --git a/app/src/main/java/app/pachli/db/AccountManager.kt b/core/accounts/src/main/kotlin/app/pachli/core/accounts/AccountManager.kt similarity index 90% rename from app/src/main/java/app/pachli/db/AccountManager.kt rename to core/accounts/src/main/kotlin/app/pachli/core/accounts/AccountManager.kt index 8f9d549e4..c538b0f0f 100644 --- a/app/src/main/java/app/pachli/db/AccountManager.kt +++ b/core/accounts/src/main/kotlin/app/pachli/core/accounts/AccountManager.kt @@ -1,4 +1,5 @@ -/* Copyright 2018 Conny Duck +/* + * Copyright 2018 Conny Duck * * This file is a part of Pachli. * @@ -14,14 +15,18 @@ * see . */ -package app.pachli.db +package app.pachli.core.accounts import android.content.Context -import app.pachli.di.ApplicationScope -import app.pachli.entity.Account -import app.pachli.entity.Status -import app.pachli.settings.PrefKeys -import app.pachli.util.SharedPreferencesRepository +import app.pachli.core.common.di.ApplicationScope +import app.pachli.core.database.dao.AccountDao +import app.pachli.core.database.dao.RemoteKeyDao +import app.pachli.core.database.model.AccountEntity +import app.pachli.core.network.model.Account +import app.pachli.core.network.model.Status +import app.pachli.core.network.retrofit.InstanceSwitchAuthInterceptor +import app.pachli.core.preferences.PrefKeys +import app.pachli.core.preferences.SharedPreferencesRepository import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow @@ -31,16 +36,12 @@ import java.util.Locale import javax.inject.Inject import javax.inject.Singleton -/** - * This class caches the account database and handles all account related operations - * @author ConnyDuck - */ - @Singleton class AccountManager @Inject constructor( private val accountDao: AccountDao, private val remoteKeyDao: RemoteKeyDao, private val sharedPreferencesRepository: SharedPreferencesRepository, + private val instanceSwitchAuthInterceptor: InstanceSwitchAuthInterceptor, @ApplicationScope private val externalScope: CoroutineScope, ) { private val _activeAccountFlow = MutableStateFlow(null) @@ -50,6 +51,12 @@ class AccountManager @Inject constructor( var activeAccount: AccountEntity? = null private set(value) { field = value + instanceSwitchAuthInterceptor.credentials = value?.let { + InstanceSwitchAuthInterceptor.Credentials( + accessToken = it.accessToken, + domain = it.domain + ) + } externalScope.launch { _activeAccountFlow.emit(value) } } diff --git a/core/common/build.gradle.kts b/core/common/build.gradle.kts new file mode 100644 index 000000000..e4e89b219 --- /dev/null +++ b/core/common/build.gradle.kts @@ -0,0 +1,30 @@ +/* + * Copyright 2023 Pachli Association + * + * This file is a part of Pachli. + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Pachli; if not, + * see . + */ + +plugins { + alias(libs.plugins.pachli.android.library) + alias(libs.plugins.pachli.android.hilt) + alias(libs.plugins.kotlin.parcelize) +} + +android { + namespace = "app.pachli.core.common" + + defaultConfig { + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } +} diff --git a/core/common/lint-baseline.xml b/core/common/lint-baseline.xml new file mode 100644 index 000000000..8eb7b588f --- /dev/null +++ b/core/common/lint-baseline.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/common/src/main/kotlin/AndroidManifest.xml b/core/common/src/main/kotlin/AndroidManifest.xml new file mode 100644 index 000000000..76e9ba6e7 --- /dev/null +++ b/core/common/src/main/kotlin/AndroidManifest.xml @@ -0,0 +1,21 @@ + + + + + + diff --git a/app/src/main/java/app/pachli/di/CoroutineScopeModule.kt b/core/common/src/main/kotlin/app/pachli/core/common/di/CoroutineScopeModule.kt similarity index 98% rename from app/src/main/java/app/pachli/di/CoroutineScopeModule.kt rename to core/common/src/main/kotlin/app/pachli/core/common/di/CoroutineScopeModule.kt index cb929e81e..583b02a96 100644 --- a/app/src/main/java/app/pachli/di/CoroutineScopeModule.kt +++ b/core/common/src/main/kotlin/app/pachli/core/common/di/CoroutineScopeModule.kt @@ -15,7 +15,7 @@ * see . */ -package app.pachli.di +package app.pachli.core.common.di import dagger.Module import dagger.Provides diff --git a/app/src/main/java/app/pachli/util/StringUtils.kt b/core/common/src/main/kotlin/app/pachli/core/common/string/StringUtils.kt similarity index 97% rename from app/src/main/java/app/pachli/util/StringUtils.kt rename to core/common/src/main/kotlin/app/pachli/core/common/string/StringUtils.kt index 9f1a25d31..dca836ad6 100644 --- a/app/src/main/java/app/pachli/util/StringUtils.kt +++ b/core/common/src/main/kotlin/app/pachli/core/common/string/StringUtils.kt @@ -1,4 +1,4 @@ -package app.pachli.util +package app.pachli.core.common.string import android.text.Spanned import java.util.Random diff --git a/app/src/main/java/app/pachli/util/AbsoluteTimeFormatter.kt b/core/common/src/main/kotlin/app/pachli/core/common/util/AbsoluteTimeFormatter.kt similarity index 97% rename from app/src/main/java/app/pachli/util/AbsoluteTimeFormatter.kt rename to core/common/src/main/kotlin/app/pachli/core/common/util/AbsoluteTimeFormatter.kt index 428b1cab3..ae55ee1a8 100644 --- a/app/src/main/java/app/pachli/util/AbsoluteTimeFormatter.kt +++ b/core/common/src/main/kotlin/app/pachli/core/common/util/AbsoluteTimeFormatter.kt @@ -1,4 +1,5 @@ -/* Copyright 2022 Tusky Contributors +/* + * Copyright 2022 Tusky Contributors * * This file is a part of Pachli. * @@ -14,7 +15,7 @@ * see . */ -package app.pachli.util +package app.pachli.core.common.util import java.text.SimpleDateFormat import java.util.Calendar diff --git a/app/src/main/java/app/pachli/util/NumberUtils.kt b/core/common/src/main/kotlin/app/pachli/core/common/util/NumberUtils.kt similarity index 51% rename from app/src/main/java/app/pachli/util/NumberUtils.kt rename to core/common/src/main/kotlin/app/pachli/core/common/util/NumberUtils.kt index fc7d27890..bd163d4b3 100644 --- a/app/src/main/java/app/pachli/util/NumberUtils.kt +++ b/core/common/src/main/kotlin/app/pachli/core/common/util/NumberUtils.kt @@ -1,4 +1,21 @@ -package app.pachli.util +/* + * Copyright 2023 Pachli Association + * + * This file is a part of Pachli. + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Pachli; if not, + * see . + */ + +package app.pachli.core.common.util import java.text.NumberFormat import kotlin.math.abs diff --git a/app/src/test/java/app/pachli/StringUtilsTest.kt b/core/common/src/test/kotlin/app/pachli/core/common/string/StringUtilsTest.kt similarity index 58% rename from app/src/test/java/app/pachli/StringUtilsTest.kt rename to core/common/src/test/kotlin/app/pachli/core/common/string/StringUtilsTest.kt index e61ff3386..85103a8cd 100644 --- a/app/src/test/java/app/pachli/StringUtilsTest.kt +++ b/core/common/src/test/kotlin/app/pachli/core/common/string/StringUtilsTest.kt @@ -1,7 +1,22 @@ -package app.pachli +/* + * Copyright 2023 Pachli Association + * + * This file is a part of Pachli. + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Pachli; if not, + * see . + */ + +package app.pachli.core.common.string -import app.pachli.util.isLessThan -import app.pachli.util.isLessThanOrEqual import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.junit.Test diff --git a/app/src/test/java/app/pachli/util/AbsoluteTimeFormatterTest.kt b/core/common/src/test/kotlin/app/pachli/core/common/util/AbsoluteTimeFormatterTest.kt similarity index 77% rename from app/src/test/java/app/pachli/util/AbsoluteTimeFormatterTest.kt rename to core/common/src/test/kotlin/app/pachli/core/common/util/AbsoluteTimeFormatterTest.kt index 4539b604d..f0e64d875 100644 --- a/app/src/test/java/app/pachli/util/AbsoluteTimeFormatterTest.kt +++ b/core/common/src/test/kotlin/app/pachli/core/common/util/AbsoluteTimeFormatterTest.kt @@ -1,4 +1,21 @@ -package app.pachli.util +/* + * Copyright 2023 Pachli Association + * + * This file is a part of Pachli. + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Pachli; if not, + * see . + */ + +package app.pachli.core.common.util import org.junit.AfterClass import org.junit.Assert.assertEquals diff --git a/app/src/test/java/app/pachli/util/NumberUtilsTest.kt b/core/common/src/test/kotlin/app/pachli/core/common/util/NumberUtilsTest.kt similarity index 98% rename from app/src/test/java/app/pachli/util/NumberUtilsTest.kt rename to core/common/src/test/kotlin/app/pachli/core/common/util/NumberUtilsTest.kt index 3e1657a02..bb2e2119e 100644 --- a/app/src/test/java/app/pachli/util/NumberUtilsTest.kt +++ b/core/common/src/test/kotlin/app/pachli/core/common/util/NumberUtilsTest.kt @@ -15,7 +15,7 @@ * see . */ -package app.pachli.util +package app.pachli.core.common.util import org.junit.AfterClass import org.junit.Assert diff --git a/core/database/build.gradle.kts b/core/database/build.gradle.kts new file mode 100644 index 000000000..07e5c982b --- /dev/null +++ b/core/database/build.gradle.kts @@ -0,0 +1,40 @@ +/* + * Copyright 2023 Pachli Association + * + * This file is a part of Pachli. + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Pachli; if not, + * see . + */ + +plugins { + alias(libs.plugins.pachli.android.library) + alias(libs.plugins.pachli.android.hilt) + alias(libs.plugins.pachli.android.room) + alias(libs.plugins.kotlin.parcelize) +} + +android { + namespace = "app.pachli.core.database" + + defaultConfig { + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } +} + +dependencies { + implementation(projects.core.common) + implementation(projects.core.network) + implementation(projects.core.preferences) + + // Because of the use of @SerializedName in DraftEntity + compileOnly(libs.gson) +} diff --git a/core/database/lint-baseline.xml b/core/database/lint-baseline.xml new file mode 100644 index 000000000..f32fed49a --- /dev/null +++ b/core/database/lint-baseline.xml @@ -0,0 +1,4 @@ + + + + diff --git a/app/schemas/app.pachli.db.AppDatabase/1.json b/core/database/schemas/app.pachli.core.database.AppDatabase/1.json similarity index 100% rename from app/schemas/app.pachli.db.AppDatabase/1.json rename to core/database/schemas/app.pachli.core.database.AppDatabase/1.json diff --git a/app/schemas/app.pachli.db.AppDatabase/2.json b/core/database/schemas/app.pachli.core.database.AppDatabase/2.json similarity index 100% rename from app/schemas/app.pachli.db.AppDatabase/2.json rename to core/database/schemas/app.pachli.core.database.AppDatabase/2.json diff --git a/app/schemas/app.pachli.db.AppDatabase/3.json b/core/database/schemas/app.pachli.core.database.AppDatabase/3.json similarity index 100% rename from app/schemas/app.pachli.db.AppDatabase/3.json rename to core/database/schemas/app.pachli.core.database.AppDatabase/3.json diff --git a/core/database/src/main/kotlin/AndroidManifest.xml b/core/database/src/main/kotlin/AndroidManifest.xml new file mode 100644 index 000000000..76e9ba6e7 --- /dev/null +++ b/core/database/src/main/kotlin/AndroidManifest.xml @@ -0,0 +1,21 @@ + + + + + + diff --git a/app/src/main/java/app/pachli/db/AppDatabase.kt b/core/database/src/main/kotlin/app/pachli/core/database/AppDatabase.kt similarity index 69% rename from app/src/main/java/app/pachli/db/AppDatabase.kt rename to core/database/src/main/kotlin/app/pachli/core/database/AppDatabase.kt index ff6b55f2f..402431fa2 100644 --- a/app/src/main/java/app/pachli/db/AppDatabase.kt +++ b/core/database/src/main/kotlin/app/pachli/core/database/AppDatabase.kt @@ -15,14 +15,29 @@ * see . */ -package app.pachli.db +package app.pachli.core.database import androidx.room.AutoMigration import androidx.room.Database import androidx.room.DeleteColumn import androidx.room.RoomDatabase import androidx.room.migration.AutoMigrationSpec -import app.pachli.components.conversation.ConversationEntity +import app.pachli.core.database.dao.AccountDao +import app.pachli.core.database.dao.ConversationsDao +import app.pachli.core.database.dao.DraftDao +import app.pachli.core.database.dao.InstanceDao +import app.pachli.core.database.dao.RemoteKeyDao +import app.pachli.core.database.dao.TimelineDao +import app.pachli.core.database.dao.TranslatedStatusDao +import app.pachli.core.database.model.AccountEntity +import app.pachli.core.database.model.ConversationEntity +import app.pachli.core.database.model.DraftEntity +import app.pachli.core.database.model.InstanceEntity +import app.pachli.core.database.model.RemoteKeyEntity +import app.pachli.core.database.model.StatusViewDataEntity +import app.pachli.core.database.model.TimelineAccountEntity +import app.pachli.core.database.model.TimelineStatusEntity +import app.pachli.core.database.model.TranslatedStatusEntity @Suppress("ClassName") @Database( diff --git a/app/src/main/java/app/pachli/db/Converters.kt b/core/database/src/main/kotlin/app/pachli/core/database/Converters.kt similarity index 86% rename from app/src/main/java/app/pachli/db/Converters.kt rename to core/database/src/main/kotlin/app/pachli/core/database/Converters.kt index 104791de8..1a0f5bf4d 100644 --- a/app/src/main/java/app/pachli/db/Converters.kt +++ b/core/database/src/main/kotlin/app/pachli/core/database/Converters.kt @@ -14,22 +14,22 @@ * see . */ -package app.pachli.db +package app.pachli.core.database import androidx.room.ProvidedTypeConverter import androidx.room.TypeConverter -import app.pachli.TabData -import app.pachli.components.conversation.ConversationAccountEntity -import app.pachli.createTabDataFromId -import app.pachli.entity.Attachment -import app.pachli.entity.Emoji -import app.pachli.entity.FilterResult -import app.pachli.entity.HashTag -import app.pachli.entity.NewPoll -import app.pachli.entity.Poll -import app.pachli.entity.Status -import app.pachli.entity.TranslatedAttachment -import app.pachli.entity.TranslatedPoll +import app.pachli.core.database.model.ConversationAccountEntity +import app.pachli.core.database.model.DraftAttachment +import app.pachli.core.database.model.TabData +import app.pachli.core.network.model.Attachment +import app.pachli.core.network.model.Emoji +import app.pachli.core.network.model.FilterResult +import app.pachli.core.network.model.HashTag +import app.pachli.core.network.model.NewPoll +import app.pachli.core.network.model.Poll +import app.pachli.core.network.model.Status +import app.pachli.core.network.model.TranslatedAttachment +import app.pachli.core.network.model.TranslatedPoll import com.google.gson.Gson import com.google.gson.reflect.TypeToken import java.net.URLDecoder @@ -69,14 +69,13 @@ class Converters @Inject constructor( return str?.split(";") ?.map { val data = it.split(":") - createTabDataFromId(data[0], data.drop(1).map { s -> URLDecoder.decode(s, "UTF-8") }) - } + TabData.from(data[0], data.drop(1).map { s -> URLDecoder.decode(s, "UTF-8") }) } } @TypeConverter fun tabDataToString(tabData: List?): String? { // List name may include ":" - return tabData?.joinToString(";") { it.id + ":" + it.arguments.joinToString(":") { s -> URLEncoder.encode(s, "UTF-8") } } + return tabData?.joinToString(";") { it.kind.repr + ":" + it.arguments.joinToString(":") { s -> URLEncoder.encode(s, "UTF-8") } } } @TypeConverter diff --git a/app/src/main/java/app/pachli/db/AccountDao.kt b/core/database/src/main/kotlin/app/pachli/core/database/dao/AccountDao.kt similarity index 90% rename from app/src/main/java/app/pachli/db/AccountDao.kt rename to core/database/src/main/kotlin/app/pachli/core/database/dao/AccountDao.kt index bd0b12ada..6f63924c7 100644 --- a/app/src/main/java/app/pachli/db/AccountDao.kt +++ b/core/database/src/main/kotlin/app/pachli/core/database/dao/AccountDao.kt @@ -1,4 +1,5 @@ -/* Copyright 2018 Conny Duck +/* + * Copyright 2018 Conny Duck * * This file is a part of Pachli. * @@ -14,13 +15,14 @@ * see . */ -package app.pachli.db +package app.pachli.core.database.dao import androidx.room.Dao import androidx.room.Delete import androidx.room.Insert import androidx.room.OnConflictStrategy import androidx.room.Query +import app.pachli.core.database.model.AccountEntity @Dao interface AccountDao { diff --git a/app/src/main/java/app/pachli/db/ConversationsDao.kt b/core/database/src/main/kotlin/app/pachli/core/database/dao/ConversationsDao.kt similarity index 92% rename from app/src/main/java/app/pachli/db/ConversationsDao.kt rename to core/database/src/main/kotlin/app/pachli/core/database/dao/ConversationsDao.kt index 1c9ccf336..df6fa81c1 100644 --- a/app/src/main/java/app/pachli/db/ConversationsDao.kt +++ b/core/database/src/main/kotlin/app/pachli/core/database/dao/ConversationsDao.kt @@ -1,4 +1,5 @@ -/* Copyright 2018 Conny Duck +/* + * Copyright 2018 Conny Duck * * This file is a part of Pachli. * @@ -14,14 +15,14 @@ * see . */ -package app.pachli.db +package app.pachli.core.database.dao import androidx.paging.PagingSource import androidx.room.Dao import androidx.room.Insert import androidx.room.OnConflictStrategy import androidx.room.Query -import app.pachli.components.conversation.ConversationEntity +import app.pachli.core.database.model.ConversationEntity @Dao interface ConversationsDao { diff --git a/app/src/main/java/app/pachli/db/DraftDao.kt b/core/database/src/main/kotlin/app/pachli/core/database/dao/DraftDao.kt similarity index 93% rename from app/src/main/java/app/pachli/db/DraftDao.kt rename to core/database/src/main/kotlin/app/pachli/core/database/dao/DraftDao.kt index 86b4fbf51..8058b4c9d 100644 --- a/app/src/main/java/app/pachli/db/DraftDao.kt +++ b/core/database/src/main/kotlin/app/pachli/core/database/dao/DraftDao.kt @@ -1,4 +1,5 @@ -/* Copyright 2020 Tusky Contributors +/* + * Copyright 2020 Tusky Contributors * * This file is a part of Pachli. * @@ -14,7 +15,7 @@ * see . */ -package app.pachli.db +package app.pachli.core.database.dao import androidx.lifecycle.LiveData import androidx.paging.PagingSource @@ -22,6 +23,7 @@ import androidx.room.Dao import androidx.room.Insert import androidx.room.OnConflictStrategy import androidx.room.Query +import app.pachli.core.database.model.DraftEntity @Dao interface DraftDao { diff --git a/app/src/main/java/app/pachli/db/InstanceDao.kt b/core/database/src/main/kotlin/app/pachli/core/database/dao/InstanceDao.kt similarity index 85% rename from app/src/main/java/app/pachli/db/InstanceDao.kt rename to core/database/src/main/kotlin/app/pachli/core/database/dao/InstanceDao.kt index cc5c596e1..d451d3bc5 100644 --- a/app/src/main/java/app/pachli/db/InstanceDao.kt +++ b/core/database/src/main/kotlin/app/pachli/core/database/dao/InstanceDao.kt @@ -1,4 +1,5 @@ -/* Copyright 2018 Conny Duck +/* + * Copyright 2018 Conny Duck * * This file is a part of Pachli. * @@ -14,12 +15,15 @@ * see . */ -package app.pachli.db +package app.pachli.core.database.dao import androidx.room.Dao import androidx.room.Query import androidx.room.RewriteQueriesToDropUnusedColumns import androidx.room.Upsert +import app.pachli.core.database.model.EmojisEntity +import app.pachli.core.database.model.InstanceEntity +import app.pachli.core.database.model.InstanceInfoEntity @Dao interface InstanceDao { diff --git a/app/src/main/java/app/pachli/db/RemoteKeyDao.kt b/core/database/src/main/kotlin/app/pachli/core/database/dao/RemoteKeyDao.kt similarity index 91% rename from app/src/main/java/app/pachli/db/RemoteKeyDao.kt rename to core/database/src/main/kotlin/app/pachli/core/database/dao/RemoteKeyDao.kt index ca382fcd4..41fe2f1c4 100644 --- a/app/src/main/java/app/pachli/db/RemoteKeyDao.kt +++ b/core/database/src/main/kotlin/app/pachli/core/database/dao/RemoteKeyDao.kt @@ -15,12 +15,14 @@ * see . */ -package app.pachli.db +package app.pachli.core.database.dao import androidx.room.Dao import androidx.room.Insert import androidx.room.OnConflictStrategy import androidx.room.Query +import app.pachli.core.database.model.RemoteKeyEntity +import app.pachli.core.database.model.RemoteKeyKind @Dao interface RemoteKeyDao { diff --git a/app/src/main/java/app/pachli/db/TimelineDao.kt b/core/database/src/main/kotlin/app/pachli/core/database/dao/TimelineDao.kt similarity index 97% rename from app/src/main/java/app/pachli/db/TimelineDao.kt rename to core/database/src/main/kotlin/app/pachli/core/database/dao/TimelineDao.kt index 3bde32be3..35cf0df2e 100644 --- a/app/src/main/java/app/pachli/db/TimelineDao.kt +++ b/core/database/src/main/kotlin/app/pachli/core/database/dao/TimelineDao.kt @@ -1,4 +1,5 @@ -/* Copyright 2021 Tusky Contributors +/* + * Copyright 2021 Tusky Contributors * * This file is a part of Pachli. * @@ -14,7 +15,7 @@ * see . */ -package app.pachli.db +package app.pachli.core.database.dao import androidx.paging.PagingSource import androidx.room.Dao @@ -23,6 +24,10 @@ import androidx.room.MapInfo import androidx.room.OnConflictStrategy.Companion.REPLACE import androidx.room.Query import androidx.room.Upsert +import app.pachli.core.database.model.StatusViewDataEntity +import app.pachli.core.database.model.TimelineAccountEntity +import app.pachli.core.database.model.TimelineStatusEntity +import app.pachli.core.database.model.TimelineStatusWithAccount @Dao abstract class TimelineDao { diff --git a/app/src/main/java/app/pachli/db/TranslatedStatusDao.kt b/core/database/src/main/kotlin/app/pachli/core/database/dao/TranslatedStatusDao.kt similarity index 90% rename from app/src/main/java/app/pachli/db/TranslatedStatusDao.kt rename to core/database/src/main/kotlin/app/pachli/core/database/dao/TranslatedStatusDao.kt index 2fdf1b61e..ab2607dff 100644 --- a/app/src/main/java/app/pachli/db/TranslatedStatusDao.kt +++ b/core/database/src/main/kotlin/app/pachli/core/database/dao/TranslatedStatusDao.kt @@ -15,10 +15,11 @@ * see . */ -package app.pachli.db +package app.pachli.core.database.dao import androidx.room.Dao import androidx.room.Upsert +import app.pachli.core.database.model.TranslatedStatusEntity @Dao interface TranslatedStatusDao { diff --git a/app/src/main/java/app/pachli/di/DatabaseModule.kt b/core/database/src/main/kotlin/app/pachli/core/database/di/DatabaseModule.kt similarity index 96% rename from app/src/main/java/app/pachli/di/DatabaseModule.kt rename to core/database/src/main/kotlin/app/pachli/core/database/di/DatabaseModule.kt index f6e37731d..df2afae66 100644 --- a/app/src/main/java/app/pachli/di/DatabaseModule.kt +++ b/core/database/src/main/kotlin/app/pachli/core/database/di/DatabaseModule.kt @@ -15,13 +15,13 @@ * see . */ -package app.pachli.di +package app.pachli.core.database.di import android.content.Context import androidx.room.Room import androidx.room.withTransaction -import app.pachli.db.AppDatabase -import app.pachli.db.Converters +import app.pachli.core.database.AppDatabase +import app.pachli.core.database.Converters import dagger.Module import dagger.Provides import dagger.hilt.InstallIn diff --git a/app/src/main/java/app/pachli/db/AccountEntity.kt b/core/database/src/main/kotlin/app/pachli/core/database/model/AccountEntity.kt similarity index 96% rename from app/src/main/java/app/pachli/db/AccountEntity.kt rename to core/database/src/main/kotlin/app/pachli/core/database/model/AccountEntity.kt index 34e9c8eea..a8a630f49 100644 --- a/app/src/main/java/app/pachli/db/AccountEntity.kt +++ b/core/database/src/main/kotlin/app/pachli/core/database/model/AccountEntity.kt @@ -1,4 +1,5 @@ -/* Copyright 2018 Conny Duck +/* + * Copyright 2018 Conny Duck * * This file is a part of Pachli. * @@ -14,17 +15,16 @@ * see . */ -package app.pachli.db +package app.pachli.core.database.model import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.Index import androidx.room.PrimaryKey import androidx.room.TypeConverters -import app.pachli.TabData -import app.pachli.defaultTabs -import app.pachli.entity.Emoji -import app.pachli.entity.Status +import app.pachli.core.database.Converters +import app.pachli.core.network.model.Emoji +import app.pachli.core.network.model.Status @Entity( indices = [ diff --git a/app/src/main/java/app/pachli/components/conversation/ConversationEntity.kt b/core/database/src/main/kotlin/app/pachli/core/database/model/ConversationEntity.kt similarity index 91% rename from app/src/main/java/app/pachli/components/conversation/ConversationEntity.kt rename to core/database/src/main/kotlin/app/pachli/core/database/model/ConversationEntity.kt index d71593ad4..5f4e5285e 100644 --- a/app/src/main/java/app/pachli/components/conversation/ConversationEntity.kt +++ b/core/database/src/main/kotlin/app/pachli/core/database/model/ConversationEntity.kt @@ -1,4 +1,5 @@ -/* Copyright 2021 Tusky Contributors +/* + * Copyright 2021 Tusky Contributors * * This file is a part of Pachli. * @@ -14,19 +15,19 @@ * see . */ -package app.pachli.components.conversation +package app.pachli.core.database.model import androidx.room.Embedded import androidx.room.Entity import androidx.room.TypeConverters -import app.pachli.db.Converters -import app.pachli.entity.Attachment -import app.pachli.entity.Conversation -import app.pachli.entity.Emoji -import app.pachli.entity.HashTag -import app.pachli.entity.Poll -import app.pachli.entity.Status -import app.pachli.entity.TimelineAccount +import app.pachli.core.database.Converters +import app.pachli.core.network.model.Attachment +import app.pachli.core.network.model.Conversation +import app.pachli.core.network.model.Emoji +import app.pachli.core.network.model.HashTag +import app.pachli.core.network.model.Poll +import app.pachli.core.network.model.Status +import app.pachli.core.network.model.TimelineAccount import java.util.Date @Entity(primaryKeys = ["id", "accountId"]) diff --git a/app/src/main/java/app/pachli/db/DraftEntity.kt b/core/database/src/main/kotlin/app/pachli/core/database/model/DraftEntity.kt similarity index 89% rename from app/src/main/java/app/pachli/db/DraftEntity.kt rename to core/database/src/main/kotlin/app/pachli/core/database/model/DraftEntity.kt index 5fb584578..1d75b2636 100644 --- a/app/src/main/java/app/pachli/db/DraftEntity.kt +++ b/core/database/src/main/kotlin/app/pachli/core/database/model/DraftEntity.kt @@ -1,4 +1,5 @@ -/* Copyright 2020 Tusky Contributors +/* + * Copyright 2020 Tusky Contributors * * This file is a part of Pachli. * @@ -14,7 +15,7 @@ * see . */ -package app.pachli.db +package app.pachli.core.database.model import android.net.Uri import android.os.Parcelable @@ -22,9 +23,10 @@ import androidx.core.net.toUri import androidx.room.Entity import androidx.room.PrimaryKey import androidx.room.TypeConverters -import app.pachli.entity.Attachment -import app.pachli.entity.NewPoll -import app.pachli.entity.Status +import app.pachli.core.database.Converters +import app.pachli.core.network.model.Attachment +import app.pachli.core.network.model.NewPoll +import app.pachli.core.network.model.Status import com.google.gson.annotations.SerializedName import kotlinx.parcelize.Parcelize diff --git a/app/src/main/java/app/pachli/db/InstanceEntity.kt b/core/database/src/main/kotlin/app/pachli/core/database/model/InstanceEntity.kt similarity index 92% rename from app/src/main/java/app/pachli/db/InstanceEntity.kt rename to core/database/src/main/kotlin/app/pachli/core/database/model/InstanceEntity.kt index 6d54d5f7e..c0a6bd979 100644 --- a/app/src/main/java/app/pachli/db/InstanceEntity.kt +++ b/core/database/src/main/kotlin/app/pachli/core/database/model/InstanceEntity.kt @@ -1,4 +1,5 @@ -/* Copyright 2018 Conny Duck +/* + * Copyright 2018 Conny Duck * * This file is a part of Pachli. * @@ -14,12 +15,13 @@ * see . */ -package app.pachli.db +package app.pachli.core.database.model import androidx.room.Entity import androidx.room.PrimaryKey import androidx.room.TypeConverters -import app.pachli.entity.Emoji +import app.pachli.core.database.Converters +import app.pachli.core.network.model.Emoji @Entity @TypeConverters(Converters::class) diff --git a/app/src/main/java/app/pachli/db/RemoteKeyEntity.kt b/core/database/src/main/kotlin/app/pachli/core/database/model/RemoteKeyEntity.kt similarity index 97% rename from app/src/main/java/app/pachli/db/RemoteKeyEntity.kt rename to core/database/src/main/kotlin/app/pachli/core/database/model/RemoteKeyEntity.kt index e38dd1195..a60c62c7d 100644 --- a/app/src/main/java/app/pachli/db/RemoteKeyEntity.kt +++ b/core/database/src/main/kotlin/app/pachli/core/database/model/RemoteKeyEntity.kt @@ -15,7 +15,7 @@ * see . */ -package app.pachli.db +package app.pachli.core.database.model import androidx.room.Entity diff --git a/core/database/src/main/kotlin/app/pachli/core/database/model/TabData.kt b/core/database/src/main/kotlin/app/pachli/core/database/model/TabData.kt new file mode 100644 index 000000000..ec245cd75 --- /dev/null +++ b/core/database/src/main/kotlin/app/pachli/core/database/model/TabData.kt @@ -0,0 +1,56 @@ +/* + * Copyright 2023 Pachli Association + * + * This file is a part of Pachli. + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Pachli; if not, + * see . + */ + +package app.pachli.core.database.model + +/** + * A tab's kind. + * + * @param repr String representation of the tab in the database + */ +enum class TabKind(val repr: String) { + HOME("Home"), + NOTIFICATIONS("Notifications"), + LOCAL("Local"), + FEDERATED("Federated"), + DIRECT("Direct"), + TRENDING_TAGS("TrendingTags"), + TRENDING_LINKS("TrendingLinks"), + TRENDING_STATUSES("TrendingStatuses"), + HASHTAG("Hashtag"), + LIST("List"), + BOOKMARKS("Bookmarks") +} + +/** this would be a good case for a sealed class, but that does not work nice with Room */ + +data class TabData(val kind: TabKind, val arguments: List = emptyList()) { + companion object { + fun from(kind: TabKind, arguments: List = emptyList()) = + TabData(kind, arguments) + + fun from(kind: String, arguments: List = emptyList()) = + TabData(TabKind.valueOf(kind.uppercase()), arguments) + } +} + +fun defaultTabs() = listOf( + TabData.from(TabKind.HOME), + TabData.from(TabKind.NOTIFICATIONS), + TabData.from(TabKind.LOCAL), + TabData.from(TabKind.DIRECT) +) diff --git a/app/src/main/java/app/pachli/db/TimelineStatusEntity.kt b/core/database/src/main/kotlin/app/pachli/core/database/model/TimelineStatusEntity.kt similarity index 94% rename from app/src/main/java/app/pachli/db/TimelineStatusEntity.kt rename to core/database/src/main/kotlin/app/pachli/core/database/model/TimelineStatusEntity.kt index 93238fdce..789b526d9 100644 --- a/app/src/main/java/app/pachli/db/TimelineStatusEntity.kt +++ b/core/database/src/main/kotlin/app/pachli/core/database/model/TimelineStatusEntity.kt @@ -1,4 +1,5 @@ -/* Copyright 2021 Tusky Contributors +/* + * Copyright 2021 Tusky Contributors * * This file is a part of Pachli. * @@ -14,7 +15,7 @@ * see . */ -package app.pachli.db +package app.pachli.core.database.model import androidx.room.ColumnInfo import androidx.room.Embedded @@ -22,15 +23,15 @@ import androidx.room.Entity import androidx.room.ForeignKey import androidx.room.Index import androidx.room.TypeConverters -import app.pachli.entity.Attachment -import app.pachli.entity.Card -import app.pachli.entity.Emoji -import app.pachli.entity.FilterResult -import app.pachli.entity.HashTag -import app.pachli.entity.Poll -import app.pachli.entity.Status -import app.pachli.entity.TimelineAccount -import app.pachli.viewdata.TranslationState +import app.pachli.core.database.Converters +import app.pachli.core.network.model.Attachment +import app.pachli.core.network.model.Card +import app.pachli.core.network.model.Emoji +import app.pachli.core.network.model.FilterResult +import app.pachli.core.network.model.HashTag +import app.pachli.core.network.model.Poll +import app.pachli.core.network.model.Status +import app.pachli.core.network.model.TimelineAccount import com.google.gson.Gson import com.google.gson.reflect.TypeToken import java.lang.reflect.Type @@ -176,6 +177,17 @@ data class TimelineAccountEntity( } } +enum class TranslationState { + /** Show the original, untranslated status */ + SHOW_ORIGINAL, + + /** Show the original, untranslated status, but translation is happening */ + TRANSLATING, + + /** Show the translated status */ + SHOW_TRANSLATION, +} + /** * The local view data for a status. * diff --git a/app/src/main/java/app/pachli/db/TranslatedStatusEntity.kt b/core/database/src/main/kotlin/app/pachli/core/database/model/TranslatedStatusEntity.kt similarity index 92% rename from app/src/main/java/app/pachli/db/TranslatedStatusEntity.kt rename to core/database/src/main/kotlin/app/pachli/core/database/model/TranslatedStatusEntity.kt index a4ccd9ec9..f1cb04ead 100644 --- a/app/src/main/java/app/pachli/db/TranslatedStatusEntity.kt +++ b/core/database/src/main/kotlin/app/pachli/core/database/model/TranslatedStatusEntity.kt @@ -15,13 +15,13 @@ * see . */ -package app.pachli.db +package app.pachli.core.database.model import androidx.room.Entity import androidx.room.TypeConverters -import app.pachli.entity.Status -import app.pachli.entity.TranslatedAttachment -import app.pachli.entity.TranslatedPoll +import app.pachli.core.database.Converters +import app.pachli.core.network.model.TranslatedAttachment +import app.pachli.core.network.model.TranslatedPoll /** * Translated version of a status, see https://docs.joinmastodon.org/entities/Translation/. diff --git a/app/src/test/java/app/pachli/db/TimelineDaoTest.kt b/core/database/src/test/kotlin/app/pachli/core/database/dao/TimelineDaoTest.kt similarity index 90% rename from app/src/test/java/app/pachli/db/TimelineDaoTest.kt rename to core/database/src/test/kotlin/app/pachli/core/database/dao/TimelineDaoTest.kt index ef0c38989..bf59cccbc 100644 --- a/app/src/test/java/app/pachli/db/TimelineDaoTest.kt +++ b/core/database/src/test/kotlin/app/pachli/core/database/dao/TimelineDaoTest.kt @@ -1,36 +1,54 @@ -package app.pachli.db +/* + * Copyright 2023 Pachli Association + * + * This file is a part of Pachli. + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Pachli; if not, + * see . + */ + +package app.pachli.core.database.dao import androidx.paging.PagingSource -import androidx.room.Room import androidx.test.ext.junit.runners.AndroidJUnit4 -import androidx.test.platform.app.InstrumentationRegistry -import app.pachli.entity.Status -import com.google.gson.Gson +import app.pachli.core.database.AppDatabase +import app.pachli.core.database.model.TimelineAccountEntity +import app.pachli.core.database.model.TimelineStatusEntity +import app.pachli.core.database.model.TimelineStatusWithAccount +import app.pachli.core.network.model.Status +import dagger.hilt.android.testing.HiltAndroidRule +import dagger.hilt.android.testing.HiltAndroidTest import kotlinx.coroutines.runBlocking -import org.junit.After import org.junit.Assert.assertEquals import org.junit.Before +import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith +import javax.inject.Inject +@HiltAndroidTest @RunWith(AndroidJUnit4::class) class TimelineDaoTest { - private lateinit var timelineDao: TimelineDao - private lateinit var db: AppDatabase + @get:Rule(order = 0) + var hilt = HiltAndroidRule(this) + + @Inject + lateinit var db: AppDatabase + + @Inject + lateinit var timelineDao: TimelineDao @Before - fun createDb() { - val context = InstrumentationRegistry.getInstrumentation().targetContext - db = Room.inMemoryDatabaseBuilder(context, AppDatabase::class.java) - .addTypeConverter(Converters(Gson())) - .allowMainThreadQueries() - .build() - timelineDao = db.timelineDao() - } - - @After - fun closeDb() { - db.close() + fun setup() { + hilt.inject() } @Test diff --git a/app/src/test/java/app/pachli/di/FakeDatabaseModule.kt b/core/database/src/test/kotlin/app/pachli/core/database/di/FakeDatabaseModule.kt similarity index 94% rename from app/src/test/java/app/pachli/di/FakeDatabaseModule.kt rename to core/database/src/test/kotlin/app/pachli/core/database/di/FakeDatabaseModule.kt index 9fee3a4e6..81d5b1d18 100644 --- a/app/src/test/java/app/pachli/di/FakeDatabaseModule.kt +++ b/core/database/src/test/kotlin/app/pachli/core/database/di/FakeDatabaseModule.kt @@ -15,12 +15,12 @@ * see . */ -package app.pachli.di +package app.pachli.core.database.di import androidx.room.Room import androidx.test.platform.app.InstrumentationRegistry -import app.pachli.db.AppDatabase -import app.pachli.db.Converters +import app.pachli.core.database.AppDatabase +import app.pachli.core.database.Converters import com.google.gson.Gson import dagger.Module import dagger.Provides diff --git a/core/database/src/test/resources/robolectric.properties b/core/database/src/test/resources/robolectric.properties new file mode 100644 index 000000000..0b006d1c0 --- /dev/null +++ b/core/database/src/test/resources/robolectric.properties @@ -0,0 +1,21 @@ +# +# Copyright 2023 Pachli Association +# +# This file is a part of Pachli. +# +# This program is free software; you can redistribute it and/or modify it under the terms of the +# GNU General Public License as published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even +# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along with Pachli; if not, +# see . +# + +# Robolectric does not support SDK 34 yet +# https://github.com/robolectric/robolectric/issues/8404 +sdk=33 +application = dagger.hilt.android.testing.HiltTestApplication diff --git a/core/network/build.gradle.kts b/core/network/build.gradle.kts new file mode 100644 index 000000000..f14908ca2 --- /dev/null +++ b/core/network/build.gradle.kts @@ -0,0 +1,44 @@ +/* + * Copyright 2023 Pachli Association + * + * This file is a part of Pachli. + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Pachli; if not, + * see . + */ + +plugins { + alias(libs.plugins.pachli.android.library) + alias(libs.plugins.pachli.android.hilt) + alias(libs.plugins.kotlin.parcelize) +} + +android { + namespace = "app.pachli.core.network" + + defaultConfig { + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } +} + +dependencies { + implementation(projects.core.common) + implementation(projects.core.preferences) + + implementation(libs.gson) + implementation(libs.bundles.retrofit) + implementation(libs.bundles.okhttp) + implementation(libs.kotlin.result) + implementation(libs.networkresult.calladapter) + implementation(libs.semver) + + testImplementation(libs.mockwebserver) +} diff --git a/core/network/lint-baseline.xml b/core/network/lint-baseline.xml new file mode 100644 index 000000000..f93456288 --- /dev/null +++ b/core/network/lint-baseline.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + diff --git a/core/network/proguard-rules.pro b/core/network/proguard-rules.pro new file mode 100644 index 000000000..2f9dc5a47 --- /dev/null +++ b/core/network/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle.kts. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/core/network/src/main/AndroidManifest.xml b/core/network/src/main/AndroidManifest.xml new file mode 100644 index 000000000..76e9ba6e7 --- /dev/null +++ b/core/network/src/main/AndroidManifest.xml @@ -0,0 +1,21 @@ + + + + + + diff --git a/app/src/main/java/app/pachli/network/Operations.kt b/core/network/src/main/kotlin/app/pachli/core/network/Operations.kt similarity index 97% rename from app/src/main/java/app/pachli/network/Operations.kt rename to core/network/src/main/kotlin/app/pachli/core/network/Operations.kt index 214f1b972..0479a0208 100644 --- a/app/src/main/java/app/pachli/network/Operations.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/Operations.kt @@ -15,11 +15,11 @@ * see . */ -package app.pachli.network +package app.pachli.core.network -import app.pachli.entity.InstanceV1 -import app.pachli.network.ServerKind.MASTODON -import app.pachli.network.model.InstanceV2 +import app.pachli.core.network.ServerKind.MASTODON +import app.pachli.core.network.model.InstanceV1 +import app.pachli.core.network.model.InstanceV2 import com.github.michaelbull.result.Err import com.github.michaelbull.result.Ok import com.github.michaelbull.result.Result diff --git a/app/src/main/java/app/pachli/util/StatusParsingHelper.kt b/core/network/src/main/kotlin/app/pachli/core/network/StatusParsingHelper.kt similarity index 94% rename from app/src/main/java/app/pachli/util/StatusParsingHelper.kt rename to core/network/src/main/kotlin/app/pachli/core/network/StatusParsingHelper.kt index a50cc6474..c3d920c08 100644 --- a/app/src/main/java/app/pachli/util/StatusParsingHelper.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/StatusParsingHelper.kt @@ -1,4 +1,5 @@ -/* Copyright 2022 Tusky Contributors +/* + * Copyright 2022 Tusky Contributors * * This file is a part of Pachli. * @@ -14,12 +15,13 @@ * see . */ -package app.pachli.util +package app.pachli.core.network import android.text.Html.TagHandler import android.text.SpannableStringBuilder import android.text.Spanned import androidx.core.text.parseAsHtml +import app.pachli.core.common.string.trimTrailingWhitespace /** * parse a String containing html from the Mastodon api to Spanned diff --git a/app/src/main/java/app/pachli/di/MastodonApiModule.kt b/core/network/src/main/kotlin/app/pachli/core/network/di/MastodonApiModule.kt similarity index 92% rename from app/src/main/java/app/pachli/di/MastodonApiModule.kt rename to core/network/src/main/kotlin/app/pachli/core/network/di/MastodonApiModule.kt index fd257d95a..043f64825 100644 --- a/app/src/main/java/app/pachli/di/MastodonApiModule.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/di/MastodonApiModule.kt @@ -15,9 +15,9 @@ * see . */ -package app.pachli.di +package app.pachli.core.network.di -import app.pachli.network.MastodonApi +import app.pachli.core.network.retrofit.MastodonApi import dagger.Module import dagger.Provides import dagger.hilt.InstallIn diff --git a/app/src/main/java/app/pachli/di/NetworkModule.kt b/core/network/src/main/kotlin/app/pachli/core/network/di/NetworkModule.kt similarity index 78% rename from app/src/main/java/app/pachli/di/NetworkModule.kt rename to core/network/src/main/kotlin/app/pachli/core/network/di/NetworkModule.kt index 47f8cd003..2f47759ec 100644 --- a/app/src/main/java/app/pachli/di/NetworkModule.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/di/NetworkModule.kt @@ -1,4 +1,5 @@ -/* Copyright 2018 charlag +/* + * Copyright 2018 charlag * * This file is a part of Pachli. * @@ -14,22 +15,22 @@ * see . */ -package app.pachli.di +package app.pachli.core.network.di import android.content.Context +import android.content.pm.PackageManager import android.os.Build -import app.pachli.BuildConfig -import app.pachli.db.AccountManager -import app.pachli.json.Rfc3339DateJsonAdapter -import app.pachli.network.InstanceSwitchAuthInterceptor -import app.pachli.network.MastodonApi -import app.pachli.network.MediaUploadApi -import app.pachli.settings.PrefKeys.HTTP_PROXY_ENABLED -import app.pachli.settings.PrefKeys.HTTP_PROXY_PORT -import app.pachli.settings.PrefKeys.HTTP_PROXY_SERVER -import app.pachli.settings.ProxyConfiguration -import app.pachli.util.SharedPreferencesRepository -import app.pachli.util.getNonNullString +import app.pachli.core.mastodon.model.MediaUploadApi +import app.pachli.core.network.BuildConfig +import app.pachli.core.network.json.Rfc3339DateJsonAdapter +import app.pachli.core.network.retrofit.InstanceSwitchAuthInterceptor +import app.pachli.core.network.retrofit.MastodonApi +import app.pachli.core.preferences.PrefKeys.HTTP_PROXY_ENABLED +import app.pachli.core.preferences.PrefKeys.HTTP_PROXY_PORT +import app.pachli.core.preferences.PrefKeys.HTTP_PROXY_SERVER +import app.pachli.core.preferences.ProxyConfiguration +import app.pachli.core.preferences.SharedPreferencesRepository +import app.pachli.core.preferences.getNonNullString import at.connyduck.calladapter.networkresult.NetworkResultCallAdapterFactory import com.google.gson.Gson import com.google.gson.GsonBuilder @@ -66,10 +67,15 @@ object NetworkModule { @Provides @Singleton fun providesHttpClient( - accountManager: AccountManager, @ApplicationContext context: Context, preferences: SharedPreferencesRepository, + instanceSwitchAuthInterceptor: InstanceSwitchAuthInterceptor, ): OkHttpClient { + val versionName = try { + context.packageManager.getPackageInfo(context.packageName, 0).versionName + } catch (e: PackageManager.NameNotFoundException) { + "unknown" + } val httpProxyEnabled = preferences.getBoolean(HTTP_PROXY_ENABLED, false) val httpServer = preferences.getNonNullString(HTTP_PROXY_SERVER, "") val httpPort = preferences.getNonNullString(HTTP_PROXY_PORT, "-1").toIntOrNull() ?: -1 @@ -84,7 +90,7 @@ object NetworkModule { val requestWithUserAgent = chain.request().newBuilder() .header( "User-Agent", - "Pachli/${BuildConfig.VERSION_NAME} Android/${Build.VERSION.RELEASE} OkHttp/${OkHttp.VERSION}", + "Pachli/$versionName Android/${Build.VERSION.RELEASE} OkHttp/${OkHttp.VERSION}", ) .build() chain.proceed(requestWithUserAgent) @@ -102,7 +108,7 @@ object NetworkModule { return builder .apply { - addInterceptor(InstanceSwitchAuthInterceptor(accountManager)) + addInterceptor(instanceSwitchAuthInterceptor) if (BuildConfig.DEBUG) { addInterceptor(HttpLoggingInterceptor().apply { level = HttpLoggingInterceptor.Level.BASIC }) } diff --git a/app/src/main/java/app/pachli/json/GuardedBooleanAdapter.kt b/core/network/src/main/kotlin/app/pachli/core/network/json/GuardedBooleanAdapter.kt similarity index 97% rename from app/src/main/java/app/pachli/json/GuardedBooleanAdapter.kt rename to core/network/src/main/kotlin/app/pachli/core/network/json/GuardedBooleanAdapter.kt index eca938121..dab1191d1 100644 --- a/app/src/main/java/app/pachli/json/GuardedBooleanAdapter.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/json/GuardedBooleanAdapter.kt @@ -14,7 +14,7 @@ * see . */ -package app.pachli.json +package app.pachli.core.network.json import com.google.gson.JsonDeserializationContext import com.google.gson.JsonDeserializer diff --git a/app/src/main/java/app/pachli/json/Iso8601Utils.kt b/core/network/src/main/kotlin/app/pachli/core/network/json/Iso8601Utils.kt similarity index 93% rename from app/src/main/java/app/pachli/json/Iso8601Utils.kt rename to core/network/src/main/kotlin/app/pachli/core/network/json/Iso8601Utils.kt index c0167b985..0176eae78 100644 --- a/app/src/main/java/app/pachli/json/Iso8601Utils.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/json/Iso8601Utils.kt @@ -1,4 +1,21 @@ -package app.pachli.json +/* + * Copyright 2023 Pachli Association + * + * This file is a part of Pachli. + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Pachli; if not, + * see . + */ + +package app.pachli.core.network.json /* * Copyright (C) 2011 FasterXML, LLC diff --git a/app/src/main/java/app/pachli/json/Rfc3339DateJsonAdapter.kt b/core/network/src/main/kotlin/app/pachli/core/network/json/Rfc3339DateJsonAdapter.kt similarity index 97% rename from app/src/main/java/app/pachli/json/Rfc3339DateJsonAdapter.kt rename to core/network/src/main/kotlin/app/pachli/core/network/json/Rfc3339DateJsonAdapter.kt index 8919f15cc..c0ef5c044 100644 --- a/app/src/main/java/app/pachli/json/Rfc3339DateJsonAdapter.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/json/Rfc3339DateJsonAdapter.kt @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package app.pachli.json +package app.pachli.core.network.json import com.google.gson.JsonParseException import com.google.gson.TypeAdapter diff --git a/app/src/main/java/app/pachli/entity/AccessToken.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/AccessToken.kt similarity index 91% rename from app/src/main/java/app/pachli/entity/AccessToken.kt rename to core/network/src/main/kotlin/app/pachli/core/network/model/AccessToken.kt index 40b287824..3e3ab48af 100644 --- a/app/src/main/java/app/pachli/entity/AccessToken.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/model/AccessToken.kt @@ -1,4 +1,5 @@ -/* Copyright 2017 Andrew Dawson +/* + * Copyright 2017 Andrew Dawson * * This file is a part of Pachli. * @@ -14,7 +15,7 @@ * see . */ -package app.pachli.entity +package app.pachli.core.network.model import com.google.gson.annotations.SerializedName diff --git a/app/src/main/java/app/pachli/entity/Account.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/Account.kt similarity index 98% rename from app/src/main/java/app/pachli/entity/Account.kt rename to core/network/src/main/kotlin/app/pachli/core/network/model/Account.kt index acd893cd6..63a7d0628 100644 --- a/app/src/main/java/app/pachli/entity/Account.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/model/Account.kt @@ -14,7 +14,7 @@ * see . */ -package app.pachli.entity +package app.pachli.core.network.model import com.google.gson.annotations.SerializedName import java.util.Date diff --git a/app/src/main/java/app/pachli/entity/Announcement.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/Announcement.kt similarity index 97% rename from app/src/main/java/app/pachli/entity/Announcement.kt rename to core/network/src/main/kotlin/app/pachli/core/network/model/Announcement.kt index 3fc442822..b762c2497 100644 --- a/app/src/main/java/app/pachli/entity/Announcement.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/model/Announcement.kt @@ -14,7 +14,7 @@ * see . */ -package app.pachli.entity +package app.pachli.core.network.model import com.google.gson.annotations.SerializedName import java.util.Date diff --git a/app/src/main/java/app/pachli/entity/AppCredentials.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/AppCredentials.kt similarity index 95% rename from app/src/main/java/app/pachli/entity/AppCredentials.kt rename to core/network/src/main/kotlin/app/pachli/core/network/model/AppCredentials.kt index 96ddc9c96..fcf1e7c3c 100644 --- a/app/src/main/java/app/pachli/entity/AppCredentials.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/model/AppCredentials.kt @@ -14,7 +14,7 @@ * see . */ -package app.pachli.entity +package app.pachli.core.network.model import com.google.gson.annotations.SerializedName diff --git a/app/src/main/java/app/pachli/entity/Attachment.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/Attachment.kt similarity index 86% rename from app/src/main/java/app/pachli/entity/Attachment.kt rename to core/network/src/main/kotlin/app/pachli/core/network/model/Attachment.kt index 65a5ee59a..05044f312 100644 --- a/app/src/main/java/app/pachli/entity/Attachment.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/model/Attachment.kt @@ -1,4 +1,5 @@ -/* Copyright 2017 Andrew Dawson +/* + * Copyright 2017 Andrew Dawson * * This file is a part of Pachli. * @@ -14,11 +15,9 @@ * see . */ -package app.pachli.entity +package app.pachli.core.network.model import android.os.Parcelable -import androidx.annotation.DrawableRes -import app.pachli.R import com.google.gson.JsonDeserializationContext import com.google.gson.JsonDeserializer import com.google.gson.JsonElement @@ -56,15 +55,6 @@ data class Attachment( UNKNOWN, } - /** @return a drawable resource for an icon to indicate the attachment type */ - @DrawableRes - fun iconResource() = when (this.type) { - Type.IMAGE -> R.drawable.ic_photo_24dp - Type.GIFV, Type.VIDEO -> R.drawable.ic_videocam_24dp - Type.AUDIO -> R.drawable.ic_music_box_24dp - Type.UNKNOWN -> R.drawable.ic_attach_file_24dp - } - class MediaTypeDeserializer : JsonDeserializer { @Throws(JsonParseException::class) override fun deserialize(json: JsonElement, classOfT: java.lang.reflect.Type, context: JsonDeserializationContext): Type { diff --git a/app/src/main/java/app/pachli/entity/Card.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/Card.kt similarity index 95% rename from app/src/main/java/app/pachli/entity/Card.kt rename to core/network/src/main/kotlin/app/pachli/core/network/model/Card.kt index 1ed836aa3..0bb9b02d4 100644 --- a/app/src/main/java/app/pachli/entity/Card.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/model/Card.kt @@ -1,4 +1,5 @@ -/* Copyright 2017 Andrew Dawson +/* + * Copyright 2017 Andrew Dawson * * This file is a part of Pachli. * @@ -14,7 +15,7 @@ * see . */ -package app.pachli.entity +package app.pachli.core.network.model import com.google.gson.annotations.SerializedName diff --git a/app/src/main/java/app/pachli/entity/Conversation.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/Conversation.kt similarity index 96% rename from app/src/main/java/app/pachli/entity/Conversation.kt rename to core/network/src/main/kotlin/app/pachli/core/network/model/Conversation.kt index 03e178e93..86225a3b6 100644 --- a/app/src/main/java/app/pachli/entity/Conversation.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/model/Conversation.kt @@ -14,7 +14,7 @@ * see . */ -package app.pachli.entity +package app.pachli.core.network.model import com.google.gson.annotations.SerializedName diff --git a/app/src/main/java/app/pachli/entity/DeletedStatus.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/DeletedStatus.kt similarity index 97% rename from app/src/main/java/app/pachli/entity/DeletedStatus.kt rename to core/network/src/main/kotlin/app/pachli/core/network/model/DeletedStatus.kt index 7c9860ef8..917f90e9b 100644 --- a/app/src/main/java/app/pachli/entity/DeletedStatus.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/model/DeletedStatus.kt @@ -14,7 +14,7 @@ * see . */ -package app.pachli.entity +package app.pachli.core.network.model import com.google.gson.annotations.SerializedName import java.util.Date diff --git a/app/src/main/java/app/pachli/entity/Emoji.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/Emoji.kt similarity index 96% rename from app/src/main/java/app/pachli/entity/Emoji.kt rename to core/network/src/main/kotlin/app/pachli/core/network/model/Emoji.kt index ed00b068f..cd8e4a3dc 100644 --- a/app/src/main/java/app/pachli/entity/Emoji.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/model/Emoji.kt @@ -14,7 +14,7 @@ * see . */ -package app.pachli.entity +package app.pachli.core.network.model import android.os.Parcelable import com.google.gson.annotations.SerializedName diff --git a/app/src/main/java/app/pachli/entity/Error.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/Error.kt similarity index 95% rename from app/src/main/java/app/pachli/entity/Error.kt rename to core/network/src/main/kotlin/app/pachli/core/network/model/Error.kt index 420b2b0e4..8c666197e 100644 --- a/app/src/main/java/app/pachli/entity/Error.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/model/Error.kt @@ -15,7 +15,7 @@ * see . */ -package app.pachli.entity +package app.pachli.core.network.model /** @see [Error](https://docs.joinmastodon.org/entities/Error/) */ data class Error( diff --git a/app/src/main/java/app/pachli/entity/Filter.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/Filter.kt similarity index 97% rename from app/src/main/java/app/pachli/entity/Filter.kt rename to core/network/src/main/kotlin/app/pachli/core/network/model/Filter.kt index c5764dff4..6ab473d93 100644 --- a/app/src/main/java/app/pachli/entity/Filter.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/model/Filter.kt @@ -1,4 +1,4 @@ -package app.pachli.entity +package app.pachli.core.network.model import android.os.Parcelable import app.pachli.components.timeline.TimelineKind diff --git a/app/src/main/java/app/pachli/entity/FilterKeyword.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/FilterKeyword.kt similarity index 87% rename from app/src/main/java/app/pachli/entity/FilterKeyword.kt rename to core/network/src/main/kotlin/app/pachli/core/network/model/FilterKeyword.kt index cb3d70f80..9bf6bfbca 100644 --- a/app/src/main/java/app/pachli/entity/FilterKeyword.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/model/FilterKeyword.kt @@ -1,4 +1,4 @@ -package app.pachli.entity +package app.pachli.core.network.model import android.os.Parcelable import com.google.gson.annotations.SerializedName diff --git a/app/src/main/java/app/pachli/entity/FilterResult.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/FilterResult.kt similarity index 86% rename from app/src/main/java/app/pachli/entity/FilterResult.kt rename to core/network/src/main/kotlin/app/pachli/core/network/model/FilterResult.kt index a9dc85c7b..4f27165b1 100644 --- a/app/src/main/java/app/pachli/entity/FilterResult.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/model/FilterResult.kt @@ -1,4 +1,4 @@ -package app.pachli.entity +package app.pachli.core.network.model import com.google.gson.annotations.SerializedName diff --git a/app/src/main/java/app/pachli/entity/FilterV1.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/FilterV1.kt similarity index 98% rename from app/src/main/java/app/pachli/entity/FilterV1.kt rename to core/network/src/main/kotlin/app/pachli/core/network/model/FilterV1.kt index 1ddb53dee..d60707f27 100644 --- a/app/src/main/java/app/pachli/entity/FilterV1.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/model/FilterV1.kt @@ -14,7 +14,7 @@ * see . */ -package app.pachli.entity +package app.pachli.core.network.model import com.google.gson.annotations.SerializedName import java.util.Date diff --git a/app/src/main/java/app/pachli/entity/HashTag.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/HashTag.kt similarity index 69% rename from app/src/main/java/app/pachli/entity/HashTag.kt rename to core/network/src/main/kotlin/app/pachli/core/network/model/HashTag.kt index ab66991bb..4a248837a 100644 --- a/app/src/main/java/app/pachli/entity/HashTag.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/model/HashTag.kt @@ -1,3 +1,3 @@ -package app.pachli.entity +package app.pachli.core.network.model data class HashTag(val name: String, val url: String, val following: Boolean? = null) diff --git a/app/src/main/java/app/pachli/util/HttpHeaderLink.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/HttpHeaderLink.kt similarity index 99% rename from app/src/main/java/app/pachli/util/HttpHeaderLink.kt rename to core/network/src/main/kotlin/app/pachli/core/network/model/HttpHeaderLink.kt index 1384fe676..0660fb6ec 100644 --- a/app/src/main/java/app/pachli/util/HttpHeaderLink.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/model/HttpHeaderLink.kt @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License along with Pachli; if not, * see . */ -package app.pachli.util +package app.pachli.core.network.model import android.net.Uri import androidx.annotation.VisibleForTesting diff --git a/app/src/main/java/app/pachli/entity/InstanceV1.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/InstanceV1.kt similarity index 98% rename from app/src/main/java/app/pachli/entity/InstanceV1.kt rename to core/network/src/main/kotlin/app/pachli/core/network/model/InstanceV1.kt index 414b2d281..faeb891f9 100644 --- a/app/src/main/java/app/pachli/entity/InstanceV1.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/model/InstanceV1.kt @@ -14,7 +14,7 @@ * see . */ -package app.pachli.entity +package app.pachli.core.network.model import com.google.gson.annotations.SerializedName diff --git a/app/src/main/java/app/pachli/network/model/InstanceV2.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/InstanceV2.kt similarity index 99% rename from app/src/main/java/app/pachli/network/model/InstanceV2.kt rename to core/network/src/main/kotlin/app/pachli/core/network/model/InstanceV2.kt index 952b8b45e..448c4096d 100644 --- a/app/src/main/java/app/pachli/network/model/InstanceV2.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/model/InstanceV2.kt @@ -15,9 +15,8 @@ * see . */ -package app.pachli.network.model +package app.pachli.core.network.model -import app.pachli.entity.Account import com.google.gson.annotations.SerializedName /** https://docs.joinmastodon.org/entities/Instance/ */ diff --git a/core/network/src/main/kotlin/app/pachli/core/network/model/LinksHeader.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/LinksHeader.kt new file mode 100644 index 000000000..a9a53c1c0 --- /dev/null +++ b/core/network/src/main/kotlin/app/pachli/core/network/model/LinksHeader.kt @@ -0,0 +1,35 @@ +/* + * Copyright 2023 Pachli Association + * + * This file is a part of Pachli. + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Pachli; if not, + * see . + */ + +package app.pachli.core.network.model + +/** Models next/prev links from the "Links" header in an API response */ +data class Links(val next: String?, val prev: String?) { + companion object { + fun from(linkHeader: String?): Links { + val links = HttpHeaderLink.parse(linkHeader) + return Links( + next = HttpHeaderLink.findByRelationType(links, "next")?.uri?.getQueryParameter( + "max_id", + ), + prev = HttpHeaderLink.findByRelationType(links, "prev")?.uri?.getQueryParameter( + "min_id", + ), + ) + } + } +} diff --git a/app/src/main/java/app/pachli/entity/Marker.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/Marker.kt similarity index 88% rename from app/src/main/java/app/pachli/entity/Marker.kt rename to core/network/src/main/kotlin/app/pachli/core/network/model/Marker.kt index 770c654d4..4d09595d5 100644 --- a/app/src/main/java/app/pachli/entity/Marker.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/model/Marker.kt @@ -1,4 +1,4 @@ -package app.pachli.entity +package app.pachli.core.network.model import com.google.gson.annotations.SerializedName import java.util.Date diff --git a/app/src/main/java/app/pachli/entity/MastoList.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/MastoList.kt similarity index 95% rename from app/src/main/java/app/pachli/entity/MastoList.kt rename to core/network/src/main/kotlin/app/pachli/core/network/model/MastoList.kt index 1bfdc38fa..f0ab30a49 100644 --- a/app/src/main/java/app/pachli/entity/MastoList.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/model/MastoList.kt @@ -14,7 +14,7 @@ * see . */ -package app.pachli.entity +package app.pachli.core.network.model data class MastoList( val id: String, diff --git a/core/network/src/main/kotlin/app/pachli/core/network/model/MediaUploadApi.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/MediaUploadApi.kt new file mode 100644 index 000000000..ed9a06786 --- /dev/null +++ b/core/network/src/main/kotlin/app/pachli/core/network/model/MediaUploadApi.kt @@ -0,0 +1,38 @@ +/* + * Copyright 2023 Pachli Association + * + * This file is a part of Pachli. + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Pachli; if not, + * see . + */ + +package app.pachli.core.mastodon.model + +import app.pachli.core.network.model.MediaUploadResult +import okhttp3.MultipartBody +import retrofit2.Response +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part + +/** endpoints defined in this interface will be called with a higher timeout than usual + * which is necessary for media uploads to succeed on some servers + */ +interface MediaUploadApi { + @Multipart + @POST("api/v2/media") + suspend fun uploadMedia( + @Part file: MultipartBody.Part, + @Part description: MultipartBody.Part? = null, + @Part focus: MultipartBody.Part? = null, + ): Response +} diff --git a/app/src/main/java/app/pachli/entity/MediaUploadResult.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/MediaUploadResult.kt similarity index 86% rename from app/src/main/java/app/pachli/entity/MediaUploadResult.kt rename to core/network/src/main/kotlin/app/pachli/core/network/model/MediaUploadResult.kt index 9980324f1..53de61327 100644 --- a/app/src/main/java/app/pachli/entity/MediaUploadResult.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/model/MediaUploadResult.kt @@ -1,4 +1,4 @@ -package app.pachli.entity +package app.pachli.core.network.model /** * The same as Attachment, except the url is null - see https://docs.joinmastodon.org/methods/statuses/media/ diff --git a/app/src/main/java/app/pachli/entity/NewStatus.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/NewStatus.kt similarity index 97% rename from app/src/main/java/app/pachli/entity/NewStatus.kt rename to core/network/src/main/kotlin/app/pachli/core/network/model/NewStatus.kt index 9a9582729..cd25bfdfa 100644 --- a/app/src/main/java/app/pachli/entity/NewStatus.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/model/NewStatus.kt @@ -14,7 +14,7 @@ * see . */ -package app.pachli.entity +package app.pachli.core.network.model import android.os.Parcelable import com.google.gson.annotations.SerializedName diff --git a/app/src/main/java/app/pachli/entity/Notification.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/Notification.kt similarity index 79% rename from app/src/main/java/app/pachli/entity/Notification.kt rename to core/network/src/main/kotlin/app/pachli/core/network/model/Notification.kt index 165636b02..e555c2905 100644 --- a/app/src/main/java/app/pachli/entity/Notification.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/model/Notification.kt @@ -1,4 +1,5 @@ -/* Copyright 2017 Andrew Dawson +/* + * Copyright 2017 Andrew Dawson * * This file is a part of Pachli. * @@ -14,10 +15,8 @@ * see . */ -package app.pachli.entity +package app.pachli.core.network.model -import androidx.annotation.StringRes -import app.pachli.R import com.google.gson.JsonDeserializationContext import com.google.gson.JsonDeserializer import com.google.gson.JsonElement @@ -36,38 +35,38 @@ data class Notification( /** From https://docs.joinmastodon.org/entities/Notification/#type */ @JsonAdapter(NotificationTypeAdapter::class) - enum class Type(val presentation: String, @StringRes val uiString: Int) { - UNKNOWN("unknown", R.string.notification_unknown_name), + enum class Type(val presentation: String) { + UNKNOWN("unknown"), /** Someone mentioned you */ - MENTION("mention", R.string.notification_mention_name), + MENTION("mention"), /** Someone boosted one of your statuses */ - REBLOG("reblog", R.string.notification_boost_name), + REBLOG("reblog"), /** Someone favourited one of your statuses */ - FAVOURITE("favourite", R.string.notification_favourite_name), + FAVOURITE("favourite"), /** Someone followed you */ - FOLLOW("follow", R.string.notification_follow_name), + FOLLOW("follow"), /** Someone requested to follow you */ - FOLLOW_REQUEST("follow_request", R.string.notification_follow_request_name), + FOLLOW_REQUEST("follow_request"), /** A poll you have voted in or created has ended */ - POLL("poll", R.string.notification_poll_name), + POLL("poll"), /** Someone you enabled notifications for has posted a status */ - STATUS("status", R.string.notification_subscription_name), + STATUS("status"), /** Someone signed up (optionally sent to admins) */ - SIGN_UP("admin.sign_up", R.string.notification_sign_up_name), + SIGN_UP("admin.sign_up"), /** A status you interacted with has been updated */ - UPDATE("update", R.string.notification_update_name), + UPDATE("update"), /** A new report has been filed */ - REPORT("admin.report", R.string.notification_report_name), + REPORT("admin.report"), ; companion object { diff --git a/app/src/main/java/app/pachli/entity/NotificationSubscribeResult.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/NotificationSubscribeResult.kt similarity index 95% rename from app/src/main/java/app/pachli/entity/NotificationSubscribeResult.kt rename to core/network/src/main/kotlin/app/pachli/core/network/model/NotificationSubscribeResult.kt index 92b0c8582..5d9f2fa37 100644 --- a/app/src/main/java/app/pachli/entity/NotificationSubscribeResult.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/model/NotificationSubscribeResult.kt @@ -14,7 +14,7 @@ * see . */ -package app.pachli.entity +package app.pachli.core.network.model import com.google.gson.annotations.SerializedName diff --git a/app/src/main/java/app/pachli/entity/Poll.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/Poll.kt similarity index 97% rename from app/src/main/java/app/pachli/entity/Poll.kt rename to core/network/src/main/kotlin/app/pachli/core/network/model/Poll.kt index 2af32132d..f3d254948 100644 --- a/app/src/main/java/app/pachli/entity/Poll.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/model/Poll.kt @@ -1,4 +1,4 @@ -package app.pachli.entity +package app.pachli.core.network.model import com.google.gson.annotations.SerializedName import java.util.Date diff --git a/app/src/main/java/app/pachli/entity/Relationship.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/Relationship.kt similarity index 92% rename from app/src/main/java/app/pachli/entity/Relationship.kt rename to core/network/src/main/kotlin/app/pachli/core/network/model/Relationship.kt index d641019f5..9ea3a0422 100644 --- a/app/src/main/java/app/pachli/entity/Relationship.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/model/Relationship.kt @@ -1,4 +1,5 @@ -/* Copyright 2017 Andrew Dawson +/* + * Copyright 2017 Andrew Dawson * * This file is a part of Pachli. * @@ -14,9 +15,9 @@ * see . */ -package app.pachli.entity +package app.pachli.core.network.model -import app.pachli.json.GuardedBooleanAdapter +import app.pachli.core.network.json.GuardedBooleanAdapter import com.google.gson.annotations.JsonAdapter import com.google.gson.annotations.SerializedName diff --git a/core/network/src/main/kotlin/app/pachli/core/network/model/Report.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/Report.kt new file mode 100644 index 000000000..c180c2306 --- /dev/null +++ b/core/network/src/main/kotlin/app/pachli/core/network/model/Report.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2023 Pachli Association + * + * This file is a part of Pachli. + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Pachli; if not, + * see . + */ + +package app.pachli.core.network.model + +import com.google.gson.annotations.SerializedName +import java.util.Date + +data class Report( + val id: String, + val category: String, + val status_ids: List?, + @SerializedName("created_at") val createdAt: Date, + @SerializedName("target_account") val targetAccount: TimelineAccount, +) diff --git a/app/src/main/java/app/pachli/entity/ScheduledStatus.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/ScheduledStatus.kt similarity index 96% rename from app/src/main/java/app/pachli/entity/ScheduledStatus.kt rename to core/network/src/main/kotlin/app/pachli/core/network/model/ScheduledStatus.kt index 18e395b8f..871fc1959 100644 --- a/app/src/main/java/app/pachli/entity/ScheduledStatus.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/model/ScheduledStatus.kt @@ -14,7 +14,7 @@ * see . */ -package app.pachli.entity +package app.pachli.core.network.model import com.google.gson.annotations.SerializedName diff --git a/app/src/main/java/app/pachli/entity/SearchResult.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/SearchResult.kt similarity index 95% rename from app/src/main/java/app/pachli/entity/SearchResult.kt rename to core/network/src/main/kotlin/app/pachli/core/network/model/SearchResult.kt index 389a78356..5b94e89e9 100644 --- a/app/src/main/java/app/pachli/entity/SearchResult.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/model/SearchResult.kt @@ -14,7 +14,7 @@ * see . */ -package app.pachli.entity +package app.pachli.core.network.model data class SearchResult( val accounts: List, diff --git a/app/src/main/java/app/pachli/entity/Status.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/Status.kt similarity index 74% rename from app/src/main/java/app/pachli/entity/Status.kt rename to core/network/src/main/kotlin/app/pachli/core/network/model/Status.kt index ec1551988..8033f8784 100644 --- a/app/src/main/java/app/pachli/entity/Status.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/model/Status.kt @@ -1,4 +1,5 @@ -/* Copyright 2017 Andrew Dawson +/* + * Copyright 2017 Andrew Dawson * * This file is a part of Pachli. * @@ -14,16 +15,11 @@ * see . */ -package app.pachli.entity +package app.pachli.core.network.model -import android.content.Context -import android.graphics.drawable.Drawable import android.text.SpannableStringBuilder import android.text.style.URLSpan -import android.widget.TextView -import androidx.appcompat.content.res.AppCompatResources -import app.pachli.R -import app.pachli.util.parseAsMastodonHtml +import app.pachli.core.network.parseAsMastodonHtml import com.google.gson.annotations.SerializedName import java.util.Date @@ -176,43 +172,3 @@ data class Status( const val MAX_POLL_OPTIONS = 4 } } - -/** - * @return A description for this visibility, or "" if it's null or [Status.Visibility.UNKNOWN]. - */ -fun Status.Visibility?.description(context: Context): CharSequence { - this ?: return "" - - val resource: Int = when (this) { - Status.Visibility.PUBLIC -> R.string.description_visibility_public - Status.Visibility.UNLISTED -> R.string.description_visibility_unlisted - Status.Visibility.PRIVATE -> R.string.description_visibility_private - Status.Visibility.DIRECT -> R.string.description_visibility_direct - Status.Visibility.UNKNOWN -> return "" - } - return context.getString(resource) -} - -/** - * @return An icon for this visibility scaled and coloured to match the text on [textView]. - * Returns null if visibility is [Status.Visibility.UNKNOWN]. - */ -fun Status.Visibility?.icon(textView: TextView): Drawable? { - this ?: return null - - val resource: Int = when (this) { - Status.Visibility.PUBLIC -> R.drawable.ic_public_24dp - Status.Visibility.UNLISTED -> R.drawable.ic_lock_open_24dp - Status.Visibility.PRIVATE -> R.drawable.ic_lock_outline_24dp - Status.Visibility.DIRECT -> R.drawable.ic_email_24dp - Status.Visibility.UNKNOWN -> return null - } - val visibilityDrawable = AppCompatResources.getDrawable( - textView.context, - resource, - ) ?: return null - val size = textView.textSize.toInt() - visibilityDrawable.setBounds(0, 0, size, size) - visibilityDrawable.setTint(textView.currentTextColor) - return visibilityDrawable -} diff --git a/app/src/main/java/app/pachli/entity/StatusContext.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/StatusContext.kt similarity index 95% rename from app/src/main/java/app/pachli/entity/StatusContext.kt rename to core/network/src/main/kotlin/app/pachli/core/network/model/StatusContext.kt index fcfedf101..3916de135 100644 --- a/app/src/main/java/app/pachli/entity/StatusContext.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/model/StatusContext.kt @@ -14,7 +14,7 @@ * see . */ -package app.pachli.entity +package app.pachli.core.network.model data class StatusContext( val ancestors: List, diff --git a/app/src/main/java/app/pachli/entity/StatusEdit.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/StatusEdit.kt similarity index 91% rename from app/src/main/java/app/pachli/entity/StatusEdit.kt rename to core/network/src/main/kotlin/app/pachli/core/network/model/StatusEdit.kt index ee288bf3e..3d3066ea5 100644 --- a/app/src/main/java/app/pachli/entity/StatusEdit.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/model/StatusEdit.kt @@ -1,4 +1,4 @@ -package app.pachli.entity +package app.pachli.core.network.model import com.google.gson.annotations.SerializedName import java.util.Date diff --git a/app/src/main/java/app/pachli/entity/StatusParams.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/StatusParams.kt similarity index 93% rename from app/src/main/java/app/pachli/entity/StatusParams.kt rename to core/network/src/main/kotlin/app/pachli/core/network/model/StatusParams.kt index fac8f3cfd..405cecd2b 100644 --- a/app/src/main/java/app/pachli/entity/StatusParams.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/model/StatusParams.kt @@ -1,4 +1,5 @@ -/* Copyright 2019 kyori19 +/* + * Copyright 2019 kyori19 * * This file is a part of Pachli. * @@ -14,7 +15,7 @@ * see . */ -package app.pachli.entity +package app.pachli.core.network.model import com.google.gson.annotations.SerializedName diff --git a/app/src/main/java/app/pachli/entity/StatusSource.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/StatusSource.kt similarity index 91% rename from app/src/main/java/app/pachli/entity/StatusSource.kt rename to core/network/src/main/kotlin/app/pachli/core/network/model/StatusSource.kt index 6a8da3756..a6d2ef7ad 100644 --- a/app/src/main/java/app/pachli/entity/StatusSource.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/model/StatusSource.kt @@ -1,4 +1,5 @@ -/* Copyright 2022 Tusky Contributors +/* + * Copyright 2022 Tusky Contributors * * This file is a part of Pachli. * @@ -14,7 +15,7 @@ * see . */ -package app.pachli.entity +package app.pachli.core.network.model import com.google.gson.annotations.SerializedName diff --git a/app/src/main/java/app/pachli/entity/TimelineAccount.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/TimelineAccount.kt similarity index 95% rename from app/src/main/java/app/pachli/entity/TimelineAccount.kt rename to core/network/src/main/kotlin/app/pachli/core/network/model/TimelineAccount.kt index 721888d0d..b4162abb8 100644 --- a/app/src/main/java/app/pachli/entity/TimelineAccount.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/model/TimelineAccount.kt @@ -1,4 +1,5 @@ -/* Copyright 2017 Andrew Dawson +/* + * Copyright 2017 Andrew Dawson * * This file is a part of Pachli. * @@ -14,7 +15,7 @@ * see . */ -package app.pachli.entity +package app.pachli.core.network.model import com.google.gson.annotations.SerializedName diff --git a/app/src/main/java/app/pachli/components/timeline/TimelineKind.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/TimelineKind.kt similarity index 100% rename from app/src/main/java/app/pachli/components/timeline/TimelineKind.kt rename to core/network/src/main/kotlin/app/pachli/core/network/model/TimelineKind.kt diff --git a/app/src/main/java/app/pachli/entity/Translation.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/Translation.kt similarity index 98% rename from app/src/main/java/app/pachli/entity/Translation.kt rename to core/network/src/main/kotlin/app/pachli/core/network/model/Translation.kt index c964034dc..fda8102b9 100644 --- a/app/src/main/java/app/pachli/entity/Translation.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/model/Translation.kt @@ -15,7 +15,7 @@ * see . */ -package app.pachli.entity +package app.pachli.core.network.model import com.google.gson.annotations.SerializedName diff --git a/app/src/main/java/app/pachli/entity/TrendingTagsResult.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/TrendingTag.kt similarity index 95% rename from app/src/main/java/app/pachli/entity/TrendingTagsResult.kt rename to core/network/src/main/kotlin/app/pachli/core/network/model/TrendingTag.kt index 443c17bcd..50cc2d700 100644 --- a/app/src/main/java/app/pachli/entity/TrendingTagsResult.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/model/TrendingTag.kt @@ -1,4 +1,5 @@ -/* Copyright 2023 Tusky Contributors +/* + * Copyright 2023 Tusky Contributors * * This file is a part of Pachli. * @@ -14,7 +15,7 @@ * see . */ -package app.pachli.entity +package app.pachli.core.network.model import java.util.Date diff --git a/app/src/main/java/app/pachli/entity/TrendsLink.kt b/core/network/src/main/kotlin/app/pachli/core/network/model/TrendsLink.kt similarity index 98% rename from app/src/main/java/app/pachli/entity/TrendsLink.kt rename to core/network/src/main/kotlin/app/pachli/core/network/model/TrendsLink.kt index ebebee226..5888a149d 100644 --- a/app/src/main/java/app/pachli/entity/TrendsLink.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/model/TrendsLink.kt @@ -15,7 +15,7 @@ * see . */ -package app.pachli.entity +package app.pachli.core.network.model import com.google.gson.annotations.SerializedName diff --git a/app/src/main/java/app/pachli/network/InstanceSwitchAuthInterceptor.kt b/core/network/src/main/kotlin/app/pachli/core/network/retrofit/InstanceSwitchAuthInterceptor.kt similarity index 77% rename from app/src/main/java/app/pachli/network/InstanceSwitchAuthInterceptor.kt rename to core/network/src/main/kotlin/app/pachli/core/network/retrofit/InstanceSwitchAuthInterceptor.kt index 1ce86604a..83c3a5d63 100644 --- a/app/src/main/java/app/pachli/network/InstanceSwitchAuthInterceptor.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/retrofit/InstanceSwitchAuthInterceptor.kt @@ -1,4 +1,5 @@ -/* Copyright 2022 Tusky Contributors +/* + * Copyright 2022 Tusky Contributors * * This file is a part of Pachli. * @@ -14,9 +15,8 @@ * see . */ -package app.pachli.network +package app.pachli.core.network.retrofit -import app.pachli.db.AccountManager import okhttp3.HttpUrl import okhttp3.Interceptor import okhttp3.MediaType.Companion.toMediaType @@ -26,8 +26,19 @@ import okhttp3.Response import okhttp3.ResponseBody.Companion.toResponseBody import timber.log.Timber import java.io.IOException +import javax.inject.Inject +import javax.inject.Singleton -class InstanceSwitchAuthInterceptor(private val accountManager: AccountManager) : Interceptor { +// AccountManager can not be used here as that would create a circular dependency +// between core.network and core.accounts. Instead, the singleton instance of this +// InstanceSwitchAuthInterceptor is injected in to AccountManager, and +// AccountManager updates `credentials` when the active account changes. + +@Singleton +class InstanceSwitchAuthInterceptor @Inject constructor() : Interceptor { + data class Credentials(val accessToken: String, val domain: String) + + var credentials: Credentials? = null @Throws(IOException::class) override fun intercept(chain: Interceptor.Chain): Response { @@ -43,14 +54,10 @@ class InstanceSwitchAuthInterceptor(private val accountManager: AccountManager) builder.url(swapHost(originalRequest.url, instanceHeader)) builder.removeHeader(MastodonApi.DOMAIN_HEADER) } else { - val currentAccount = accountManager.activeAccount - - if (currentAccount != null) { - val accessToken = currentAccount.accessToken - if (accessToken.isNotEmpty()) { - // use domain of current account - builder.url(swapHost(originalRequest.url, currentAccount.domain)) - .header("Authorization", "Bearer %s".format(accessToken)) + credentials?.let { + if (it.accessToken.isNotEmpty()) { + builder.url(swapHost(originalRequest.url, it.domain)) + .header("Authorization", "Bearer %s".format(it.accessToken)) } } } diff --git a/app/src/main/java/app/pachli/network/MastodonApi.kt b/core/network/src/main/kotlin/app/pachli/core/network/retrofit/MastodonApi.kt similarity index 93% rename from app/src/main/java/app/pachli/network/MastodonApi.kt rename to core/network/src/main/kotlin/app/pachli/core/network/retrofit/MastodonApi.kt index 0cb88f195..3eae7224d 100644 --- a/app/src/main/java/app/pachli/network/MastodonApi.kt +++ b/core/network/src/main/kotlin/app/pachli/core/network/retrofit/MastodonApi.kt @@ -14,41 +14,40 @@ * see . */ -package app.pachli.network +package app.pachli.core.network.retrofit -import app.pachli.entity.AccessToken -import app.pachli.entity.Account -import app.pachli.entity.Announcement -import app.pachli.entity.AppCredentials -import app.pachli.entity.Attachment -import app.pachli.entity.Conversation -import app.pachli.entity.DeletedStatus -import app.pachli.entity.Emoji -import app.pachli.entity.Filter -import app.pachli.entity.FilterKeyword -import app.pachli.entity.FilterV1 -import app.pachli.entity.HashTag -import app.pachli.entity.InstanceV1 -import app.pachli.entity.Marker -import app.pachli.entity.MastoList -import app.pachli.entity.MediaUploadResult -import app.pachli.entity.NewStatus -import app.pachli.entity.Notification -import app.pachli.entity.NotificationSubscribeResult -import app.pachli.entity.Poll -import app.pachli.entity.Relationship -import app.pachli.entity.ScheduledStatus -import app.pachli.entity.SearchResult -import app.pachli.entity.Status -import app.pachli.entity.StatusContext -import app.pachli.entity.StatusEdit -import app.pachli.entity.StatusSource -import app.pachli.entity.TimelineAccount -import app.pachli.entity.Translation -import app.pachli.entity.TrendingTag -import app.pachli.entity.TrendsLink -import app.pachli.network.model.InstanceV2 -import app.pachli.util.HttpHeaderLink +import app.pachli.core.network.model.AccessToken +import app.pachli.core.network.model.Account +import app.pachli.core.network.model.Announcement +import app.pachli.core.network.model.AppCredentials +import app.pachli.core.network.model.Attachment +import app.pachli.core.network.model.Conversation +import app.pachli.core.network.model.DeletedStatus +import app.pachli.core.network.model.Emoji +import app.pachli.core.network.model.Filter +import app.pachli.core.network.model.FilterKeyword +import app.pachli.core.network.model.FilterV1 +import app.pachli.core.network.model.HashTag +import app.pachli.core.network.model.InstanceV1 +import app.pachli.core.network.model.InstanceV2 +import app.pachli.core.network.model.Marker +import app.pachli.core.network.model.MastoList +import app.pachli.core.network.model.MediaUploadResult +import app.pachli.core.network.model.NewStatus +import app.pachli.core.network.model.Notification +import app.pachli.core.network.model.NotificationSubscribeResult +import app.pachli.core.network.model.Poll +import app.pachli.core.network.model.Relationship +import app.pachli.core.network.model.ScheduledStatus +import app.pachli.core.network.model.SearchResult +import app.pachli.core.network.model.Status +import app.pachli.core.network.model.StatusContext +import app.pachli.core.network.model.StatusEdit +import app.pachli.core.network.model.StatusSource +import app.pachli.core.network.model.TimelineAccount +import app.pachli.core.network.model.Translation +import app.pachli.core.network.model.TrendingTag +import app.pachli.core.network.model.TrendsLink import at.connyduck.calladapter.networkresult.NetworkResult import okhttp3.MultipartBody import okhttp3.RequestBody @@ -75,23 +74,6 @@ import retrofit2.http.Query * for documentation of the Mastodon REST API see https://docs.joinmastodon.org/api/ */ -/** Models next/prev links from the "Links" header in an API response */ -data class Links(val next: String?, val prev: String?) { - companion object { - fun from(linkHeader: String?): Links { - val links = HttpHeaderLink.parse(linkHeader) - return Links( - next = HttpHeaderLink.findByRelationType(links, "next")?.uri?.getQueryParameter( - "max_id", - ), - prev = HttpHeaderLink.findByRelationType(links, "prev")?.uri?.getQueryParameter( - "min_id", - ), - ) - } - } -} - @JvmSuppressWildcards interface MastodonApi { diff --git a/app/src/test/java/app/pachli/network/ServerKindTest.kt b/core/network/src/test/kotlin/app/pachli/core/network/ServerKindTest.kt similarity index 90% rename from app/src/test/java/app/pachli/network/ServerKindTest.kt rename to core/network/src/test/kotlin/app/pachli/core/network/ServerKindTest.kt index d34959602..506001ab9 100644 --- a/app/src/test/java/app/pachli/network/ServerKindTest.kt +++ b/core/network/src/test/kotlin/app/pachli/core/network/ServerKindTest.kt @@ -15,12 +15,12 @@ * see . */ -package app.pachli.network +package app.pachli.core.network -import app.pachli.network.ServerKind.AKKOMA -import app.pachli.network.ServerKind.MASTODON -import app.pachli.network.ServerKind.PLEROMA -import app.pachli.network.ServerKind.UNKNOWN +import app.pachli.core.network.ServerKind.AKKOMA +import app.pachli.core.network.ServerKind.MASTODON +import app.pachli.core.network.ServerKind.PLEROMA +import app.pachli.core.network.ServerKind.UNKNOWN import com.github.michaelbull.result.Ok import com.github.michaelbull.result.Result import io.github.z4kn4fein.semver.Version diff --git a/app/src/test/java/app/pachli/json/GuardedBooleanAdapterTest.kt b/core/network/src/test/kotlin/app/pachli/core/network/json/GuardedBooleanAdapterTest.kt similarity index 97% rename from app/src/test/java/app/pachli/json/GuardedBooleanAdapterTest.kt rename to core/network/src/test/kotlin/app/pachli/core/network/json/GuardedBooleanAdapterTest.kt index 8fecb5973..a0930e70f 100644 --- a/app/src/test/java/app/pachli/json/GuardedBooleanAdapterTest.kt +++ b/core/network/src/test/kotlin/app/pachli/core/network/json/GuardedBooleanAdapterTest.kt @@ -1,6 +1,6 @@ -package app.pachli.json +package app.pachli.core.network.json -import app.pachli.entity.Relationship +import app.pachli.core.network.model.Relationship import com.google.gson.Gson import org.junit.Assert.assertEquals import org.junit.Test diff --git a/app/src/test/java/app/pachli/util/HttpHeaderLinkTest.kt b/core/network/src/test/kotlin/app/pachli/core/network/model/HttpHeaderLinkTest.kt similarity index 99% rename from app/src/test/java/app/pachli/util/HttpHeaderLinkTest.kt rename to core/network/src/test/kotlin/app/pachli/core/network/model/HttpHeaderLinkTest.kt index 47caa9de6..4c9bd1a24 100644 --- a/app/src/test/java/app/pachli/util/HttpHeaderLinkTest.kt +++ b/core/network/src/test/kotlin/app/pachli/core/network/model/HttpHeaderLinkTest.kt @@ -15,7 +15,7 @@ * see . */ -package app.pachli.util +package app.pachli.core.network.model import androidx.test.ext.junit.runners.AndroidJUnit4 import org.junit.Assert.assertEquals diff --git a/app/src/test/java/app/pachli/network/InstanceV1SwitchAuthInterceptorTest.kt b/core/network/src/test/kotlin/app/pachli/core/network/retrofit/InstanceV1SwitchAuthInterceptorTest.kt similarity index 64% rename from app/src/test/java/app/pachli/network/InstanceV1SwitchAuthInterceptorTest.kt rename to core/network/src/test/kotlin/app/pachli/core/network/retrofit/InstanceV1SwitchAuthInterceptorTest.kt index 80a2039cf..390b569d3 100644 --- a/app/src/test/java/app/pachli/network/InstanceV1SwitchAuthInterceptorTest.kt +++ b/core/network/src/test/kotlin/app/pachli/core/network/retrofit/InstanceV1SwitchAuthInterceptorTest.kt @@ -1,7 +1,23 @@ -package app.pachli.network +/* + * Copyright 2023 Pachli Association + * + * This file is a part of Pachli. + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Pachli; if not, + * see . + */ -import app.pachli.db.AccountEntity -import app.pachli.db.AccountManager +package app.pachli.core.network.retrofit + +import androidx.test.ext.junit.runners.AndroidJUnit4 import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.mockwebserver.MockResponse @@ -11,9 +27,9 @@ import org.junit.Assert.assertEquals import org.junit.Assert.assertNull import org.junit.Before import org.junit.Test -import org.mockito.kotlin.doAnswer -import org.mockito.kotlin.mock +import org.junit.runner.RunWith +@RunWith(AndroidJUnit4::class) class InstanceV1SwitchAuthInterceptorTest { private val mockWebServer = MockWebServer() @@ -32,12 +48,8 @@ class InstanceV1SwitchAuthInterceptorTest { fun `should make regular request when requested`() { mockWebServer.enqueue(MockResponse()) - val accountManager: AccountManager = mock { - on { activeAccount } doAnswer { null } - } - val okHttpClient = OkHttpClient.Builder() - .addInterceptor(InstanceSwitchAuthInterceptor(accountManager)) + .addInterceptor(InstanceSwitchAuthInterceptor()) .build() val request = Request.Builder() @@ -54,21 +66,14 @@ class InstanceV1SwitchAuthInterceptorTest { fun `should make request to instance requested in special header`() { mockWebServer.enqueue(MockResponse()) - val accountManager: AccountManager = mock { - on { activeAccount } doAnswer { - AccountEntity( - id = 1, - domain = "test.domain", - accessToken = "fakeToken", - clientId = "fakeId", - clientSecret = "fakeSecret", - isActive = true, - ) - } - } + val interceptor = InstanceSwitchAuthInterceptor() + interceptor.credentials = InstanceSwitchAuthInterceptor.Credentials( + accessToken = "fakeToken", + domain = "test.domain" + ) val okHttpClient = OkHttpClient.Builder() - .addInterceptor(InstanceSwitchAuthInterceptor(accountManager)) + .addInterceptor(interceptor) .build() val request = Request.Builder() @@ -88,21 +93,14 @@ class InstanceV1SwitchAuthInterceptorTest { fun `should make request to current instance when requested and user is logged in`() { mockWebServer.enqueue(MockResponse()) - val accountManager: AccountManager = mock { - on { activeAccount } doAnswer { - AccountEntity( - id = 1, - domain = mockWebServer.hostName, - accessToken = "fakeToken", - clientId = "fakeId", - clientSecret = "fakeSecret", - isActive = true, - ) - } - } + val interceptor = InstanceSwitchAuthInterceptor() + interceptor.credentials = InstanceSwitchAuthInterceptor.Credentials( + accessToken = "fakeToken", + domain = mockWebServer.hostName + ) val okHttpClient = OkHttpClient.Builder() - .addInterceptor(InstanceSwitchAuthInterceptor(accountManager)) + .addInterceptor(interceptor) .build() val request = Request.Builder() @@ -121,12 +119,8 @@ class InstanceV1SwitchAuthInterceptorTest { fun `should fail to make request when request to current instance is requested but no user is logged in`() { mockWebServer.enqueue(MockResponse()) - val accountManager: AccountManager = mock { - on { activeAccount } doAnswer { null } - } - val okHttpClient = OkHttpClient.Builder() - .addInterceptor(InstanceSwitchAuthInterceptor(accountManager)) + .addInterceptor(InstanceSwitchAuthInterceptor()) .build() val request = Request.Builder() diff --git a/core/network/src/test/resources/robolectric.properties b/core/network/src/test/resources/robolectric.properties new file mode 100644 index 000000000..69da0b97b --- /dev/null +++ b/core/network/src/test/resources/robolectric.properties @@ -0,0 +1,20 @@ +# +# Copyright 2023 Pachli Association +# +# This file is a part of Pachli. +# +# This program is free software; you can redistribute it and/or modify it under the terms of the +# GNU General Public License as published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even +# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along with Pachli; if not, +# see . +# + +# Robolectric does not support SDK 34 yet +# https://github.com/robolectric/robolectric/issues/8404 +sdk=33 diff --git a/core/preferences/build.gradle.kts b/core/preferences/build.gradle.kts new file mode 100644 index 000000000..e9eeb0258 --- /dev/null +++ b/core/preferences/build.gradle.kts @@ -0,0 +1,36 @@ +/* + * Copyright 2023 Pachli Association + * + * This file is a part of Pachli. + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Pachli; if not, + * see . + */ + +plugins { + alias(libs.plugins.pachli.android.library) + alias(libs.plugins.pachli.android.hilt) + alias(libs.plugins.kotlin.parcelize) +} + +android { + namespace = "app.pachli.core.preferences" + + defaultConfig { + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } +} + +dependencies { + implementation(projects.core.common) + + implementation(libs.bundles.androidx) +} diff --git a/core/preferences/lint-baseline.xml b/core/preferences/lint-baseline.xml new file mode 100644 index 000000000..f32fed49a --- /dev/null +++ b/core/preferences/lint-baseline.xml @@ -0,0 +1,4 @@ + + + + diff --git a/core/preferences/src/main/AndroidManifest.xml b/core/preferences/src/main/AndroidManifest.xml new file mode 100644 index 000000000..76e9ba6e7 --- /dev/null +++ b/core/preferences/src/main/AndroidManifest.xml @@ -0,0 +1,21 @@ + + + + + + diff --git a/app/src/main/java/app/pachli/settings/ProxyConfiguration.kt b/core/preferences/src/main/kotlin/app/pachli/core/preferences/ProxyConfiguration.kt similarity index 65% rename from app/src/main/java/app/pachli/settings/ProxyConfiguration.kt rename to core/preferences/src/main/kotlin/app/pachli/core/preferences/ProxyConfiguration.kt index a071bfeb9..e3b118b89 100644 --- a/app/src/main/java/app/pachli/settings/ProxyConfiguration.kt +++ b/core/preferences/src/main/kotlin/app/pachli/core/preferences/ProxyConfiguration.kt @@ -1,4 +1,21 @@ -package app.pachli.settings +/* + * Copyright 2023 Pachli Association + * + * This file is a part of Pachli. + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Pachli; if not, + * see . + */ + +package app.pachli.core.preferences import java.net.IDN diff --git a/app/src/main/java/app/pachli/settings/SettingsConstants.kt b/core/preferences/src/main/kotlin/app/pachli/core/preferences/SettingsConstants.kt similarity index 99% rename from app/src/main/java/app/pachli/settings/SettingsConstants.kt rename to core/preferences/src/main/kotlin/app/pachli/core/preferences/SettingsConstants.kt index a56e35361..a44f0f3ea 100644 --- a/app/src/main/java/app/pachli/settings/SettingsConstants.kt +++ b/core/preferences/src/main/kotlin/app/pachli/core/preferences/SettingsConstants.kt @@ -1,4 +1,4 @@ -package app.pachli.settings +package app.pachli.core.preferences enum class AppTheme(val value: String) { NIGHT("night"), diff --git a/app/src/main/java/app/pachli/util/SharedPreferencesExtensions.kt b/core/preferences/src/main/kotlin/app/pachli/core/preferences/SharedPreferencesExtensions.kt similarity index 83% rename from app/src/main/java/app/pachli/util/SharedPreferencesExtensions.kt rename to core/preferences/src/main/kotlin/app/pachli/core/preferences/SharedPreferencesExtensions.kt index e970429fb..58cb3cf1c 100644 --- a/app/src/main/java/app/pachli/util/SharedPreferencesExtensions.kt +++ b/core/preferences/src/main/kotlin/app/pachli/core/preferences/SharedPreferencesExtensions.kt @@ -1,4 +1,4 @@ -package app.pachli.util +package app.pachli.core.preferences import android.content.SharedPreferences diff --git a/app/src/main/java/app/pachli/util/SharedPreferencesRepository.kt b/core/preferences/src/main/kotlin/app/pachli/core/preferences/SharedPreferencesRepository.kt similarity index 96% rename from app/src/main/java/app/pachli/util/SharedPreferencesRepository.kt rename to core/preferences/src/main/kotlin/app/pachli/core/preferences/SharedPreferencesRepository.kt index 995fc3692..528bf046a 100644 --- a/app/src/main/java/app/pachli/util/SharedPreferencesRepository.kt +++ b/core/preferences/src/main/kotlin/app/pachli/core/preferences/SharedPreferencesRepository.kt @@ -15,11 +15,11 @@ * see . */ -package app.pachli.util +package app.pachli.core.preferences import android.content.SharedPreferences import androidx.annotation.Keep -import app.pachli.di.ApplicationScope +import app.pachli.core.common.di.ApplicationScope import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.launch diff --git a/app/src/main/java/app/pachli/di/PreferencesModule.kt b/core/preferences/src/main/kotlin/app/pachli/core/preferences/di/PreferencesModule.kt similarity index 96% rename from app/src/main/java/app/pachli/di/PreferencesModule.kt rename to core/preferences/src/main/kotlin/app/pachli/core/preferences/di/PreferencesModule.kt index 0e3e43e13..88e0c29c5 100644 --- a/app/src/main/java/app/pachli/di/PreferencesModule.kt +++ b/core/preferences/src/main/kotlin/app/pachli/core/preferences/di/PreferencesModule.kt @@ -15,7 +15,7 @@ * see . */ -package app.pachli.di +package app.pachli.core.preferences.di import android.app.Application import android.content.SharedPreferences diff --git a/app/src/test/java/app/pachli/entity/ProxyConfigurationTest.kt b/core/preferences/src/test/kotlin/app/pachli/core/preferences/ProxyConfigurationTest.kt similarity index 70% rename from app/src/test/java/app/pachli/entity/ProxyConfigurationTest.kt rename to core/preferences/src/test/kotlin/app/pachli/core/preferences/ProxyConfigurationTest.kt index 2175324ba..80faf7091 100644 --- a/app/src/test/java/app/pachli/entity/ProxyConfigurationTest.kt +++ b/core/preferences/src/test/kotlin/app/pachli/core/preferences/ProxyConfigurationTest.kt @@ -1,6 +1,22 @@ -package app.pachli.entity +/* + * Copyright 2023 Pachli Association + * + * This file is a part of Pachli. + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Pachli; if not, + * see . + */ + +package app.pachli.core.preferences -import app.pachli.settings.ProxyConfiguration import org.junit.Assert import org.junit.Test diff --git a/app/src/test/java/app/pachli/util/SharedPreferencesRepositoryTest.kt b/core/preferences/src/test/kotlin/app/pachli/core/preferences/SharedPreferencesRepositoryTest.kt similarity index 96% rename from app/src/test/java/app/pachli/util/SharedPreferencesRepositoryTest.kt rename to core/preferences/src/test/kotlin/app/pachli/core/preferences/SharedPreferencesRepositoryTest.kt index 36b693227..28b6d1059 100644 --- a/app/src/test/java/app/pachli/util/SharedPreferencesRepositoryTest.kt +++ b/core/preferences/src/test/kotlin/app/pachli/core/preferences/SharedPreferencesRepositoryTest.kt @@ -15,13 +15,13 @@ * see . */ -package app.pachli.util +package app.pachli.core.preferences import androidx.core.content.edit import androidx.test.ext.junit.runners.AndroidJUnit4 import app.cash.turbine.test -import app.pachli.components.timeline.MainCoroutineRule -import app.pachli.fakes.InMemorySharedPreferences +import app.pachli.core.testing.fakes.InMemorySharedPreferences +import app.pachli.core.testing.rules.MainCoroutineRule import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest diff --git a/core/preferences/src/test/resources/robolectric.properties b/core/preferences/src/test/resources/robolectric.properties new file mode 100644 index 000000000..69da0b97b --- /dev/null +++ b/core/preferences/src/test/resources/robolectric.properties @@ -0,0 +1,20 @@ +# +# Copyright 2023 Pachli Association +# +# This file is a part of Pachli. +# +# This program is free software; you can redistribute it and/or modify it under the terms of the +# GNU General Public License as published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even +# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along with Pachli; if not, +# see . +# + +# Robolectric does not support SDK 34 yet +# https://github.com/robolectric/robolectric/issues/8404 +sdk=33 diff --git a/core/testing/build.gradle.kts b/core/testing/build.gradle.kts new file mode 100644 index 000000000..d3bd0d914 --- /dev/null +++ b/core/testing/build.gradle.kts @@ -0,0 +1,44 @@ +/* + * Copyright 2023 Pachli Association + * + * This file is a part of Pachli. + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Pachli; if not, + * see . + */ + +plugins { + alias(libs.plugins.pachli.android.library) + alias(libs.plugins.pachli.android.hilt) + alias(libs.plugins.kotlin.parcelize) +} + +android { + namespace = "app.pachli.core.testing" + + defaultConfig { + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } +} + +dependencies { + implementation(projects.core.common) + + api(libs.kotlinx.coroutines.test) + api(libs.androidx.test.junit) + api(libs.androidx.core.testing) + api(libs.androidx.test.core.ktx) + api(libs.robolectric) + api(libs.truth) + api(libs.turbine) + + androidTestImplementation(libs.androidx.test.junit) +} diff --git a/core/testing/lint-baseline.xml b/core/testing/lint-baseline.xml new file mode 100644 index 000000000..a32ee8243 --- /dev/null +++ b/core/testing/lint-baseline.xml @@ -0,0 +1,140 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/test/java/app/pachli/fakes/InMemorySharedPreferences.kt b/core/testing/src/main/kotlin/app/pachli/core/testing/fakes/InMemorySharedPreferences.kt similarity index 99% rename from app/src/test/java/app/pachli/fakes/InMemorySharedPreferences.kt rename to core/testing/src/main/kotlin/app/pachli/core/testing/fakes/InMemorySharedPreferences.kt index 47afb2613..3b66ed79d 100644 --- a/app/src/test/java/app/pachli/fakes/InMemorySharedPreferences.kt +++ b/core/testing/src/main/kotlin/app/pachli/core/testing/fakes/InMemorySharedPreferences.kt @@ -15,7 +15,7 @@ * see . */ -package app.pachli.fakes +package app.pachli.core.testing.fakes import android.content.SharedPreferences import android.content.SharedPreferences.Editor diff --git a/app/src/test/java/app/pachli/rules/LazyActivityScenarioRule.kt b/core/testing/src/main/kotlin/app/pachli/core/testing/rules/LazyActivityScenarioRule.kt similarity index 98% rename from app/src/test/java/app/pachli/rules/LazyActivityScenarioRule.kt rename to core/testing/src/main/kotlin/app/pachli/core/testing/rules/LazyActivityScenarioRule.kt index c84735d22..e9ca772f5 100644 --- a/app/src/test/java/app/pachli/rules/LazyActivityScenarioRule.kt +++ b/core/testing/src/main/kotlin/app/pachli/core/testing/rules/LazyActivityScenarioRule.kt @@ -15,7 +15,7 @@ * see . */ -package app.pachli.rules +package app.pachli.core.testing.rules import android.app.Activity import android.content.Intent diff --git a/app/src/test/java/app/pachli/components/timeline/MainCoroutineRule.kt b/core/testing/src/main/kotlin/app/pachli/core/testing/rules/MainCoroutineRule.kt similarity index 97% rename from app/src/test/java/app/pachli/components/timeline/MainCoroutineRule.kt rename to core/testing/src/main/kotlin/app/pachli/core/testing/rules/MainCoroutineRule.kt index 2e23ea4ae..1750bd88e 100644 --- a/app/src/test/java/app/pachli/components/timeline/MainCoroutineRule.kt +++ b/core/testing/src/main/kotlin/app/pachli/core/testing/rules/MainCoroutineRule.kt @@ -15,7 +15,7 @@ * see . */ -package app.pachli.components.timeline +package app.pachli.core.testing.rules import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0f8ee015c..8e2c79b89 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -37,9 +37,12 @@ glide = "4.16.0" glide-animation-plugin = "2.23.0" gson = "2.10.1" hilt = "2.48.1" +junit = "4.13.2" kotlin = "1.9.20" kotlin-result = "1.1.8" +ksp = "1.9.20-1.0.14" image-cropper = "4.3.2" +lint = "31.2.0" # = agp + 23.0.0 (= 8.2.0), see https://github.com/googlesamples/android-custom-lint-rules#lint-version material = "1.10.0" material-drawer = "9.0.2" material-typeface = "4.0.0.2-kotlin" @@ -64,13 +67,23 @@ xmlwriter = "1.0.4" [plugins] aboutlibraries = { id = "com.mikepenz.aboutlibraries.plugin", version.ref = "aboutlibraries" } android-application = { id = "com.android.application", version.ref = "agp" } -google-ksp = "com.google.devtools.ksp:1.9.20-1.0.14" +android-library = { id = "com.android.library", version.ref = "agp" } +android-lint = { id = "com.android.lint", version.ref = "agp" } +google-ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } hilt = { id = "com.google.dagger.hilt.android", version.ref = "hilt" } kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } +kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlin" } ktlint = "org.jlleitschuh.gradle.ktlint:11.6.1" room = { id = "androidx.room", version.ref = "androidx-room" } +# Plugins defined by this project +pachli-android-application = { id = "pachli.android.application", version = "unspecified" } +pachli-android-application-flavors = { id = "pachli.android.application.flavors", version = "unspecified" } +pachli-android-hilt = { id = "pachli.android.hilt", version = "unspecified" } +pachli-android-library = { id = "pachli.android.library", version = "unspecified" } +pachli-android-room = { id = "pachli.android.room", version = "unspecified" } + [libraries] aboutlibraries-core = { module = "com.mikepenz:aboutlibraries-core", version.ref = "aboutlibraries" } aboutlibraries-legacy-ui = { module = "com.mikepenz:aboutlibraries", version.ref = "aboutlibraries" } @@ -131,11 +144,17 @@ gson = { module = "com.google.code.gson:gson", version.ref = "gson" } hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hilt" } hilt-compiler = { module = "com.google.dagger:hilt-compiler", version.ref = "hilt" } hilt-android-testing = { module = "com.google.dagger:hilt-android-testing", version.ref = "hilt" } +junit = { module = "junit:junit", version.ref = "junit" } kotlin-result = { module = "com.michael-bull.kotlin-result:kotlin-result", version.ref = "kotlin-result" } kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "coroutines" } kotlinx-coroutines-rx3 = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-rx3", version.ref = "coroutines" } kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "coroutines" } +kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" } image-cropper = { module = "com.github.CanHub:Android-Image-Cropper", version.ref = "image-cropper" } +lint-api = { module = "com.android.tools.lint:lint-api", version.ref = "lint" } +lint-checks = { module = "com.android.tools.lint:lint-checks", version.ref = "lint" } +lint-cli = { module = "com.android.tools.lint:lint", version.ref = "lint" } +lint-tests = { module = "com.android.tools.lint:lint-tests", version.ref = "lint" } material-drawer-core = { module = "com.mikepenz:materialdrawer", version.ref = "material-drawer" } material-drawer-iconics = { module = "com.mikepenz:materialdrawer-iconics", version.ref = "material-drawer" } material-typeface = { module = "com.mikepenz:google-material-typeface", version.ref = "material-typeface" } @@ -160,6 +179,11 @@ turbine = { module = "app.cash.turbine:turbine", version.ref = "turbine" } unified-push = { module = "com.github.UnifiedPush:android-connector", version.ref = "unified-push" } xmlwriter = { module = "org.pageseeder.xmlwriter:pso-xmlwriter", version.ref = "xmlwriter" } +# build-logic dependencies +android-gradlePlugin = { module = "com.android.tools.build:gradle", version.ref = "agp" } +kotlin-gradlePlugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" } +ksp-gradlePlugin = { module = "com.google.devtools.ksp:com.google.devtools.ksp.gradle.plugin", version.ref = "ksp" } + [bundles] aboutlibraries = ["aboutlibraries-core", "aboutlibraries-legacy-ui"] androidx = ["androidx-core-ktx", "androidx-appcompat", "androidx-fragment-ktx", "androidx-browser", "androidx-swiperefreshlayout", @@ -173,6 +197,8 @@ androidx = ["androidx-core-ktx", "androidx-appcompat", "androidx-fragment-ktx", autodispose = ["autodispose-core", "autodispose-android-lifecycle"] filemojicompat = ["filemojicompat-core", "filemojicompat-ui", "filemojicompat-defaults"] glide = ["glide-core", "glide-okhttp3-integration", "glide-animation-plugin"] +lint-api = ["kotlin-stdlib", "lint-api", "lint-checks"] +lint-tests = ["junit", "lint-cli", "lint-tests"] material-drawer = ["material-drawer-core", "material-drawer-iconics"] mockito = ["mockito-kotlin", "mockito-inline"] okhttp = ["okhttp-core", "okhttp-logging-interceptor"] diff --git a/plugins/markdown2resource/build.gradle.kts b/plugins/markdown2resource/build.gradle.kts index fa309a6e6..07ad90095 100644 --- a/plugins/markdown2resource/build.gradle.kts +++ b/plugins/markdown2resource/build.gradle.kts @@ -22,11 +22,6 @@ plugins { kotlin("jvm") version "1.9.20" } -repositories { - google() - mavenCentral() -} - group = "app.pachli.plugins" version = "0.0.1" diff --git a/plugins/markdown2resource/gradle.properties b/plugins/markdown2resource/gradle.properties new file mode 100644 index 000000000..328a2a1fa --- /dev/null +++ b/plugins/markdown2resource/gradle.properties @@ -0,0 +1,21 @@ +# +# Copyright 2023 Pachli Association +# +# This file is a part of Pachli. +# +# This program is free software; you can redistribute it and/or modify it under the terms of the +# GNU General Public License as published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even +# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along with Pachli; if not, +# see . +# + +# Gradle properties are not passed to included builds https://github.com/gradle/gradle/issues/2534 +org.gradle.parallel=true +org.gradle.caching=true +org.gradle.configureondemand=true diff --git a/plugins/markdown2resource/settings.gradle b/plugins/markdown2resource/settings.gradle deleted file mode 100644 index c8b759b7a..000000000 --- a/plugins/markdown2resource/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -rootProject.name = "markdown2resource-plugin" diff --git a/plugins/markdown2resource/settings.gradle.kts b/plugins/markdown2resource/settings.gradle.kts new file mode 100644 index 000000000..eb39e6c92 --- /dev/null +++ b/plugins/markdown2resource/settings.gradle.kts @@ -0,0 +1,30 @@ +/* + * Copyright 2023 Pachli Association + * + * This file is a part of Pachli. + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Pachli; if not, + * see . + */ + +dependencyResolutionManagement { + repositories { + google() + mavenCentral() + } + versionCatalogs { + create("libs") { + from(files("../../gradle/libs.versions.toml")) + } + } +} + +rootProject.name = "markdown2resource-plugin" diff --git a/settings.gradle b/settings.gradle deleted file mode 100644 index 4dd3ebaac..000000000 --- a/settings.gradle +++ /dev/null @@ -1,23 +0,0 @@ -pluginManagement { - repositories { - google() - gradlePluginPortal() - } - - includeBuild 'plugins/markdown2resource' -} - -dependencyResolutionManagement { - repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) - repositories { - google() - mavenCentral() - maven { url 'https://jitpack.io' } - } -} - -enableFeaturePreview("STABLE_CONFIGURATION_CACHE") - -include ':app' -include ':tools:mklanguages' -include ':checks' diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 000000000..3c8e22ee0 --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1,33 @@ +pluginManagement { + repositories { + google() + gradlePluginPortal() + } + + includeBuild("build-logic") + includeBuild("plugins/markdown2resource") +} + +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { + google() + mavenCentral() + maven("https://jitpack.io") + } +} + +enableFeaturePreview("STABLE_CONFIGURATION_CACHE") +enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") + +rootProject.name = "pachli-android" + +include(":app") +include(":core:accounts") +include(":core:common") +include(":core:database") +include(":core:preferences") +include(":core:network") +include(":core:testing") +include(":tools:mklanguages") +include(":checks") diff --git a/tools/build.gradle.kts b/tools/build.gradle.kts index 0f105dd53..00c2eeae9 100644 --- a/tools/build.gradle.kts +++ b/tools/build.gradle.kts @@ -22,7 +22,7 @@ subprojects { apply(plugin = "application") dependencies { - "implementation"("com.github.ajalt.clikt:clikt:3.5.4") + add("implementation", "com.github.ajalt.clikt:clikt:3.5.4") } tasks.withType().configureEach { diff --git a/tools/mklanguages/settings.gradle.kts b/tools/mklanguages/settings.gradle.kts new file mode 100644 index 000000000..56f78cb51 --- /dev/null +++ b/tools/mklanguages/settings.gradle.kts @@ -0,0 +1,30 @@ +/* + * Copyright 2023 Pachli Association + * + * This file is a part of Pachli. + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Pachli; if not, + * see . + */ + +dependencyResolutionManagement { + repositories { + google() + mavenCentral() + } + versionCatalogs { + create("libs") { + from(files("../../gradle/libs.versions.toml")) + } + } +} + +rootProject.name = "mklanguages"