├── .editorconfig
├── .gemini
└── config.yaml
├── .gitattributes
├── .github
├── FUNDING.yml
├── ISSUE_TEMPLATE
│ ├── 1_request_feature.yml
│ ├── 2_report_issue.yml
│ └── config.yml
├── dependabot.yml
├── pull_request_template.md
├── readme-images
│ ├── app-icon.png
│ └── screens.png
├── scripts
│ └── release_note_generate.sh
└── workflows
│ ├── build_benchmark.yml
│ ├── build_dispatch_preview.yml
│ ├── build_preview.yml
│ ├── build_pull_request.yml
│ ├── build_push.yml
│ ├── build_release.yml
│ ├── codeberg_mirror.yml
│ ├── delete_merged_branch.yml
│ ├── pr_label.yml
│ └── update_website.yml
├── .gitignore
├── .idea
└── icon.png
├── .weblate
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── app
├── build.gradle.kts
├── proguard-android-optimize.txt
├── proguard-rules.pro
└── src
│ ├── beta
│ └── res
│ │ ├── drawable
│ │ ├── ic_launcher_background.xml
│ │ ├── ic_launcher_foreground.xml
│ │ └── komikku.png
│ │ ├── values
│ │ └── colors.xml
│ │ └── xml
│ │ └── shortcuts.xml
│ ├── debug
│ └── res
│ │ ├── drawable
│ │ ├── ic_launcher_background.xml
│ │ ├── ic_launcher_foreground.xml
│ │ └── komikku.png
│ │ └── values
│ │ └── colors.xml
│ ├── main
│ ├── AndroidManifest.xml
│ ├── baseline-prof.txt
│ ├── java
│ │ ├── eu
│ │ │ └── kanade
│ │ │ │ ├── core
│ │ │ │ ├── preference
│ │ │ │ │ ├── CheckboxState.kt
│ │ │ │ │ └── PreferenceMutableState.kt
│ │ │ │ └── util
│ │ │ │ │ ├── CollectionUtils.kt
│ │ │ │ │ └── SourceUtil.kt
│ │ │ │ ├── domain
│ │ │ │ ├── DomainModule.kt
│ │ │ │ ├── KMKDomainModule.kt
│ │ │ │ ├── SYDomainModule.kt
│ │ │ │ ├── base
│ │ │ │ │ ├── BasePreferences.kt
│ │ │ │ │ └── ExtensionInstallerPreference.kt
│ │ │ │ ├── chapter
│ │ │ │ │ ├── interactor
│ │ │ │ │ │ ├── GetAvailableScanlators.kt
│ │ │ │ │ │ ├── SetReadStatus.kt
│ │ │ │ │ │ └── SyncChaptersWithSource.kt
│ │ │ │ │ └── model
│ │ │ │ │ │ ├── Chapter.kt
│ │ │ │ │ │ └── ChapterFilter.kt
│ │ │ │ ├── download
│ │ │ │ │ └── interactor
│ │ │ │ │ │ └── DeleteDownload.kt
│ │ │ │ ├── extension
│ │ │ │ │ ├── interactor
│ │ │ │ │ │ ├── GetExtensionLanguages.kt
│ │ │ │ │ │ ├── GetExtensionSources.kt
│ │ │ │ │ │ ├── GetExtensionsByType.kt
│ │ │ │ │ │ └── TrustExtension.kt
│ │ │ │ │ └── model
│ │ │ │ │ │ └── Extensions.kt
│ │ │ │ ├── manga
│ │ │ │ │ ├── interactor
│ │ │ │ │ │ ├── CreateSortTag.kt
│ │ │ │ │ │ ├── DeleteSortTag.kt
│ │ │ │ │ │ ├── GetExcludedScanlators.kt
│ │ │ │ │ │ ├── GetPagePreviews.kt
│ │ │ │ │ │ ├── GetSortTag.kt
│ │ │ │ │ │ ├── ReorderSortTag.kt
│ │ │ │ │ │ ├── SetExcludedScanlators.kt
│ │ │ │ │ │ ├── SetMangaViewerFlags.kt
│ │ │ │ │ │ ├── SmartSearchMerge.kt
│ │ │ │ │ │ └── UpdateManga.kt
│ │ │ │ │ └── model
│ │ │ │ │ │ ├── Manga.kt
│ │ │ │ │ │ └── PagePreview.kt
│ │ │ │ ├── source
│ │ │ │ │ ├── interactor
│ │ │ │ │ │ ├── CreateSourceCategory.kt
│ │ │ │ │ │ ├── DeleteSourceCategory.kt
│ │ │ │ │ │ ├── GetEnabledSources.kt
│ │ │ │ │ │ ├── GetExhSavedSearch.kt
│ │ │ │ │ │ ├── GetIncognitoState.kt
│ │ │ │ │ │ ├── GetLanguagesWithSources.kt
│ │ │ │ │ │ ├── GetShowLatest.kt
│ │ │ │ │ │ ├── GetSourceCategories.kt
│ │ │ │ │ │ ├── GetSourcesWithFavoriteCount.kt
│ │ │ │ │ │ ├── RenameSourceCategory.kt
│ │ │ │ │ │ ├── SetMigrateSorting.kt
│ │ │ │ │ │ ├── SetSourceCategories.kt
│ │ │ │ │ │ ├── ToggleExcludeFromDataSaver.kt
│ │ │ │ │ │ ├── ToggleIncognito.kt
│ │ │ │ │ │ ├── ToggleLanguage.kt
│ │ │ │ │ │ ├── ToggleSource.kt
│ │ │ │ │ │ └── ToggleSourcePin.kt
│ │ │ │ │ ├── model
│ │ │ │ │ │ └── Source.kt
│ │ │ │ │ └── service
│ │ │ │ │ │ └── SourcePreferences.kt
│ │ │ │ ├── sync
│ │ │ │ │ ├── SyncPreferences.kt
│ │ │ │ │ └── models
│ │ │ │ │ │ └── SyncSettings.kt
│ │ │ │ ├── track
│ │ │ │ │ ├── interactor
│ │ │ │ │ │ ├── AddTracks.kt
│ │ │ │ │ │ ├── RefreshTracks.kt
│ │ │ │ │ │ ├── SyncChapterProgressWithTrack.kt
│ │ │ │ │ │ └── TrackChapter.kt
│ │ │ │ │ ├── model
│ │ │ │ │ │ ├── AutoTrackState.kt
│ │ │ │ │ │ └── Track.kt
│ │ │ │ │ ├── service
│ │ │ │ │ │ ├── DelayedTrackingUpdateJob.kt
│ │ │ │ │ │ └── TrackPreferences.kt
│ │ │ │ │ └── store
│ │ │ │ │ │ └── DelayedTrackingStore.kt
│ │ │ │ └── ui
│ │ │ │ │ ├── UiPreferences.kt
│ │ │ │ │ └── model
│ │ │ │ │ ├── AppTheme.kt
│ │ │ │ │ ├── TabletUiMode.kt
│ │ │ │ │ └── ThemeMode.kt
│ │ │ │ ├── presentation
│ │ │ │ ├── browse
│ │ │ │ │ ├── BrowseSourceScreen.kt
│ │ │ │ │ ├── BrowseTabWrapper.kt
│ │ │ │ │ ├── ExtensionDetailsScreen.kt
│ │ │ │ │ ├── ExtensionFilterScreen.kt
│ │ │ │ │ ├── ExtensionsScreen.kt
│ │ │ │ │ ├── FeedOrderScreen.kt
│ │ │ │ │ ├── FeedScreen.kt
│ │ │ │ │ ├── GlobalSearchScreen.kt
│ │ │ │ │ ├── MigrateMangaScreen.kt
│ │ │ │ │ ├── MigrateSearchScreen.kt
│ │ │ │ │ ├── MigrateSourceScreen.kt
│ │ │ │ │ ├── MigrationListScreen.kt
│ │ │ │ │ ├── RelatedMangasScreen.kt
│ │ │ │ │ ├── SourceFeedOrderScreen.kt
│ │ │ │ │ ├── SourceFeedScreen.kt
│ │ │ │ │ ├── SourcesFilterScreen.kt
│ │ │ │ │ ├── SourcesScreen.kt
│ │ │ │ │ └── components
│ │ │ │ │ │ ├── BaseBrowseItem.kt
│ │ │ │ │ │ ├── BaseSourceItem.kt
│ │ │ │ │ │ ├── BrowseBadges.kt
│ │ │ │ │ │ ├── BrowseIcons.kt
│ │ │ │ │ │ ├── BrowseSourceComfortableGrid.kt
│ │ │ │ │ │ ├── BrowseSourceCompactGrid.kt
│ │ │ │ │ │ ├── BrowseSourceDialogs.kt
│ │ │ │ │ │ ├── BrowseSourceEHentaiList.kt
│ │ │ │ │ │ ├── BrowseSourceFloatingActionButton.kt
│ │ │ │ │ │ ├── BrowseSourceList.kt
│ │ │ │ │ │ ├── BrowseSourceLoadingItem.kt
│ │ │ │ │ │ ├── BrowseSourceSimpleToolbar.kt
│ │ │ │ │ │ ├── BrowseSourceToolbar.kt
│ │ │ │ │ │ ├── BulkFavoriteDialogs.kt
│ │ │ │ │ │ ├── FeedOrderListItem.kt
│ │ │ │ │ │ ├── GlobalSearchCardRow.kt
│ │ │ │ │ │ ├── GlobalSearchResultItems.kt
│ │ │ │ │ │ ├── GlobalSearchToolbar.kt
│ │ │ │ │ │ ├── MigrationActionIcon.kt
│ │ │ │ │ │ ├── MigrationExitDialog.kt
│ │ │ │ │ │ ├── MigrationItem.kt
│ │ │ │ │ │ ├── MigrationItemResult.kt
│ │ │ │ │ │ ├── MigrationMangaDialog.kt
│ │ │ │ │ │ ├── MigrationProgressDialog.kt
│ │ │ │ │ │ ├── RelatedMangasComfortableGrid.kt
│ │ │ │ │ │ ├── RelatedMangasCompactGrid.kt
│ │ │ │ │ │ ├── RelatedMangasList.kt
│ │ │ │ │ │ └── SourceFeedDialogs.kt
│ │ │ │ ├── category
│ │ │ │ │ ├── BiometricTimesScreen.kt
│ │ │ │ │ ├── CategoryExtensions.kt
│ │ │ │ │ ├── CategoryScreen.kt
│ │ │ │ │ ├── SortTagScreen.kt
│ │ │ │ │ ├── SourceCategoryScreen.kt
│ │ │ │ │ └── components
│ │ │ │ │ │ ├── CategoryDialogs.kt
│ │ │ │ │ │ ├── CategoryFloatingActionButton.kt
│ │ │ │ │ │ ├── CategoryListItem.kt
│ │ │ │ │ │ ├── biometric
│ │ │ │ │ │ ├── BiometricTimesContent.kt
│ │ │ │ │ │ └── BiometricTimesListItem.kt
│ │ │ │ │ │ ├── genre
│ │ │ │ │ │ ├── SortTagContent.kt
│ │ │ │ │ │ └── SortTagListItem.kt
│ │ │ │ │ │ └── sources
│ │ │ │ │ │ ├── SourceCategoryContent.kt
│ │ │ │ │ │ └── SourceCategoryListItem.kt
│ │ │ │ ├── components
│ │ │ │ │ ├── AdaptiveSheet.kt
│ │ │ │ │ ├── AppBar.kt
│ │ │ │ │ ├── AroundLayout.kt
│ │ │ │ │ ├── Banners.kt
│ │ │ │ │ ├── BulkSelectionToolbar.kt
│ │ │ │ │ ├── Chip.kt
│ │ │ │ │ ├── DateText.kt
│ │ │ │ │ ├── DownloadDropdownMenu.kt
│ │ │ │ │ ├── DropdownMenu.kt
│ │ │ │ │ ├── EmptyScreen.kt
│ │ │ │ │ ├── SourceSearchBox.kt
│ │ │ │ │ ├── SpinnerAdapter.kt
│ │ │ │ │ ├── TabbedDialog.kt
│ │ │ │ │ └── TabbedScreen.kt
│ │ │ │ ├── crash
│ │ │ │ │ └── CrashScreen.kt
│ │ │ │ ├── history
│ │ │ │ │ ├── HistoryScreen.kt
│ │ │ │ │ ├── HistoryScreenModelStateProvider.kt
│ │ │ │ │ └── components
│ │ │ │ │ │ ├── HistoryDialogs.kt
│ │ │ │ │ │ ├── HistoryItem.kt
│ │ │ │ │ │ └── HistoryWithRelationsProvider.kt
│ │ │ │ ├── library
│ │ │ │ │ ├── DeleteLibraryMangaDialog.kt
│ │ │ │ │ ├── LibrarySettingsDialog.kt
│ │ │ │ │ └── components
│ │ │ │ │ │ ├── CommonMangaItem.kt
│ │ │ │ │ │ ├── GlobalSearchItem.kt
│ │ │ │ │ │ ├── LazyLibraryGrid.kt
│ │ │ │ │ │ ├── LibraryBadges.kt
│ │ │ │ │ │ ├── LibraryComfortableGrid.kt
│ │ │ │ │ │ ├── LibraryCompactGrid.kt
│ │ │ │ │ │ ├── LibraryContent.kt
│ │ │ │ │ │ ├── LibraryList.kt
│ │ │ │ │ │ ├── LibraryPager.kt
│ │ │ │ │ │ ├── LibraryTabs.kt
│ │ │ │ │ │ ├── LibraryToolbar.kt
│ │ │ │ │ │ ├── SyncFavoritesConfirmDialog.kt
│ │ │ │ │ │ ├── SyncFavoritesProgressDialog.kt
│ │ │ │ │ │ └── SyncFavoritesWarningDialog.kt
│ │ │ │ ├── libraryUpdateError
│ │ │ │ │ ├── LibraryUpdateErrorScreen.kt
│ │ │ │ │ └── components
│ │ │ │ │ │ └── LibraryUpdateErrorUiItem.kt
│ │ │ │ ├── manga
│ │ │ │ │ ├── ChapterSettingsDialog.kt
│ │ │ │ │ ├── DuplicateMangaDialog.kt
│ │ │ │ │ ├── MangaNotesScreen.kt
│ │ │ │ │ ├── MangaScreen.kt
│ │ │ │ │ ├── MangaScreenConstants.kt
│ │ │ │ │ └── components
│ │ │ │ │ │ ├── BaseMangaListItem.kt
│ │ │ │ │ │ ├── ChapterDownloadIndicator.kt
│ │ │ │ │ │ ├── ChapterHeader.kt
│ │ │ │ │ │ ├── DotSeparatorText.kt
│ │ │ │ │ │ ├── MangaBottomActionMenu.kt
│ │ │ │ │ │ ├── MangaChapterListItem.kt
│ │ │ │ │ │ ├── MangaCover.kt
│ │ │ │ │ │ ├── MangaCoverDialog.kt
│ │ │ │ │ │ ├── MangaDialogs.kt
│ │ │ │ │ │ ├── MangaInfoButtons.kt
│ │ │ │ │ │ ├── MangaInfoHeader.kt
│ │ │ │ │ │ ├── MangaNotesDisplay.kt
│ │ │ │ │ │ ├── MangaNotesSection.kt
│ │ │ │ │ │ ├── MangaNotesTextArea.kt
│ │ │ │ │ │ ├── MangaToolbar.kt
│ │ │ │ │ │ ├── MarkdownRender.kt
│ │ │ │ │ │ ├── MissingChapterCountListItem.kt
│ │ │ │ │ │ ├── NamespaceTags.kt
│ │ │ │ │ │ ├── OutlineButtonWithArrow.kt
│ │ │ │ │ │ ├── PagePreviews.kt
│ │ │ │ │ │ ├── RelatedMangasRow.kt
│ │ │ │ │ │ └── ScanlatorFilterDialog.kt
│ │ │ │ ├── more
│ │ │ │ │ ├── ComingUpdatesScreen.kt
│ │ │ │ │ ├── LogoHeader.kt
│ │ │ │ │ ├── MoreScreen.kt
│ │ │ │ │ ├── NewUpdateScreen.kt
│ │ │ │ │ ├── WhatsNewScreen.kt
│ │ │ │ │ ├── onboarding
│ │ │ │ │ │ ├── GuidesStep.kt
│ │ │ │ │ │ ├── OnboardingScreen.kt
│ │ │ │ │ │ ├── OnboardingStep.kt
│ │ │ │ │ │ ├── PermissionStep.kt
│ │ │ │ │ │ ├── StorageStep.kt
│ │ │ │ │ │ └── ThemeStep.kt
│ │ │ │ │ ├── settings
│ │ │ │ │ │ ├── Preference.kt
│ │ │ │ │ │ ├── PreferenceItem.kt
│ │ │ │ │ │ ├── PreferenceScaffold.kt
│ │ │ │ │ │ ├── PreferenceScreen.kt
│ │ │ │ │ │ ├── screen
│ │ │ │ │ │ │ ├── Commons.kt
│ │ │ │ │ │ │ ├── ConfigureExhDialog.kt
│ │ │ │ │ │ │ ├── SearchableSettings.kt
│ │ │ │ │ │ │ ├── SettingsAdvancedScreen.kt
│ │ │ │ │ │ │ ├── SettingsAppearanceScreen.kt
│ │ │ │ │ │ │ ├── SettingsBrowseScreen.kt
│ │ │ │ │ │ │ ├── SettingsDataScreen.kt
│ │ │ │ │ │ │ ├── SettingsDownloadScreen.kt
│ │ │ │ │ │ │ ├── SettingsEhScreen.kt
│ │ │ │ │ │ │ ├── SettingsLibraryScreen.kt
│ │ │ │ │ │ │ ├── SettingsMainScreen.kt
│ │ │ │ │ │ │ ├── SettingsMangadexScreen.kt
│ │ │ │ │ │ │ ├── SettingsReaderScreen.kt
│ │ │ │ │ │ │ ├── SettingsSearchScreen.kt
│ │ │ │ │ │ │ ├── SettingsSecurityScreen.kt
│ │ │ │ │ │ │ ├── SettingsTrackingScreen.kt
│ │ │ │ │ │ │ ├── about
│ │ │ │ │ │ │ │ ├── AboutScreen.kt
│ │ │ │ │ │ │ │ ├── OpenSourceLibraryLicenseScreen.kt
│ │ │ │ │ │ │ │ ├── OpenSourceLicensesScreen.kt
│ │ │ │ │ │ │ │ └── WhatsNewDialog.kt
│ │ │ │ │ │ │ ├── advanced
│ │ │ │ │ │ │ │ └── ClearDatabaseScreen.kt
│ │ │ │ │ │ │ ├── appearance
│ │ │ │ │ │ │ │ ├── AppCustomThemeColorPickerScreen.kt
│ │ │ │ │ │ │ │ └── AppLanguageScreen.kt
│ │ │ │ │ │ │ ├── browse
│ │ │ │ │ │ │ │ ├── ExtensionReposScreen.kt
│ │ │ │ │ │ │ │ ├── ExtensionReposScreenModel.kt
│ │ │ │ │ │ │ │ └── components
│ │ │ │ │ │ │ │ │ ├── ExtensionReposContent.kt
│ │ │ │ │ │ │ │ │ ├── ExtensionReposDialogs.kt
│ │ │ │ │ │ │ │ │ └── ExtensionReposScreen.kt
│ │ │ │ │ │ │ ├── data
│ │ │ │ │ │ │ │ ├── CreateBackupScreen.kt
│ │ │ │ │ │ │ │ ├── RestoreBackupScreen.kt
│ │ │ │ │ │ │ │ ├── StorageInfo.kt
│ │ │ │ │ │ │ │ ├── SyncSettingsSelector.kt
│ │ │ │ │ │ │ │ └── SyncTriggerOptionsScreen.kt
│ │ │ │ │ │ │ └── debug
│ │ │ │ │ │ │ │ ├── BackupSchemaScreen.kt
│ │ │ │ │ │ │ │ ├── DebugInfoScreen.kt
│ │ │ │ │ │ │ │ └── WorkerInfoScreen.kt
│ │ │ │ │ │ └── widget
│ │ │ │ │ │ │ ├── AppThemeModePreferenceWidget.kt
│ │ │ │ │ │ │ ├── AppThemePreferenceWidget.kt
│ │ │ │ │ │ │ ├── BasePreferenceWidget.kt
│ │ │ │ │ │ │ ├── EditTextPreferenceWidget.kt
│ │ │ │ │ │ │ ├── InfoWidget.kt
│ │ │ │ │ │ │ ├── ListPreferenceWidget.kt
│ │ │ │ │ │ │ ├── MultiSelectListPreferenceWidget.kt
│ │ │ │ │ │ │ ├── PreferenceGroupHeader.kt
│ │ │ │ │ │ │ ├── SwitchPreferenceWidget.kt
│ │ │ │ │ │ │ ├── TextPreferenceWidget.kt
│ │ │ │ │ │ │ ├── ThemeColorPickerWidget.kt
│ │ │ │ │ │ │ ├── TrackingPreferenceWidget.kt
│ │ │ │ │ │ │ └── TriStateListDialog.kt
│ │ │ │ │ └── stats
│ │ │ │ │ │ ├── StatsScreenContent.kt
│ │ │ │ │ │ ├── StatsScreenState.kt
│ │ │ │ │ │ ├── components
│ │ │ │ │ │ └── StatsItem.kt
│ │ │ │ │ │ └── data
│ │ │ │ │ │ └── StatsData.kt
│ │ │ │ ├── reader
│ │ │ │ │ ├── ChapterListDialog.kt
│ │ │ │ │ ├── ChapterTransition.kt
│ │ │ │ │ ├── DisplayRefreshHost.kt
│ │ │ │ │ ├── OrientationSelectDialog.kt
│ │ │ │ │ ├── PageIndicatorText.kt
│ │ │ │ │ ├── ReaderContentOverlay.kt
│ │ │ │ │ ├── ReaderPageActionsDialog.kt
│ │ │ │ │ ├── ReadingModeSelectDialog.kt
│ │ │ │ │ ├── appbars
│ │ │ │ │ │ ├── BottomReaderBar.kt
│ │ │ │ │ │ ├── ExhUtils.kt
│ │ │ │ │ │ └── ReaderAppBars.kt
│ │ │ │ │ ├── components
│ │ │ │ │ │ ├── ChapterNavigator.kt
│ │ │ │ │ │ └── ModeSelectionDialog.kt
│ │ │ │ │ └── settings
│ │ │ │ │ │ ├── ColorFilterPage.kt
│ │ │ │ │ │ ├── GeneralSettingsPage.kt
│ │ │ │ │ │ ├── ReaderSettingsDialog.kt
│ │ │ │ │ │ └── ReadingModePage.kt
│ │ │ │ ├── theme
│ │ │ │ │ ├── TachiyomiTheme.kt
│ │ │ │ │ └── colorscheme
│ │ │ │ │ │ ├── BaseColorScheme.kt
│ │ │ │ │ │ ├── CloudflareColorScheme.kt
│ │ │ │ │ │ ├── CottoncandyColorScheme.kt
│ │ │ │ │ │ ├── CustomColorScheme.kt
│ │ │ │ │ │ ├── DoomColorScheme.kt
│ │ │ │ │ │ ├── GreenAppleColorScheme.kt
│ │ │ │ │ │ ├── LavenderColorScheme.kt
│ │ │ │ │ │ ├── MatrixColorScheme.kt
│ │ │ │ │ │ ├── MidnightDuskColorScheme.kt
│ │ │ │ │ │ ├── MochaColorScheme.kt
│ │ │ │ │ │ ├── MonetColorScheme.kt
│ │ │ │ │ │ ├── MonochromeColorScheme.kt
│ │ │ │ │ │ ├── NordColorScheme.kt
│ │ │ │ │ │ ├── SapphireColorScheme.kt
│ │ │ │ │ │ ├── StrawberryColorScheme.kt
│ │ │ │ │ │ ├── TachiyomiColorScheme.kt
│ │ │ │ │ │ ├── TakoColorScheme.kt
│ │ │ │ │ │ ├── TealTurqoiseColorScheme.kt
│ │ │ │ │ │ ├── TidalWaveColorScheme.kt
│ │ │ │ │ │ ├── YinYangColorScheme.kt
│ │ │ │ │ │ └── YotsubaColorScheme.kt
│ │ │ │ ├── track
│ │ │ │ │ ├── TrackInfoDialogHome.kt
│ │ │ │ │ ├── TrackInfoDialogHomePreviewProvider.kt
│ │ │ │ │ ├── TrackInfoDialogSelector.kt
│ │ │ │ │ ├── TrackerSearch.kt
│ │ │ │ │ ├── TrackerSearchPreviewProvider.kt
│ │ │ │ │ └── components
│ │ │ │ │ │ ├── TrackLogoIcon.kt
│ │ │ │ │ │ └── TrackLogoIconPreviewProvider.kt
│ │ │ │ ├── updates
│ │ │ │ │ ├── UpdatesDialog.kt
│ │ │ │ │ ├── UpdatesScreen.kt
│ │ │ │ │ └── UpdatesUiItem.kt
│ │ │ │ ├── util
│ │ │ │ │ ├── ChapterNumberFormatter.kt
│ │ │ │ │ ├── ExceptionFormatter.kt
│ │ │ │ │ ├── FastScrollAnimateItem.kt
│ │ │ │ │ ├── Navigator.kt
│ │ │ │ │ ├── Permissions.kt
│ │ │ │ │ ├── Resources.kt
│ │ │ │ │ ├── TimeUtils.kt
│ │ │ │ │ └── WindowSize.kt
│ │ │ │ └── webview
│ │ │ │ │ ├── EhLoginWebViewScreen.kt
│ │ │ │ │ ├── WebViewScreenContent.kt
│ │ │ │ │ └── components
│ │ │ │ │ └── IgneousDialog.kt
│ │ │ │ ├── tachiyomi
│ │ │ │ ├── App.kt
│ │ │ │ ├── AppInfo.kt
│ │ │ │ ├── crash
│ │ │ │ │ ├── CrashActivity.kt
│ │ │ │ │ └── GlobalExceptionHandler.kt
│ │ │ │ ├── data
│ │ │ │ │ ├── BannerProgressStatus.kt
│ │ │ │ │ ├── backup
│ │ │ │ │ │ ├── BackupDecoder.kt
│ │ │ │ │ │ ├── BackupFileValidator.kt
│ │ │ │ │ │ ├── BackupNotifier.kt
│ │ │ │ │ │ ├── create
│ │ │ │ │ │ │ ├── BackupCreateJob.kt
│ │ │ │ │ │ │ ├── BackupCreator.kt
│ │ │ │ │ │ │ ├── BackupOptions.kt
│ │ │ │ │ │ │ └── creators
│ │ │ │ │ │ │ │ ├── CategoriesBackupCreator.kt
│ │ │ │ │ │ │ │ ├── ExtensionRepoBackupCreator.kt
│ │ │ │ │ │ │ │ ├── FeedBackupCreator.kt
│ │ │ │ │ │ │ │ ├── MangaBackupCreator.kt
│ │ │ │ │ │ │ │ ├── PreferenceBackupCreator.kt
│ │ │ │ │ │ │ │ ├── SavedSearchBackupCreator.kt
│ │ │ │ │ │ │ │ └── SourcesBackupCreator.kt
│ │ │ │ │ │ ├── models
│ │ │ │ │ │ │ ├── Backup.kt
│ │ │ │ │ │ │ ├── BackupCategory.kt
│ │ │ │ │ │ │ ├── BackupChapter.kt
│ │ │ │ │ │ │ ├── BackupExtensionRepos.kt
│ │ │ │ │ │ │ ├── BackupFeed.kt
│ │ │ │ │ │ │ ├── BackupFlatMetadata.kt
│ │ │ │ │ │ │ ├── BackupHistory.kt
│ │ │ │ │ │ │ ├── BackupManga.kt
│ │ │ │ │ │ │ ├── BackupMergedMangaReference.kt
│ │ │ │ │ │ │ ├── BackupPreference.kt
│ │ │ │ │ │ │ ├── BackupSavedSearch.kt
│ │ │ │ │ │ │ ├── BackupSource.kt
│ │ │ │ │ │ │ ├── BackupTracking.kt
│ │ │ │ │ │ │ └── metadata
│ │ │ │ │ │ │ │ ├── BackupSearchMetadata.kt
│ │ │ │ │ │ │ │ ├── BackupSearchTag.kt
│ │ │ │ │ │ │ │ └── BackupSearchTitle.kt
│ │ │ │ │ │ └── restore
│ │ │ │ │ │ │ ├── BackupRestoreJob.kt
│ │ │ │ │ │ │ ├── BackupRestorer.kt
│ │ │ │ │ │ │ ├── RestoreOptions.kt
│ │ │ │ │ │ │ └── restorers
│ │ │ │ │ │ │ ├── CategoriesRestorer.kt
│ │ │ │ │ │ │ ├── ExtensionRepoRestorer.kt
│ │ │ │ │ │ │ ├── FeedRestorer.kt
│ │ │ │ │ │ │ ├── MangaRestorer.kt
│ │ │ │ │ │ │ ├── PreferenceRestorer.kt
│ │ │ │ │ │ │ └── SavedSearchRestorer.kt
│ │ │ │ │ ├── cache
│ │ │ │ │ │ ├── ChapterCache.kt
│ │ │ │ │ │ ├── CoverCache.kt
│ │ │ │ │ │ └── PagePreviewCache.kt
│ │ │ │ │ ├── coil
│ │ │ │ │ │ ├── BufferedSourceFetcher.kt
│ │ │ │ │ │ ├── MangaCoverFetcher.kt
│ │ │ │ │ │ ├── MangaCoverKeyer.kt
│ │ │ │ │ │ ├── MangaCoverMetadata.kt
│ │ │ │ │ │ ├── PagePreviewFetcher.kt
│ │ │ │ │ │ ├── PagePreviewKeyer.kt
│ │ │ │ │ │ ├── TachiyomiImageDecoder.kt
│ │ │ │ │ │ └── Utils.kt
│ │ │ │ │ ├── database
│ │ │ │ │ │ └── models
│ │ │ │ │ │ │ ├── Chapter.kt
│ │ │ │ │ │ │ ├── ChapterImpl.kt
│ │ │ │ │ │ │ ├── Track.kt
│ │ │ │ │ │ │ └── TrackImpl.kt
│ │ │ │ │ ├── download
│ │ │ │ │ │ ├── DownloadCache.kt
│ │ │ │ │ │ ├── DownloadJob.kt
│ │ │ │ │ │ ├── DownloadManager.kt
│ │ │ │ │ │ ├── DownloadNotifier.kt
│ │ │ │ │ │ ├── DownloadPendingDeleter.kt
│ │ │ │ │ │ ├── DownloadProvider.kt
│ │ │ │ │ │ ├── DownloadStore.kt
│ │ │ │ │ │ ├── Downloader.kt
│ │ │ │ │ │ └── model
│ │ │ │ │ │ │ └── Download.kt
│ │ │ │ │ ├── export
│ │ │ │ │ │ └── LibraryExporter.kt
│ │ │ │ │ ├── library
│ │ │ │ │ │ ├── LibraryUpdateJob.kt
│ │ │ │ │ │ ├── LibraryUpdateNotifier.kt
│ │ │ │ │ │ └── MetadataUpdateJob.kt
│ │ │ │ │ ├── notification
│ │ │ │ │ │ ├── NotificationHandler.kt
│ │ │ │ │ │ ├── NotificationReceiver.kt
│ │ │ │ │ │ └── Notifications.kt
│ │ │ │ │ ├── preference
│ │ │ │ │ │ └── SharedPreferencesDataStore.kt
│ │ │ │ │ ├── saver
│ │ │ │ │ │ └── ImageSaver.kt
│ │ │ │ │ ├── sync
│ │ │ │ │ │ ├── SyncDataJob.kt
│ │ │ │ │ │ ├── SyncManager.kt
│ │ │ │ │ │ ├── SyncNotifier.kt
│ │ │ │ │ │ ├── models
│ │ │ │ │ │ │ └── SyncTriggerOptions.kt
│ │ │ │ │ │ └── service
│ │ │ │ │ │ │ ├── GoogleDriveSyncService.kt
│ │ │ │ │ │ │ ├── SyncService.kt
│ │ │ │ │ │ │ └── SyncYomiSyncService.kt
│ │ │ │ │ ├── track
│ │ │ │ │ │ ├── BaseTracker.kt
│ │ │ │ │ │ ├── DeletableTracker.kt
│ │ │ │ │ │ ├── EnhancedTracker.kt
│ │ │ │ │ │ ├── TrackStatus.kt
│ │ │ │ │ │ ├── Tracker.kt
│ │ │ │ │ │ ├── TrackerManager.kt
│ │ │ │ │ │ ├── anilist
│ │ │ │ │ │ │ ├── Anilist.kt
│ │ │ │ │ │ │ ├── AnilistApi.kt
│ │ │ │ │ │ │ ├── AnilistInterceptor.kt
│ │ │ │ │ │ │ ├── AnilistUtils.kt
│ │ │ │ │ │ │ └── dto
│ │ │ │ │ │ │ │ ├── ALAddManga.kt
│ │ │ │ │ │ │ │ ├── ALFuzzyDate.kt
│ │ │ │ │ │ │ │ ├── ALManga.kt
│ │ │ │ │ │ │ │ ├── ALMangaMetadata.kt
│ │ │ │ │ │ │ │ ├── ALOAuth.kt
│ │ │ │ │ │ │ │ ├── ALSearch.kt
│ │ │ │ │ │ │ │ ├── ALSearchItem.kt
│ │ │ │ │ │ │ │ ├── ALUser.kt
│ │ │ │ │ │ │ │ └── ALUserList.kt
│ │ │ │ │ │ ├── bangumi
│ │ │ │ │ │ │ ├── Bangumi.kt
│ │ │ │ │ │ │ ├── BangumiApi.kt
│ │ │ │ │ │ │ ├── BangumiInterceptor.kt
│ │ │ │ │ │ │ ├── BangumiUtils.kt
│ │ │ │ │ │ │ └── dto
│ │ │ │ │ │ │ │ ├── BGMCollectionResponse.kt
│ │ │ │ │ │ │ │ ├── BGMOAuth.kt
│ │ │ │ │ │ │ │ ├── BGMSearch.kt
│ │ │ │ │ │ │ │ ├── BGMSubject.kt
│ │ │ │ │ │ │ │ └── BGMUser.kt
│ │ │ │ │ │ ├── kavita
│ │ │ │ │ │ │ ├── Kavita.kt
│ │ │ │ │ │ │ ├── KavitaApi.kt
│ │ │ │ │ │ │ ├── KavitaInterceptor.kt
│ │ │ │ │ │ │ └── KavitaModels.kt
│ │ │ │ │ │ ├── kitsu
│ │ │ │ │ │ │ ├── Kitsu.kt
│ │ │ │ │ │ │ ├── KitsuApi.kt
│ │ │ │ │ │ │ ├── KitsuDateHelper.kt
│ │ │ │ │ │ │ ├── KitsuInterceptor.kt
│ │ │ │ │ │ │ ├── KitsuUtils.kt
│ │ │ │ │ │ │ └── dto
│ │ │ │ │ │ │ │ ├── KitsuAddManga.kt
│ │ │ │ │ │ │ │ ├── KitsuListSearch.kt
│ │ │ │ │ │ │ │ ├── KitsuMangaMetadata.kt
│ │ │ │ │ │ │ │ ├── KitsuOAuth.kt
│ │ │ │ │ │ │ │ ├── KitsuSearch.kt
│ │ │ │ │ │ │ │ ├── KitsuSearchItemCover.kt
│ │ │ │ │ │ │ │ └── KitsuUser.kt
│ │ │ │ │ │ ├── komga
│ │ │ │ │ │ │ ├── Komga.kt
│ │ │ │ │ │ │ ├── KomgaApi.kt
│ │ │ │ │ │ │ └── KomgaModels.kt
│ │ │ │ │ │ ├── mangaupdates
│ │ │ │ │ │ │ ├── MangaUpdates.kt
│ │ │ │ │ │ │ ├── MangaUpdatesApi.kt
│ │ │ │ │ │ │ ├── MangaUpdatesInterceptor.kt
│ │ │ │ │ │ │ └── dto
│ │ │ │ │ │ │ │ ├── MUContext.kt
│ │ │ │ │ │ │ │ ├── MUImage.kt
│ │ │ │ │ │ │ │ ├── MUListItem.kt
│ │ │ │ │ │ │ │ ├── MULoginResponse.kt
│ │ │ │ │ │ │ │ ├── MURating.kt
│ │ │ │ │ │ │ │ ├── MURecord.kt
│ │ │ │ │ │ │ │ ├── MUSearch.kt
│ │ │ │ │ │ │ │ ├── MUSeries.kt
│ │ │ │ │ │ │ │ ├── MUStatus.kt
│ │ │ │ │ │ │ │ └── MUUrl.kt
│ │ │ │ │ │ ├── mdlist
│ │ │ │ │ │ │ └── MdList.kt
│ │ │ │ │ │ ├── model
│ │ │ │ │ │ │ ├── TrackMangaMetadata.kt
│ │ │ │ │ │ │ └── TrackSearch.kt
│ │ │ │ │ │ ├── myanimelist
│ │ │ │ │ │ │ ├── MyAnimeList.kt
│ │ │ │ │ │ │ ├── MyAnimeListApi.kt
│ │ │ │ │ │ │ ├── MyAnimeListInterceptor.kt
│ │ │ │ │ │ │ ├── MyAnimeListUtils.kt
│ │ │ │ │ │ │ └── dto
│ │ │ │ │ │ │ │ ├── MALList.kt
│ │ │ │ │ │ │ │ ├── MALManga.kt
│ │ │ │ │ │ │ │ ├── MALOAuth.kt
│ │ │ │ │ │ │ │ ├── MALSearch.kt
│ │ │ │ │ │ │ │ ├── MALUser.kt
│ │ │ │ │ │ │ │ └── MALUserListSearch.kt
│ │ │ │ │ │ ├── shikimori
│ │ │ │ │ │ │ ├── Shikimori.kt
│ │ │ │ │ │ │ ├── ShikimoriApi.kt
│ │ │ │ │ │ │ ├── ShikimoriInterceptor.kt
│ │ │ │ │ │ │ ├── ShikimoriUtils.kt
│ │ │ │ │ │ │ └── dto
│ │ │ │ │ │ │ │ ├── SMAddMangaResponse.kt
│ │ │ │ │ │ │ │ ├── SMManga.kt
│ │ │ │ │ │ │ │ ├── SMMetadata.kt
│ │ │ │ │ │ │ │ ├── SMOAuth.kt
│ │ │ │ │ │ │ │ ├── SMUser.kt
│ │ │ │ │ │ │ │ └── SMUserListEntry.kt
│ │ │ │ │ │ └── suwayomi
│ │ │ │ │ │ │ ├── Suwayomi.kt
│ │ │ │ │ │ │ ├── SuwayomiApi.kt
│ │ │ │ │ │ │ └── SuwayomiModels.kt
│ │ │ │ │ └── updater
│ │ │ │ │ │ ├── AppUpdateBroadcast.kt
│ │ │ │ │ │ ├── AppUpdateChecker.kt
│ │ │ │ │ │ ├── AppUpdateDownloadJob.kt
│ │ │ │ │ │ ├── AppUpdateJob.kt
│ │ │ │ │ │ └── AppUpdateNotifier.kt
│ │ │ │ ├── di
│ │ │ │ │ ├── AppModule.kt
│ │ │ │ │ ├── PreferenceModule.kt
│ │ │ │ │ └── SYPreferenceModule.kt
│ │ │ │ ├── extension
│ │ │ │ │ ├── ExtensionManager.kt
│ │ │ │ │ ├── api
│ │ │ │ │ │ ├── ExtensionApi.kt
│ │ │ │ │ │ └── ExtensionUpdateNotifier.kt
│ │ │ │ │ ├── installer
│ │ │ │ │ │ ├── Installer.kt
│ │ │ │ │ │ ├── PackageInstallerInstaller.kt
│ │ │ │ │ │ └── ShizukuInstaller.kt
│ │ │ │ │ ├── model
│ │ │ │ │ │ ├── Extension.kt
│ │ │ │ │ │ ├── InstallStep.kt
│ │ │ │ │ │ └── LoadResult.kt
│ │ │ │ │ └── util
│ │ │ │ │ │ ├── ExtensionInstallActivity.kt
│ │ │ │ │ │ ├── ExtensionInstallReceiver.kt
│ │ │ │ │ │ ├── ExtensionInstallService.kt
│ │ │ │ │ │ ├── ExtensionInstaller.kt
│ │ │ │ │ │ └── ExtensionLoader.kt
│ │ │ │ ├── source
│ │ │ │ │ ├── AndroidSourceManager.kt
│ │ │ │ │ ├── SourceExtensions.kt
│ │ │ │ │ └── online
│ │ │ │ │ │ ├── all
│ │ │ │ │ │ ├── EHentai.kt
│ │ │ │ │ │ ├── MangaDex.kt
│ │ │ │ │ │ ├── MergedSource.kt
│ │ │ │ │ │ └── NHentai.kt
│ │ │ │ │ │ └── english
│ │ │ │ │ │ ├── EightMuses.kt
│ │ │ │ │ │ ├── HBrowse.kt
│ │ │ │ │ │ ├── Pururin.kt
│ │ │ │ │ │ └── Tsumino.kt
│ │ │ │ ├── ui
│ │ │ │ │ ├── base
│ │ │ │ │ │ ├── activity
│ │ │ │ │ │ │ └── BaseActivity.kt
│ │ │ │ │ │ └── delegate
│ │ │ │ │ │ │ ├── SecureActivityDelegate.kt
│ │ │ │ │ │ │ └── ThemingDelegate.kt
│ │ │ │ │ ├── browse
│ │ │ │ │ │ ├── BrowseTab.kt
│ │ │ │ │ │ ├── BulkFavoriteScreenModel.kt
│ │ │ │ │ │ ├── extension
│ │ │ │ │ │ │ ├── ExtensionFilterScreen.kt
│ │ │ │ │ │ │ ├── ExtensionFilterScreenModel.kt
│ │ │ │ │ │ │ ├── ExtensionsScreen.kt
│ │ │ │ │ │ │ ├── ExtensionsScreenModel.kt
│ │ │ │ │ │ │ ├── ExtensionsTab.kt
│ │ │ │ │ │ │ └── details
│ │ │ │ │ │ │ │ ├── ExtensionDetailsScreen.kt
│ │ │ │ │ │ │ │ ├── ExtensionDetailsScreenModel.kt
│ │ │ │ │ │ │ │ └── SourcePreferencesScreen.kt
│ │ │ │ │ │ ├── feed
│ │ │ │ │ │ │ ├── FeedScreenModel.kt
│ │ │ │ │ │ │ └── FeedTab.kt
│ │ │ │ │ │ ├── migration
│ │ │ │ │ │ │ ├── MigrationFlags.kt
│ │ │ │ │ │ │ ├── advanced
│ │ │ │ │ │ │ │ ├── design
│ │ │ │ │ │ │ │ │ ├── MigrationBottomSheetDialog.kt
│ │ │ │ │ │ │ │ │ ├── MigrationSourceAdapter.kt
│ │ │ │ │ │ │ │ │ ├── MigrationSourceHolder.kt
│ │ │ │ │ │ │ │ │ ├── MigrationSourceItem.kt
│ │ │ │ │ │ │ │ │ ├── PreMigrationScreen.kt
│ │ │ │ │ │ │ │ │ └── PreMigrationScreenModel.kt
│ │ │ │ │ │ │ │ └── process
│ │ │ │ │ │ │ │ │ ├── MigratingManga.kt
│ │ │ │ │ │ │ │ │ ├── MigrationListScreen.kt
│ │ │ │ │ │ │ │ │ ├── MigrationListScreenModel.kt
│ │ │ │ │ │ │ │ │ └── MigrationProcedureConfig.kt
│ │ │ │ │ │ │ ├── manga
│ │ │ │ │ │ │ │ ├── MigrateMangaScreen.kt
│ │ │ │ │ │ │ │ └── MigrateMangaScreenModel.kt
│ │ │ │ │ │ │ ├── search
│ │ │ │ │ │ │ │ ├── MigrateDialog.kt
│ │ │ │ │ │ │ │ ├── MigrateSearchScreen.kt
│ │ │ │ │ │ │ │ ├── MigrateSearchScreenDialogScreenModel.kt
│ │ │ │ │ │ │ │ ├── MigrateSearchScreenModel.kt
│ │ │ │ │ │ │ │ └── SourceSearchScreen.kt
│ │ │ │ │ │ │ └── sources
│ │ │ │ │ │ │ │ ├── MigrateSourceScreenModel.kt
│ │ │ │ │ │ │ │ └── MigrateSourceTab.kt
│ │ │ │ │ │ └── source
│ │ │ │ │ │ │ ├── SourcesFilterScreen.kt
│ │ │ │ │ │ │ ├── SourcesFilterScreenModel.kt
│ │ │ │ │ │ │ ├── SourcesScreen.kt
│ │ │ │ │ │ │ ├── SourcesScreenModel.kt
│ │ │ │ │ │ │ ├── SourcesTab.kt
│ │ │ │ │ │ │ ├── browse
│ │ │ │ │ │ │ ├── AutoCompleteItem.kt
│ │ │ │ │ │ │ ├── BrowseSourceScreen.kt
│ │ │ │ │ │ │ ├── BrowseSourceScreenModel.kt
│ │ │ │ │ │ │ ├── MangaDexFilterHeader.kt
│ │ │ │ │ │ │ ├── SavedSearchItem.kt
│ │ │ │ │ │ │ └── SourceFilterDialog.kt
│ │ │ │ │ │ │ ├── feed
│ │ │ │ │ │ │ ├── SourceFeedScreen.kt
│ │ │ │ │ │ │ └── SourceFeedScreenModel.kt
│ │ │ │ │ │ │ └── globalsearch
│ │ │ │ │ │ │ ├── GlobalSearchScreen.kt
│ │ │ │ │ │ │ ├── GlobalSearchScreenModel.kt
│ │ │ │ │ │ │ └── SearchScreenModel.kt
│ │ │ │ │ ├── category
│ │ │ │ │ │ ├── CategoryScreen.kt
│ │ │ │ │ │ ├── CategoryScreenModel.kt
│ │ │ │ │ │ ├── biometric
│ │ │ │ │ │ │ ├── BiometricTimesScreen.kt
│ │ │ │ │ │ │ ├── BiometricTimesScreenModel.kt
│ │ │ │ │ │ │ ├── TimeRange.kt
│ │ │ │ │ │ │ └── TimeRangeItem.kt
│ │ │ │ │ │ ├── genre
│ │ │ │ │ │ │ ├── SortTagScreen.kt
│ │ │ │ │ │ │ └── SortTagScreenModel.kt
│ │ │ │ │ │ └── sources
│ │ │ │ │ │ │ ├── SourceCategoryScreen.kt
│ │ │ │ │ │ │ └── SourceCategoryScreenModel.kt
│ │ │ │ │ ├── deeplink
│ │ │ │ │ │ ├── DeepLinkActivity.kt
│ │ │ │ │ │ ├── DeepLinkScreen.kt
│ │ │ │ │ │ └── DeepLinkScreenModel.kt
│ │ │ │ │ ├── download
│ │ │ │ │ │ ├── DownloadAdapter.kt
│ │ │ │ │ │ ├── DownloadHeaderHolder.kt
│ │ │ │ │ │ ├── DownloadHeaderItem.kt
│ │ │ │ │ │ ├── DownloadHolder.kt
│ │ │ │ │ │ ├── DownloadItem.kt
│ │ │ │ │ │ ├── DownloadQueueScreen.kt
│ │ │ │ │ │ └── DownloadQueueScreenModel.kt
│ │ │ │ │ ├── history
│ │ │ │ │ │ ├── HistoryScreenModel.kt
│ │ │ │ │ │ └── HistoryTab.kt
│ │ │ │ │ ├── home
│ │ │ │ │ │ └── HomeScreen.kt
│ │ │ │ │ ├── library
│ │ │ │ │ │ ├── LibraryItem.kt
│ │ │ │ │ │ ├── LibraryScreenModel.kt
│ │ │ │ │ │ ├── LibrarySettingsScreenModel.kt
│ │ │ │ │ │ └── LibraryTab.kt
│ │ │ │ │ ├── libraryUpdateError
│ │ │ │ │ │ ├── LibraryUpdateErrorScreen.kt
│ │ │ │ │ │ └── LibraryUpdateErrorScreenModel.kt
│ │ │ │ │ ├── main
│ │ │ │ │ │ └── MainActivity.kt
│ │ │ │ │ ├── manga
│ │ │ │ │ │ ├── EditMangaDialog.kt
│ │ │ │ │ │ ├── MangaCoverScreenModel.kt
│ │ │ │ │ │ ├── MangaScreen.kt
│ │ │ │ │ │ ├── MangaScreenModel.kt
│ │ │ │ │ │ ├── PaletteScreen.kt
│ │ │ │ │ │ ├── RelatedMangasScreen.kt
│ │ │ │ │ │ ├── merged
│ │ │ │ │ │ │ ├── EditMergedMangaAdapter.kt
│ │ │ │ │ │ │ ├── EditMergedMangaHolder.kt
│ │ │ │ │ │ │ ├── EditMergedMangaItem.kt
│ │ │ │ │ │ │ ├── EditMergedSettingsDialog.kt
│ │ │ │ │ │ │ └── EditMergedSettingsHeaderAdapter.kt
│ │ │ │ │ │ ├── notes
│ │ │ │ │ │ │ └── MangaNotesScreen.kt
│ │ │ │ │ │ └── track
│ │ │ │ │ │ │ ├── TrackInfoDialog.kt
│ │ │ │ │ │ │ └── TrackItem.kt
│ │ │ │ │ ├── more
│ │ │ │ │ │ ├── ComingUpdatesScreen.kt
│ │ │ │ │ │ ├── MoreTab.kt
│ │ │ │ │ │ ├── NewUpdateScreen.kt
│ │ │ │ │ │ ├── OnboardingScreen.kt
│ │ │ │ │ │ └── WhatsNewScreen.kt
│ │ │ │ │ ├── reader
│ │ │ │ │ │ ├── ReaderActivity.kt
│ │ │ │ │ │ ├── ReaderNavigationOverlayView.kt
│ │ │ │ │ │ ├── ReaderViewModel.kt
│ │ │ │ │ │ ├── SaveImageNotifier.kt
│ │ │ │ │ │ ├── chapter
│ │ │ │ │ │ │ └── ReaderChapterItem.kt
│ │ │ │ │ │ ├── loader
│ │ │ │ │ │ │ ├── ArchivePageLoader.kt
│ │ │ │ │ │ │ ├── ChapterLoader.kt
│ │ │ │ │ │ │ ├── DirectoryPageLoader.kt
│ │ │ │ │ │ │ ├── DownloadPageLoader.kt
│ │ │ │ │ │ │ ├── EpubPageLoader.kt
│ │ │ │ │ │ │ ├── HttpPageLoader.kt
│ │ │ │ │ │ │ └── PageLoader.kt
│ │ │ │ │ │ ├── model
│ │ │ │ │ │ │ ├── ChapterTransition.kt
│ │ │ │ │ │ │ ├── InsertPage.kt
│ │ │ │ │ │ │ ├── ReaderChapter.kt
│ │ │ │ │ │ │ ├── ReaderItem.kt
│ │ │ │ │ │ │ ├── ReaderPage.kt
│ │ │ │ │ │ │ └── ViewerChapters.kt
│ │ │ │ │ │ ├── setting
│ │ │ │ │ │ │ ├── ReaderBottomButton.kt
│ │ │ │ │ │ │ ├── ReaderOrientation.kt
│ │ │ │ │ │ │ ├── ReaderPreferences.kt
│ │ │ │ │ │ │ ├── ReaderSettingsScreenModel.kt
│ │ │ │ │ │ │ └── ReadingMode.kt
│ │ │ │ │ │ └── viewer
│ │ │ │ │ │ │ ├── GestureDetectorWithLongTap.kt
│ │ │ │ │ │ │ ├── MissingChapters.kt
│ │ │ │ │ │ │ ├── ReaderButton.kt
│ │ │ │ │ │ │ ├── ReaderPageImageView.kt
│ │ │ │ │ │ │ ├── ReaderProgressIndicator.kt
│ │ │ │ │ │ │ ├── ReaderTransitionView.kt
│ │ │ │ │ │ │ ├── Viewer.kt
│ │ │ │ │ │ │ ├── ViewerConfig.kt
│ │ │ │ │ │ │ ├── ViewerNavigation.kt
│ │ │ │ │ │ │ ├── navigation
│ │ │ │ │ │ │ ├── DisabledNavigation.kt
│ │ │ │ │ │ │ ├── EdgeNavigation.kt
│ │ │ │ │ │ │ ├── KindlishNavigation.kt
│ │ │ │ │ │ │ ├── LNavigation.kt
│ │ │ │ │ │ │ └── RightAndLeftNavigation.kt
│ │ │ │ │ │ │ ├── pager
│ │ │ │ │ │ │ ├── Pager.kt
│ │ │ │ │ │ │ ├── PagerConfig.kt
│ │ │ │ │ │ │ ├── PagerPageHolder.kt
│ │ │ │ │ │ │ ├── PagerTransitionHolder.kt
│ │ │ │ │ │ │ ├── PagerViewer.kt
│ │ │ │ │ │ │ ├── PagerViewerAdapter.kt
│ │ │ │ │ │ │ └── PagerViewers.kt
│ │ │ │ │ │ │ └── webtoon
│ │ │ │ │ │ │ ├── WebtoonAdapter.kt
│ │ │ │ │ │ │ ├── WebtoonBaseHolder.kt
│ │ │ │ │ │ │ ├── WebtoonConfig.kt
│ │ │ │ │ │ │ ├── WebtoonFrame.kt
│ │ │ │ │ │ │ ├── WebtoonLayoutManager.kt
│ │ │ │ │ │ │ ├── WebtoonPageHolder.kt
│ │ │ │ │ │ │ ├── WebtoonRecyclerView.kt
│ │ │ │ │ │ │ ├── WebtoonSubsamplingImageView.kt
│ │ │ │ │ │ │ ├── WebtoonTransitionHolder.kt
│ │ │ │ │ │ │ └── WebtoonViewer.kt
│ │ │ │ │ ├── security
│ │ │ │ │ │ └── UnlockActivity.kt
│ │ │ │ │ ├── setting
│ │ │ │ │ │ ├── SettingsScreen.kt
│ │ │ │ │ │ └── track
│ │ │ │ │ │ │ ├── BaseOAuthLoginActivity.kt
│ │ │ │ │ │ │ ├── GoogleDriveLoginActivity.kt
│ │ │ │ │ │ │ └── TrackLoginActivity.kt
│ │ │ │ │ ├── stats
│ │ │ │ │ │ ├── StatsScreen.kt
│ │ │ │ │ │ └── StatsScreenModel.kt
│ │ │ │ │ ├── updates
│ │ │ │ │ │ ├── UpdatesScreenModel.kt
│ │ │ │ │ │ └── UpdatesTab.kt
│ │ │ │ │ └── webview
│ │ │ │ │ │ ├── WebViewActivity.kt
│ │ │ │ │ │ ├── WebViewScreen.kt
│ │ │ │ │ │ └── WebViewScreenModel.kt
│ │ │ │ ├── util
│ │ │ │ │ ├── CrashLogUtil.kt
│ │ │ │ │ ├── MangaExtensions.kt
│ │ │ │ │ ├── PkceUtil.kt
│ │ │ │ │ ├── chapter
│ │ │ │ │ │ ├── ChapterFilterDownloaded.kt
│ │ │ │ │ │ ├── ChapterGetNextUnread.kt
│ │ │ │ │ │ └── ChapterRemoveDuplicates.kt
│ │ │ │ │ ├── lang
│ │ │ │ │ │ ├── CloseableExtensions.kt
│ │ │ │ │ │ ├── DateExtensions.kt
│ │ │ │ │ │ └── RectFExtensions.kt
│ │ │ │ │ ├── storage
│ │ │ │ │ │ ├── FileExtensions.kt
│ │ │ │ │ │ └── OkioExtensions.kt
│ │ │ │ │ ├── system
│ │ │ │ │ │ ├── AnimationExtensions.kt
│ │ │ │ │ │ ├── AuthenticatorUtil.kt
│ │ │ │ │ │ ├── BuildConfig.kt
│ │ │ │ │ │ ├── ChildFirstPathClassLoader.kt
│ │ │ │ │ │ ├── ContextExtensions.kt
│ │ │ │ │ │ ├── DeviceUtilExtensions.kt
│ │ │ │ │ │ ├── DisplayExtensions.kt
│ │ │ │ │ │ ├── DrawableExtensions.kt
│ │ │ │ │ │ ├── IntentExtensions.kt
│ │ │ │ │ │ ├── InternalResourceHelper.kt
│ │ │ │ │ │ ├── LocaleHelper.kt
│ │ │ │ │ │ ├── NetworkExtensions.kt
│ │ │ │ │ │ ├── NetworkStateTracker.kt
│ │ │ │ │ │ ├── NotificationExtensions.kt
│ │ │ │ │ │ └── WorkManagerExtensions.kt
│ │ │ │ │ └── view
│ │ │ │ │ │ ├── EditTextPreferenceExtensions.kt
│ │ │ │ │ │ ├── ViewExtensions.kt
│ │ │ │ │ │ └── WindowExtensions.kt
│ │ │ │ └── widget
│ │ │ │ │ ├── AutoCompleteAdapter.kt
│ │ │ │ │ ├── TachiyomiTextInputEditText.kt
│ │ │ │ │ ├── ViewPagerAdapter.kt
│ │ │ │ │ └── materialdialogs
│ │ │ │ │ └── MaterialAlertDialogBuilderExtensions.kt
│ │ │ │ └── test
│ │ │ │ └── DummyTracker.kt
│ │ ├── exh
│ │ │ ├── EXHMigrations.kt
│ │ │ ├── GalleryAdder.kt
│ │ │ ├── assets
│ │ │ │ ├── EhAssets.kt
│ │ │ │ └── ehassets
│ │ │ │ │ ├── EhLogo.kt
│ │ │ │ │ └── MangadexLogo.kt
│ │ │ ├── debug
│ │ │ │ ├── DebugFunctions.kt
│ │ │ │ ├── DebugToggles.kt
│ │ │ │ └── SettingsDebugScreen.kt
│ │ │ ├── eh
│ │ │ │ ├── EHTags.kt
│ │ │ │ ├── EHentaiThrottleManager.kt
│ │ │ │ ├── EHentaiUpdateHelper.kt
│ │ │ │ ├── EHentaiUpdateNotifier.kt
│ │ │ │ ├── EHentaiUpdateWorker.kt
│ │ │ │ ├── EHentaiUpdaterStats.kt
│ │ │ │ ├── GalleryNotUpdatedException.kt
│ │ │ │ ├── MemAutoFlushingLookupTable.kt
│ │ │ │ └── tags
│ │ │ │ │ ├── Artist.kt
│ │ │ │ │ ├── Artist2.kt
│ │ │ │ │ ├── Character.kt
│ │ │ │ │ ├── Cosplayer.kt
│ │ │ │ │ ├── Female.kt
│ │ │ │ │ ├── Group.kt
│ │ │ │ │ ├── Group2.kt
│ │ │ │ │ ├── Language.kt
│ │ │ │ │ ├── Male.kt
│ │ │ │ │ ├── Mixed.kt
│ │ │ │ │ ├── Other.kt
│ │ │ │ │ ├── Parody.kt
│ │ │ │ │ ├── Reclass.kt
│ │ │ │ │ └── TagList.kt
│ │ │ ├── favorites
│ │ │ │ ├── FavoritesSyncHelper.kt
│ │ │ │ └── LocalFavoritesStorage.kt
│ │ │ ├── log
│ │ │ │ ├── EHDebugModeOverlay.kt
│ │ │ │ ├── EnhancedFilePrinter.kt
│ │ │ │ └── XLogLogcatLogger.kt
│ │ │ ├── md
│ │ │ │ ├── MangaDexLoginActivity.kt
│ │ │ │ ├── dto
│ │ │ │ │ ├── AtHomeDto.kt
│ │ │ │ │ ├── ChapterDto.kt
│ │ │ │ │ ├── ListCallDto.kt
│ │ │ │ │ ├── MangaDto.kt
│ │ │ │ │ ├── MangaPlusDto.kt
│ │ │ │ │ ├── RatingDto.kt
│ │ │ │ │ ├── ResultDto.kt
│ │ │ │ │ ├── SimilarDto.kt
│ │ │ │ │ └── StatisticsDto.kt
│ │ │ │ ├── follows
│ │ │ │ │ ├── MangaDexFollowsPagingSource.kt
│ │ │ │ │ ├── MangaDexFollowsScreen.kt
│ │ │ │ │ └── MangaDexFollowsScreenModel.kt
│ │ │ │ ├── handlers
│ │ │ │ │ ├── ApiMangaParser.kt
│ │ │ │ │ ├── AzukiHandler.kt
│ │ │ │ │ ├── BilibiliHandler.kt
│ │ │ │ │ ├── ComikeyHandler.kt
│ │ │ │ │ ├── FilterHandler.kt
│ │ │ │ │ ├── FollowsHandler.kt
│ │ │ │ │ ├── MangaHandler.kt
│ │ │ │ │ ├── MangaHotHandler.kt
│ │ │ │ │ ├── MangaPlusHandler.kt
│ │ │ │ │ ├── NamicomiHandler.kt
│ │ │ │ │ ├── PageHandler.kt
│ │ │ │ │ └── SimilarHandler.kt
│ │ │ │ ├── network
│ │ │ │ │ ├── MangaDexAuthInterceptor.kt
│ │ │ │ │ └── MangaDexLoginHelper.kt
│ │ │ │ ├── service
│ │ │ │ │ ├── MangaDexAuthService.kt
│ │ │ │ │ ├── MangaDexService.kt
│ │ │ │ │ └── SimilarService.kt
│ │ │ │ ├── similar
│ │ │ │ │ └── MangaDexSimilarPagingSource.kt
│ │ │ │ └── utils
│ │ │ │ │ ├── FollowStatus.kt
│ │ │ │ │ ├── MdApi.kt
│ │ │ │ │ ├── MdConstants.kt
│ │ │ │ │ ├── MdExtensions.kt
│ │ │ │ │ ├── MdLang.kt
│ │ │ │ │ └── MdUtil.kt
│ │ │ ├── pagepreview
│ │ │ │ ├── PagePreviewScreen.kt
│ │ │ │ ├── PagePreviewScreenModel.kt
│ │ │ │ └── components
│ │ │ │ │ └── PagePreviewScreen.kt
│ │ │ ├── recs
│ │ │ │ ├── BrowseRecommendsScreen.kt
│ │ │ │ ├── BrowseRecommendsScreenModel.kt
│ │ │ │ ├── RecommendsScreen.kt
│ │ │ │ ├── RecommendsScreenModel.kt
│ │ │ │ ├── components
│ │ │ │ │ └── RecommendsScreen.kt
│ │ │ │ └── sources
│ │ │ │ │ ├── AniListPagingSource.kt
│ │ │ │ │ ├── ComickPagingSource.kt
│ │ │ │ │ ├── MangaUpdatesPagingSource.kt
│ │ │ │ │ ├── MyAnimeListPagingSource.kt
│ │ │ │ │ └── RecommendationPagingSource.kt
│ │ │ ├── search
│ │ │ │ ├── MultiWildcard.kt
│ │ │ │ ├── Namespace.kt
│ │ │ │ ├── QueryComponent.kt
│ │ │ │ ├── SearchEngine.kt
│ │ │ │ ├── SingleWildcard.kt
│ │ │ │ ├── StringTextComponent.kt
│ │ │ │ ├── Text.kt
│ │ │ │ └── TextComponent.kt
│ │ │ ├── smartsearch
│ │ │ │ └── SmartSearchEngine.kt
│ │ │ ├── source
│ │ │ │ ├── BlacklistedSources.kt
│ │ │ │ └── SourceHelper.kt
│ │ │ ├── uconfig
│ │ │ │ ├── EHConfigurator.kt
│ │ │ │ ├── EHHathPerksResponse.kt
│ │ │ │ └── EhUConfigBuilder.kt
│ │ │ ├── ui
│ │ │ │ ├── batchadd
│ │ │ │ │ ├── BatchAddScreen.kt
│ │ │ │ │ └── BatchAddScreenModel.kt
│ │ │ │ ├── intercept
│ │ │ │ │ └── InterceptActivity.kt
│ │ │ │ ├── login
│ │ │ │ │ └── EhLoginActivity.kt
│ │ │ │ ├── metadata
│ │ │ │ │ ├── MetadataViewScreen.kt
│ │ │ │ │ ├── MetadataViewScreenModel.kt
│ │ │ │ │ └── adapters
│ │ │ │ │ │ ├── EHentaiDescriptionAdapter.kt
│ │ │ │ │ │ ├── EightMusesDescriptionAdapter.kt
│ │ │ │ │ │ ├── HBrowseDescriptionAdapter.kt
│ │ │ │ │ │ ├── MangaDexDescriptionAdapter.kt
│ │ │ │ │ │ ├── MetadataUIUtil.kt
│ │ │ │ │ │ ├── NHentaiDescriptionAdapter.kt
│ │ │ │ │ │ ├── PururinDescriptionAdapter.kt
│ │ │ │ │ │ └── TsuminoDescriptionAdapter.kt
│ │ │ │ └── smartsearch
│ │ │ │ │ ├── SmartSearchScreen.kt
│ │ │ │ │ └── SmartSearchScreenModel.kt
│ │ │ └── util
│ │ │ │ ├── AnnotatedString.kt
│ │ │ │ ├── Boolean.kt
│ │ │ │ ├── ContextExtensions.kt
│ │ │ │ ├── CoroutineUtil.kt
│ │ │ │ ├── DataSaver.kt
│ │ │ │ ├── ExceptionUtil.kt
│ │ │ │ ├── LewdMangaChecker.kt
│ │ │ │ ├── MangaType.kt
│ │ │ │ ├── Math.kt
│ │ │ │ ├── OkHttpExtensions.kt
│ │ │ │ ├── OkHttpUtil.kt
│ │ │ │ ├── SearchOverride.kt
│ │ │ │ ├── SourceTagsUtil.kt
│ │ │ │ ├── UriFilter.kt
│ │ │ │ └── UriGroup.kt
│ │ └── mihon
│ │ │ ├── core
│ │ │ ├── designsystem
│ │ │ │ └── utils
│ │ │ │ │ └── WindowSize.kt
│ │ │ └── migration
│ │ │ │ ├── MigrateUtils.kt
│ │ │ │ ├── Migration.kt
│ │ │ │ ├── MigrationCompletedListener.kt
│ │ │ │ ├── MigrationContext.kt
│ │ │ │ ├── MigrationJobFactory.kt
│ │ │ │ ├── MigrationStrategy.kt
│ │ │ │ ├── MigrationStrategyFactory.kt
│ │ │ │ ├── Migrator.kt
│ │ │ │ └── migrations
│ │ │ │ ├── AlwaysBackupMigration.kt
│ │ │ │ ├── CategoryPreferencesCleanupMigration.kt
│ │ │ │ ├── ChangeMiuiExtensionInstallerMigration.kt
│ │ │ │ ├── ChangeThemeModeToUppercaseMigration.kt
│ │ │ │ ├── ChangeTrackingQueueTypeMigration.kt
│ │ │ │ ├── ClearBrokenPagePreviewCacheMigration.kt
│ │ │ │ ├── DelegateHBrowseMigration.kt
│ │ │ │ ├── DelegateNHentaiMigration.kt
│ │ │ │ ├── DeleteOldEhFavoritesDatabaseMigration.kt
│ │ │ │ ├── DeleteOldMangaDexTracksMigration.kt
│ │ │ │ ├── EHentaiMigration.kt
│ │ │ │ ├── IntegratedHentaiMigration.kt
│ │ │ │ ├── LogoutFromMALMigration.kt
│ │ │ │ ├── LogoutFromMangaDexMigration.kt
│ │ │ │ ├── MergedMangaRewriteMigration.kt
│ │ │ │ ├── Migrations.kt
│ │ │ │ ├── MoveCacheToDiskSettingMigration.kt
│ │ │ │ ├── MoveCatalogueCoverOnlyGridSettingMigration.kt
│ │ │ │ ├── MoveCoverOnlyGridSettingMigration.kt
│ │ │ │ ├── MoveDOHSettingMigration.kt
│ │ │ │ ├── MoveEncryptionSettingsToAppStateMigration.kt
│ │ │ │ ├── MoveExtensionRepoSettingsMigration.kt
│ │ │ │ ├── MoveLatestToFeedMigration.kt
│ │ │ │ ├── MoveLibraryNonCompleteSettingMigration.kt
│ │ │ │ ├── MoveLibrarySortingSettingsMigration.kt
│ │ │ │ ├── MoveReaderTapSettingMigration.kt
│ │ │ │ ├── MoveReadingButtonSettingMigration.kt
│ │ │ │ ├── MoveRelativeTimeSettingMigration.kt
│ │ │ │ ├── MoveSecureScreenSettingMigration.kt
│ │ │ │ ├── MoveSettingsToPrivateOrAppStateMigration.kt
│ │ │ │ ├── MoveSortingModeSettingMigration.kt
│ │ │ │ ├── MoveSortingModeSettingsMigration.kt
│ │ │ │ ├── RemoveBatteryNotLowRestrictionMigration.kt
│ │ │ │ ├── RemoveOldReaderThemeMigration.kt
│ │ │ │ ├── RemoveShortLibraryUpdatesMigration.kt
│ │ │ │ ├── RemoveShorterLibraryUpdatesMigration.kt
│ │ │ │ ├── RemoveUpdateCheckerJobsMigration.kt
│ │ │ │ ├── ResetFilterAndSortSettingsMigration.kt
│ │ │ │ ├── ResetReaderSettingsMigration.kt
│ │ │ │ ├── ResetRotationSettingMigration.kt
│ │ │ │ ├── SetupAppUpdateMigration.kt
│ │ │ │ ├── SetupBackupCreateMigration.kt
│ │ │ │ ├── SetupEHentaiUpdateMigration.kt
│ │ │ │ ├── SetupLibraryUpdateMigration.kt
│ │ │ │ ├── SetupSyncDataMigration.kt
│ │ │ │ └── TrustExtensionRepositoryMigration.kt
│ │ │ └── feature
│ │ │ └── upcoming
│ │ │ ├── UpcomingScreen.kt
│ │ │ ├── UpcomingScreenContent.kt
│ │ │ ├── UpcomingScreenModel.kt
│ │ │ ├── UpcomingUIModel.kt
│ │ │ └── components
│ │ │ ├── UpcomingItem.kt
│ │ │ └── calendar
│ │ │ ├── Calendar.kt
│ │ │ ├── CalendarDay.kt
│ │ │ ├── CalendarHeader.kt
│ │ │ └── CalendarIndicator.kt
│ └── res
│ │ ├── anim-v33
│ │ ├── shared_axis_x_pop_enter.xml
│ │ ├── shared_axis_x_pop_exit.xml
│ │ ├── shared_axis_x_push_enter.xml
│ │ └── shared_axis_x_push_exit.xml
│ │ ├── anim
│ │ ├── fade_in_side.xml
│ │ ├── fade_in_side_left.xml
│ │ ├── fade_out_side.xml
│ │ ├── fade_out_side_left.xml
│ │ ├── shared_axis_x_pop_enter.xml
│ │ ├── shared_axis_x_pop_exit.xml
│ │ ├── shared_axis_x_push_enter.xml
│ │ └── shared_axis_x_push_exit.xml
│ │ ├── color
│ │ └── draggable_card_foreground.xml
│ │ ├── drawable-hdpi
│ │ ├── ic_book_open_variant_24dp.xml
│ │ └── ic_page_next_outline_24dp.xml
│ │ ├── drawable-night
│ │ ├── ic_bmc_button.xml
│ │ └── ic_splash.xml
│ │ ├── drawable-nodpi
│ │ ├── ic_manga_updates.webp
│ │ ├── ic_tracker_anilist.webp
│ │ ├── ic_tracker_bangumi.webp
│ │ ├── ic_tracker_kavita.webp
│ │ ├── ic_tracker_kitsu.webp
│ │ ├── ic_tracker_komga.webp
│ │ ├── ic_tracker_mal.webp
│ │ ├── ic_tracker_shikimori.webp
│ │ └── ic_tracker_suwayomi.webp
│ │ ├── drawable
│ │ ├── anim_browse_enter.xml
│ │ ├── anim_caret_down.xml
│ │ ├── anim_history_enter.xml
│ │ ├── anim_incognito.xml
│ │ ├── anim_library_enter.xml
│ │ ├── anim_more_enter.xml
│ │ ├── anim_updates_enter.xml
│ │ ├── cover_error.xml
│ │ ├── cover_error_vector.xml
│ │ ├── globe.xml
│ │ ├── ic_add_24dp.xml
│ │ ├── ic_baseline_menu_book_24.xml
│ │ ├── ic_bmc_button.xml
│ │ ├── ic_book_24dp.xml
│ │ ├── ic_browse_filled_24dp.xml
│ │ ├── ic_close_24dp.xml
│ │ ├── ic_crop_24dp.xml
│ │ ├── ic_crop_off_24dp.xml
│ │ ├── ic_delete_24dp.xml
│ │ ├── ic_done_24dp.xml
│ │ ├── ic_done_prev_24dp.xml
│ │ ├── ic_download_chapter_24dp.xml
│ │ ├── ic_drag_handle_24dp.xml
│ │ ├── ic_extension_24dp.xml
│ │ ├── ic_flag_esperanto.xml
│ │ ├── ic_flag_lfn.xml
│ │ ├── ic_flag_un.xml
│ │ ├── ic_folder_24dp.xml
│ │ ├── ic_format_list_numbered_24dp.xml
│ │ ├── ic_get_app_24dp.xml
│ │ ├── ic_glasses_24dp.xml
│ │ ├── ic_glasses_with_hat_24dp.xml
│ │ ├── ic_info_24dp.xml
│ │ ├── ic_keyboard_arrow_down_white_32dp.xml
│ │ ├── ic_keyboard_arrow_up_white_32dp.xml
│ │ ├── ic_komikku.xml
│ │ ├── ic_komikku_dark.xml
│ │ ├── ic_label_24dp.xml
│ │ ├── ic_launch.xml
│ │ ├── ic_launcher_background.xml
│ │ ├── ic_launcher_foreground.xml
│ │ ├── ic_launcher_monochrome.xml
│ │ ├── ic_outline_sd_card_24.xml
│ │ ├── ic_overflow_24dp.xml
│ │ ├── ic_pause_24dp.xml
│ │ ├── ic_photo_24dp.xml
│ │ ├── ic_play_arrow_24dp.xml
│ │ ├── ic_progress_clock_24dp.xml
│ │ ├── ic_reader_continuous_vertical_24dp.xml
│ │ ├── ic_reader_default_24dp.xml
│ │ ├── ic_reader_ltr_24dp.xml
│ │ ├── ic_reader_rtl_24dp.xml
│ │ ├── ic_reader_vertical_24dp.xml
│ │ ├── ic_reader_webtoon_24dp.xml
│ │ ├── ic_refresh_24dp.xml
│ │ ├── ic_save_black_24dp.xml
│ │ ├── ic_share_24dp.xml
│ │ ├── ic_splash.xml
│ │ ├── ic_start_reading_24dp.xml
│ │ ├── ic_sync_24dp.xml
│ │ ├── ic_system_update_alt_white_24dp.xml
│ │ ├── ic_tracker_mangadex_logo.xml
│ │ ├── ic_ungroup_24dp.xml
│ │ ├── ic_warning_white_24dp.xml
│ │ ├── komikku.png
│ │ ├── line_divider.xml
│ │ ├── list_item_selector_background.xml
│ │ ├── material_popup_background.xml
│ │ ├── rounded_rectangle.xml
│ │ ├── sc_collections_bookmark_48dp.xml
│ │ ├── sc_explore_48dp.xml
│ │ ├── sc_history_48dp.xml
│ │ └── sc_new_releases_48dp.xml
│ │ ├── layout
│ │ ├── description_adapter_8m.xml
│ │ ├── description_adapter_eh.xml
│ │ ├── description_adapter_hb.xml
│ │ ├── description_adapter_md.xml
│ │ ├── description_adapter_nh.xml
│ │ ├── description_adapter_pu.xml
│ │ ├── description_adapter_ts.xml
│ │ ├── dialog_stub_textinput.xml
│ │ ├── download_header.xml
│ │ ├── download_item.xml
│ │ ├── download_list.xml
│ │ ├── edit_manga_dialog.xml
│ │ ├── edit_merged_settings_dialog.xml
│ │ ├── edit_merged_settings_header.xml
│ │ ├── edit_merged_settings_item.xml
│ │ ├── migration_bottom_sheet.xml
│ │ ├── migration_source_item.xml
│ │ ├── pre_migration_list.xml
│ │ ├── pref_widget_switch_material.xml
│ │ ├── reader_activity.xml
│ │ └── reader_error.xml
│ │ ├── menu
│ │ └── download_single.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_default_source.webp
│ │ ├── ic_ehentai_source.png
│ │ ├── ic_exhentai_source.png
│ │ ├── ic_local_source.webp
│ │ └── ic_merged_source.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_default_source.webp
│ │ ├── ic_ehentai_source.png
│ │ ├── ic_exhentai_source.png
│ │ ├── ic_local_source.webp
│ │ └── ic_merged_source.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_default_source.webp
│ │ ├── ic_ehentai_source.png
│ │ ├── ic_exhentai_source.png
│ │ ├── ic_local_source.webp
│ │ └── ic_merged_source.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_default_source.webp
│ │ ├── ic_ehentai_source.png
│ │ ├── ic_exhentai_source.png
│ │ ├── ic_local_source.webp
│ │ └── ic_merged_source.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_default_source.webp
│ │ ├── ic_ehentai_source.png
│ │ ├── ic_exhentai_source.png
│ │ ├── ic_local_source.webp
│ │ └── ic_merged_source.png
│ │ ├── mipmap
│ │ ├── extension.png
│ │ ├── ic_launcher.xml
│ │ ├── komikku.png
│ │ └── repo.jpeg
│ │ ├── raw
│ │ └── mangadex_dmca_uuids.txt
│ │ ├── values-night-v31
│ │ └── themes.xml
│ │ ├── values-night
│ │ ├── bools.xml
│ │ └── themes.xml
│ │ ├── values-v27
│ │ ├── bools.xml
│ │ └── themes.xml
│ │ ├── values-v31
│ │ └── themes.xml
│ │ ├── values
│ │ ├── arrays_sy.xml
│ │ ├── attrs.xml
│ │ ├── bools.xml
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── ids.xml
│ │ ├── styles.xml
│ │ ├── styles_sy.xml
│ │ └── themes.xml
│ │ └── xml
│ │ ├── network_security_config.xml
│ │ ├── provider_paths.xml
│ │ ├── s_pen_actions.xml
│ │ ├── searchable.xml
│ │ └── shortcuts.xml
│ └── test
│ ├── java
│ └── mihon
│ │ └── core
│ │ └── migration
│ │ └── MigratorTest.kt
│ └── kotlin
│ └── Tester.kt
├── build.gradle.kts
├── buildSrc
├── build.gradle.kts
├── settings.gradle.kts
└── src
│ └── main
│ └── kotlin
│ ├── mihon.android.application.compose.gradle.kts
│ ├── mihon.android.application.gradle.kts
│ ├── mihon.benchmark.gradle.kts
│ ├── mihon.code.lint.gradle.kts
│ ├── mihon.library.compose.gradle.kts
│ ├── mihon.library.gradle.kts
│ └── mihon
│ └── buildlogic
│ ├── AndroidConfig.kt
│ ├── BuildConfig.kt
│ ├── Commands.kt
│ ├── ProjectExtensions.kt
│ └── tasks
│ └── LocalesConfigTask.kt
├── core-metadata
├── build.gradle.kts
├── consumer-rules.pro
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ └── java
│ └── tachiyomi
│ └── core
│ └── metadata
│ ├── comicinfo
│ └── ComicInfo.kt
│ └── tachiyomi
│ └── MangaDetails.kt
├── core
├── archive
│ ├── build.gradle.kts
│ └── src
│ │ └── main
│ │ ├── AndroidManifest.xml
│ │ └── kotlin
│ │ └── mihon
│ │ └── core
│ │ └── archive
│ │ ├── ArchiveEntry.kt
│ │ ├── ArchiveInputStream.kt
│ │ ├── ArchiveReader.kt
│ │ ├── CbzCrypto.kt
│ │ ├── EpubReader.kt
│ │ ├── UniFileExtensions.kt
│ │ └── ZipWriter.kt
└── common
│ ├── build.gradle.kts
│ └── src
│ └── main
│ ├── AndroidManifest.xml
│ └── kotlin
│ ├── eu
│ └── kanade
│ │ └── tachiyomi
│ │ ├── core
│ │ └── security
│ │ │ ├── PrivacyPreferences.kt
│ │ │ └── SecurityPreferences.kt
│ │ ├── network
│ │ ├── AndroidCookieJar.kt
│ │ ├── DohProviders.kt
│ │ ├── JavaScriptEngine.kt
│ │ ├── NetworkHelper.kt
│ │ ├── NetworkPreferences.kt
│ │ ├── OkHttpExtensions.kt
│ │ ├── ProgressListener.kt
│ │ ├── ProgressResponseBody.kt
│ │ ├── Requests.kt
│ │ └── interceptor
│ │ │ ├── CloudflareInterceptor.kt
│ │ │ ├── IgnoreGzipInterceptor.kt
│ │ │ ├── RateLimitInterceptor.kt
│ │ │ ├── SpecificHostRateLimitInterceptor.kt
│ │ │ ├── UncaughtExceptionInterceptor.kt
│ │ │ ├── UserAgentInterceptor.kt
│ │ │ └── WebViewInterceptor.kt
│ │ └── util
│ │ ├── lang
│ │ ├── Hash.kt
│ │ └── StringExtensions.kt
│ │ ├── storage
│ │ └── DiskUtil.kt
│ │ └── system
│ │ ├── DensityExtensions.kt
│ │ ├── DeviceUtil.kt
│ │ ├── GLUtil.kt
│ │ ├── ToastExtensions.kt
│ │ └── WebViewUtil.kt
│ ├── exh
│ ├── log
│ │ ├── EHLogLevel.kt
│ │ ├── EHNetworkLogging.kt
│ │ └── Logging.kt
│ ├── pref
│ │ └── DelegateSourcePreferences.kt
│ └── util
│ │ ├── ListUtil.kt
│ │ ├── StringBuilderExtensions.kt
│ │ └── StringUtil.kt
│ └── tachiyomi
│ └── core
│ └── common
│ ├── Constants.kt
│ ├── i18n
│ └── Localize.kt
│ ├── preference
│ ├── AndroidPreference.kt
│ ├── AndroidPreferenceStore.kt
│ ├── CheckboxState.kt
│ ├── InMemoryPreferenceStore.kt
│ ├── Preference.kt
│ ├── PreferenceStore.kt
│ └── TriState.kt
│ ├── storage
│ ├── AndroidStorageFolderProvider.kt
│ ├── FolderProvider.kt
│ ├── UniFileExtensions.kt
│ └── UniFileTempFileManager.kt
│ └── util
│ ├── QuerySanitizer.kt
│ ├── lang
│ ├── BooleanExtensions.kt
│ ├── CoroutinesExtensions.kt
│ ├── RxCoroutineBridge.kt
│ └── SortUtil.kt
│ └── system
│ ├── ImageUtil.kt
│ └── LogcatExtensions.kt
├── data
├── build.gradle.kts
├── consumer-rules.pro
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ ├── mihon
│ │ └── data
│ │ │ └── repository
│ │ │ └── ExtensionRepoRepositoryImpl.kt
│ └── tachiyomi
│ │ └── data
│ │ ├── AndroidDatabaseHandler.kt
│ │ ├── DatabaseAdapter.kt
│ │ ├── DatabaseHandler.kt
│ │ ├── QueryPagingSource.kt
│ │ ├── TransactionContext.kt
│ │ ├── category
│ │ ├── CategoryMapper.kt
│ │ └── CategoryRepositoryImpl.kt
│ │ ├── chapter
│ │ ├── ChapterMapper.kt
│ │ ├── ChapterRepositoryImpl.kt
│ │ └── ChapterSanitizer.kt
│ │ ├── history
│ │ ├── HistoryMapper.kt
│ │ └── HistoryRepositoryImpl.kt
│ │ ├── libraryUpdateError
│ │ ├── LibraryUpdateErrorMapper.kt
│ │ ├── LibraryUpdateErrorRepositoryImpl.kt
│ │ ├── LibraryUpdateErrorWithRelationsMapper.kt
│ │ └── LibraryUpdateErrorWithRelationsRepositoryImpl.kt
│ │ ├── libraryUpdateErrorMessage
│ │ ├── LibraryUpdateErrorMessageMapper.kt
│ │ └── LibraryUpdateErrorMessageRepositoryImpl.kt
│ │ ├── manga
│ │ ├── CustomMangaRepositoryImpl.kt
│ │ ├── FavoritesEntryRepositoryImpl.kt
│ │ ├── MangaMapper.kt
│ │ ├── MangaMergeRepositoryImpl.kt
│ │ ├── MangaMetadataRepositoryImpl.kt
│ │ ├── MangaRepositoryImpl.kt
│ │ └── MergedMangaMapper.kt
│ │ ├── release
│ │ ├── GithubRelease.kt
│ │ └── ReleaseServiceImpl.kt
│ │ ├── source
│ │ ├── EHentaiPagingSource.kt
│ │ ├── FeedSavedSearchMapper.kt
│ │ ├── FeedSavedSearchRepositoryImpl.kt
│ │ ├── SavedSearchMapper.kt
│ │ ├── SavedSearchRepositoryImpl.kt
│ │ ├── SourcePagingSource.kt
│ │ ├── SourceRepositoryImpl.kt
│ │ └── StubSourceRepositoryImpl.kt
│ │ ├── track
│ │ ├── TrackMapper.kt
│ │ └── TrackRepositoryImpl.kt
│ │ └── updates
│ │ └── UpdatesRepositoryImpl.kt
│ └── sqldelight
│ ├── 28.db
│ └── tachiyomi
│ ├── data
│ ├── categories.sq
│ ├── chapters.sq
│ ├── eh.sq
│ ├── eh_favorites.sq
│ ├── excluded_scanlators.sq
│ ├── extension_repos.sq
│ ├── feed_saved_search.sq
│ ├── history.sq
│ ├── libraryUpdateError.sq
│ ├── libraryUpdateErrorMessage.sq
│ ├── manga_sync.sq
│ ├── mangas.sq
│ ├── mangas_categories.sq
│ ├── merged.sq
│ ├── saved_search.sq
│ ├── search_metadata.sq
│ ├── search_tags.sq
│ ├── search_titles.sq
│ └── sources.sq
│ ├── migrations
│ ├── 1.sqm
│ ├── 10.sqm
│ ├── 11.sqm
│ ├── 12.sqm
│ ├── 13.sqm
│ ├── 14.sqm
│ ├── 15.sqm
│ ├── 16.sqm
│ ├── 17.sqm
│ ├── 18.sqm
│ ├── 19.sqm
│ ├── 2.sqm
│ ├── 20.sqm
│ ├── 21.sqm
│ ├── 22.sqm
│ ├── 23.sqm
│ ├── 24.sqm
│ ├── 25.sqm
│ ├── 26.sqm
│ ├── 27.sqm
│ ├── 28.sqm
│ ├── 29.sqm
│ ├── 3.sqm
│ ├── 30.sqm
│ ├── 31.sqm
│ ├── 32.sqm
│ ├── 33.sqm
│ ├── 34.sqm
│ ├── 35.sqm
│ ├── 36.sqm
│ ├── 37.sqm
│ ├── 38.sqm
│ ├── 39.sqm
│ ├── 4.sqm
│ ├── 5.sqm
│ ├── 6.sqm
│ ├── 7.sqm
│ ├── 8.sqm
│ └── 9.sqm
│ └── view
│ ├── historyView.sq
│ ├── libraryUpdateErrorView.sq
│ ├── libraryView.sq
│ └── updatesView.sq
├── domain
├── build.gradle.kts
├── consumer-rules.pro
├── proguard-rules.pro
└── src
│ ├── main
│ ├── AndroidManifest.xml
│ └── java
│ │ ├── exh
│ │ └── source
│ │ │ └── DomainSourceHelpers.kt
│ │ ├── mihon
│ │ └── domain
│ │ │ ├── chapter
│ │ │ └── interactor
│ │ │ │ └── FilterChaptersForDownload.kt
│ │ │ ├── extensionrepo
│ │ │ ├── exception
│ │ │ │ └── SaveExtensionRepoException.kt
│ │ │ ├── interactor
│ │ │ │ ├── CreateExtensionRepo.kt
│ │ │ │ ├── DeleteExtensionRepo.kt
│ │ │ │ ├── GetExtensionRepo.kt
│ │ │ │ ├── GetExtensionRepoCount.kt
│ │ │ │ ├── ReplaceExtensionRepo.kt
│ │ │ │ └── UpdateExtensionRepo.kt
│ │ │ ├── model
│ │ │ │ └── ExtensionRepo.kt
│ │ │ ├── repository
│ │ │ │ └── ExtensionRepoRepository.kt
│ │ │ └── service
│ │ │ │ ├── ExtensionRepoDto.kt
│ │ │ │ └── ExtensionRepoService.kt
│ │ │ ├── manga
│ │ │ └── model
│ │ │ │ └── SManga.kt
│ │ │ └── upcoming
│ │ │ └── interactor
│ │ │ └── GetUpcomingManga.kt
│ │ └── tachiyomi
│ │ └── domain
│ │ ├── UnsortedPreferences.kt
│ │ ├── backup
│ │ └── service
│ │ │ └── BackupPreferences.kt
│ │ ├── category
│ │ ├── interactor
│ │ │ ├── CreateCategoryWithName.kt
│ │ │ ├── DeleteCategory.kt
│ │ │ ├── GetCategories.kt
│ │ │ ├── GetCategoriesPerLibraryManga.kt
│ │ │ ├── HideCategory.kt
│ │ │ ├── RenameCategory.kt
│ │ │ ├── ReorderCategory.kt
│ │ │ ├── ResetCategoryFlags.kt
│ │ │ ├── SetDisplayMode.kt
│ │ │ ├── SetMangaCategories.kt
│ │ │ ├── SetSortModeForCategory.kt
│ │ │ └── UpdateCategory.kt
│ │ ├── model
│ │ │ ├── Category.kt
│ │ │ └── CategoryUpdate.kt
│ │ └── repository
│ │ │ └── CategoryRepository.kt
│ │ ├── chapter
│ │ ├── interactor
│ │ │ ├── DeleteChapters.kt
│ │ │ ├── GetChapter.kt
│ │ │ ├── GetChapterByUrl.kt
│ │ │ ├── GetChapterByUrlAndMangaId.kt
│ │ │ ├── GetChaptersByMangaId.kt
│ │ │ ├── GetMergedChaptersByMangaId.kt
│ │ │ ├── SetMangaDefaultChapterFlags.kt
│ │ │ ├── ShouldUpdateDbChapter.kt
│ │ │ └── UpdateChapter.kt
│ │ ├── model
│ │ │ ├── Chapter.kt
│ │ │ ├── ChapterUpdate.kt
│ │ │ └── NoChaptersException.kt
│ │ ├── repository
│ │ │ └── ChapterRepository.kt
│ │ └── service
│ │ │ ├── ChapterRecognition.kt
│ │ │ ├── ChapterSort.kt
│ │ │ └── MissingChapters.kt
│ │ ├── download
│ │ └── service
│ │ │ └── DownloadPreferences.kt
│ │ ├── history
│ │ ├── interactor
│ │ │ ├── GetHistory.kt
│ │ │ ├── GetHistoryByMangaId.kt
│ │ │ ├── GetNextChapters.kt
│ │ │ ├── GetTotalReadDuration.kt
│ │ │ ├── RemoveHistory.kt
│ │ │ └── UpsertHistory.kt
│ │ ├── model
│ │ │ ├── History.kt
│ │ │ ├── HistoryUpdate.kt
│ │ │ └── HistoryWithRelations.kt
│ │ └── repository
│ │ │ └── HistoryRepository.kt
│ │ ├── library
│ │ ├── model
│ │ │ ├── Flag.kt
│ │ │ ├── GroupLibraryMode.kt
│ │ │ ├── LibraryDisplayMode.kt
│ │ │ ├── LibraryGroup.kt
│ │ │ ├── LibraryManga.kt
│ │ │ └── LibrarySortMode.kt
│ │ └── service
│ │ │ └── LibraryPreferences.kt
│ │ ├── libraryUpdateError
│ │ ├── interactor
│ │ │ ├── DeleteLibraryUpdateErrors.kt
│ │ │ ├── GetLibraryUpdateErrorWithRelations.kt
│ │ │ ├── GetLibraryUpdateErrors.kt
│ │ │ └── InsertLibraryUpdateErrors.kt
│ │ ├── model
│ │ │ ├── LibraryUpdateError.kt
│ │ │ └── LibraryUpdateErrorWithRelations.kt
│ │ └── repository
│ │ │ ├── LibraryUpdateErrorRepository.kt
│ │ │ └── LibraryUpdateErrorWithRelationsRepository.kt
│ │ ├── libraryUpdateErrorMessage
│ │ ├── interactor
│ │ │ ├── DeleteLibraryUpdateErrorMessages.kt
│ │ │ ├── GetLibraryUpdateErrorMessages.kt
│ │ │ └── InsertLibraryUpdateErrorMessages.kt
│ │ ├── model
│ │ │ └── LibraryUpdateErrorMessage.kt
│ │ └── repository
│ │ │ └── LibraryUpdateErrorMessageRepository.kt
│ │ ├── manga
│ │ ├── interactor
│ │ │ ├── DeleteByMergeId.kt
│ │ │ ├── DeleteFavoriteEntries.kt
│ │ │ ├── DeleteMangaById.kt
│ │ │ ├── DeleteMergeById.kt
│ │ │ ├── FetchInterval.kt
│ │ │ ├── GetAllManga.kt
│ │ │ ├── GetCustomMangaInfo.kt
│ │ │ ├── GetDuplicateLibraryManga.kt
│ │ │ ├── GetExhFavoriteMangaWithMetadata.kt
│ │ │ ├── GetFavoriteEntries.kt
│ │ │ ├── GetFavorites.kt
│ │ │ ├── GetFlatMetadataById.kt
│ │ │ ├── GetIdsOfFavoriteMangaWithMetadata.kt
│ │ │ ├── GetLibraryManga.kt
│ │ │ ├── GetManga.kt
│ │ │ ├── GetMangaBySource.kt
│ │ │ ├── GetMangaByUrlAndSourceId.kt
│ │ │ ├── GetMangaWithChapters.kt
│ │ │ ├── GetMergedManga.kt
│ │ │ ├── GetMergedMangaById.kt
│ │ │ ├── GetMergedMangaForDownloading.kt
│ │ │ ├── GetMergedReferencesById.kt
│ │ │ ├── GetReadMangaNotInLibraryView.kt
│ │ │ ├── GetSearchMetadata.kt
│ │ │ ├── GetSearchTags.kt
│ │ │ ├── GetSearchTitles.kt
│ │ │ ├── InsertFavoriteEntries.kt
│ │ │ ├── InsertFavoriteEntryAlternative.kt
│ │ │ ├── InsertFlatMetadata.kt
│ │ │ ├── InsertMergedReference.kt
│ │ │ ├── NetworkToLocalManga.kt
│ │ │ ├── ResetViewerFlags.kt
│ │ │ ├── SetCustomMangaInfo.kt
│ │ │ ├── SetMangaChapterFlags.kt
│ │ │ ├── UpdateMangaNotes.kt
│ │ │ └── UpdateMergedSettings.kt
│ │ ├── model
│ │ │ ├── CustomMangaInfo.kt
│ │ │ ├── FavoriteEntry.kt
│ │ │ ├── FavoriteEntryAlternative.kt
│ │ │ ├── Manga.kt
│ │ │ ├── MangaCover.kt
│ │ │ ├── MangaUpdate.kt
│ │ │ ├── MangaWithChapterCount.kt
│ │ │ ├── MergeMangaSettingsUpdate.kt
│ │ │ ├── MergedMangaReference.kt
│ │ │ └── TriState.kt
│ │ └── repository
│ │ │ ├── CustomMangaRepository.kt
│ │ │ ├── FavoritesEntryRepository.kt
│ │ │ ├── MangaMergeRepository.kt
│ │ │ ├── MangaMetadataRepository.kt
│ │ │ └── MangaRepository.kt
│ │ ├── release
│ │ ├── interactor
│ │ │ └── GetApplicationRelease.kt
│ │ ├── model
│ │ │ └── Release.kt
│ │ └── service
│ │ │ ├── AppUpdatePolicy.kt
│ │ │ └── ReleaseService.kt
│ │ ├── source
│ │ ├── interactor
│ │ │ ├── CountFeedSavedSearchBySourceId.kt
│ │ │ ├── CountFeedSavedSearchGlobal.kt
│ │ │ ├── DeleteFeedSavedSearchById.kt
│ │ │ ├── DeleteSavedSearchById.kt
│ │ │ ├── GetFeedSavedSearchBySourceId.kt
│ │ │ ├── GetFeedSavedSearchGlobal.kt
│ │ │ ├── GetRemoteManga.kt
│ │ │ ├── GetSavedSearchById.kt
│ │ │ ├── GetSavedSearchBySourceId.kt
│ │ │ ├── GetSavedSearchBySourceIdFeed.kt
│ │ │ ├── GetSavedSearchGlobalFeed.kt
│ │ │ ├── GetSourcesWithNonLibraryManga.kt
│ │ │ ├── InsertFeedSavedSearch.kt
│ │ │ ├── InsertSavedSearch.kt
│ │ │ └── ReorderFeed.kt
│ │ ├── model
│ │ │ ├── EXHSavedSearch.kt
│ │ │ ├── FeedSavedSearch.kt
│ │ │ ├── FeedSavedSearchUpdate.kt
│ │ │ ├── Pin.kt
│ │ │ ├── SavedSearch.kt
│ │ │ ├── Source.kt
│ │ │ ├── SourceWithCount.kt
│ │ │ └── StubSource.kt
│ │ ├── repository
│ │ │ ├── FeedSavedSearchRepository.kt
│ │ │ ├── SavedSearchRepository.kt
│ │ │ ├── SourceRepository.kt
│ │ │ └── StubSourceRepository.kt
│ │ └── service
│ │ │ └── SourceManager.kt
│ │ ├── storage
│ │ └── service
│ │ │ ├── StorageManager.kt
│ │ │ └── StoragePreferences.kt
│ │ ├── track
│ │ ├── interactor
│ │ │ ├── DeleteTrack.kt
│ │ │ ├── GetTracks.kt
│ │ │ ├── GetTracksPerManga.kt
│ │ │ ├── InsertTrack.kt
│ │ │ └── IsTrackUnfollowed.kt
│ │ ├── model
│ │ │ └── Track.kt
│ │ └── repository
│ │ │ └── TrackRepository.kt
│ │ └── updates
│ │ ├── interactor
│ │ └── GetUpdates.kt
│ │ ├── model
│ │ └── UpdatesWithRelations.kt
│ │ └── repository
│ │ └── UpdatesRepository.kt
│ └── test
│ └── java
│ └── tachiyomi
│ └── domain
│ ├── chapter
│ └── service
│ │ ├── ChapterRecognitionTest.kt
│ │ └── MissingChaptersTest.kt
│ ├── library
│ └── model
│ │ └── LibraryFlagsTest.kt
│ ├── manga
│ └── interactor
│ │ └── FetchIntervalTest.kt
│ └── release
│ └── interactor
│ └── GetApplicationReleaseTest.kt
├── flagkit
├── build.gradle.kts
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── murgupluoglu
│ │ └── flagkit
│ │ └── FlagKit.kt
│ └── res
│ └── drawable
│ ├── ad.xml
│ ├── ae.xml
│ ├── af.xml
│ ├── ag.xml
│ ├── ai.xml
│ ├── al.xml
│ ├── am.xml
│ ├── ao.xml
│ ├── ar.xml
│ ├── as.xml
│ ├── at.xml
│ ├── au.xml
│ ├── aw.xml
│ ├── ax.xml
│ ├── az.xml
│ ├── ba.xml
│ ├── bb.xml
│ ├── bd.xml
│ ├── be.xml
│ ├── bf.xml
│ ├── bg.xml
│ ├── bh.xml
│ ├── bi.xml
│ ├── bj.xml
│ ├── bl.xml
│ ├── bm.xml
│ ├── bn.xml
│ ├── bo.xml
│ ├── br.xml
│ ├── bs.xml
│ ├── bt.xml
│ ├── bv.xml
│ ├── bw.xml
│ ├── by.xml
│ ├── bz.xml
│ ├── ca.xml
│ ├── cc.xml
│ ├── cd.xml
│ ├── cf.xml
│ ├── cg.xml
│ ├── ch.xml
│ ├── ci.xml
│ ├── ck.xml
│ ├── cl.xml
│ ├── cm.xml
│ ├── cn.xml
│ ├── co.xml
│ ├── cr.xml
│ ├── cu.xml
│ ├── cv.xml
│ ├── cw.xml
│ ├── cx.xml
│ ├── cy.xml
│ ├── cz.xml
│ ├── de.xml
│ ├── dj.xml
│ ├── dk.xml
│ ├── dm.xml
│ ├── do_.xml
│ ├── dz.xml
│ ├── ec.xml
│ ├── ee.xml
│ ├── eg.xml
│ ├── er.xml
│ ├── es.xml
│ ├── et.xml
│ ├── eu.xml
│ ├── fi.xml
│ ├── fj.xml
│ ├── fk.xml
│ ├── fm.xml
│ ├── fo.xml
│ ├── fr.xml
│ ├── ga.xml
│ ├── gb.xml
│ ├── gb_eng.xml
│ ├── gb_nir.xml
│ ├── gb_sct.xml
│ ├── gb_wls.xml
│ ├── gb_zet.xml
│ ├── gd.xml
│ ├── ge.xml
│ ├── gf.xml
│ ├── gg.xml
│ ├── gh.xml
│ ├── gi.xml
│ ├── gl.xml
│ ├── gm.xml
│ ├── gn.xml
│ ├── gp.xml
│ ├── gq.xml
│ ├── gr.xml
│ ├── gs.xml
│ ├── gt.xml
│ ├── gu.xml
│ ├── gw.xml
│ ├── gy.xml
│ ├── hk.xml
│ ├── hm.xml
│ ├── hn.xml
│ ├── hr.xml
│ ├── ht.xml
│ ├── hu.xml
│ ├── id.xml
│ ├── ie.xml
│ ├── il.xml
│ ├── im.xml
│ ├── in_.xml
│ ├── io.xml
│ ├── iq.xml
│ ├── ir.xml
│ ├── is_.xml
│ ├── it.xml
│ ├── je.xml
│ ├── jm.xml
│ ├── jo.xml
│ ├── jp.xml
│ ├── ke.xml
│ ├── kg.xml
│ ├── kh.xml
│ ├── ki.xml
│ ├── km.xml
│ ├── kn.xml
│ ├── kp.xml
│ ├── kr.xml
│ ├── kw.xml
│ ├── ky.xml
│ ├── kz.xml
│ ├── la.xml
│ ├── lb.xml
│ ├── lc.xml
│ ├── li.xml
│ ├── lk.xml
│ ├── lr.xml
│ ├── ls.xml
│ ├── lt.xml
│ ├── lu.xml
│ ├── lv.xml
│ ├── ly.xml
│ ├── ma.xml
│ ├── mc.xml
│ ├── md.xml
│ ├── me.xml
│ ├── mf.xml
│ ├── mg.xml
│ ├── mh.xml
│ ├── mk.xml
│ ├── ml.xml
│ ├── mm.xml
│ ├── mn.xml
│ ├── mo.xml
│ ├── mp.xml
│ ├── mq.xml
│ ├── mr.xml
│ ├── ms.xml
│ ├── mt.xml
│ ├── mu.xml
│ ├── mv.xml
│ ├── mw.xml
│ ├── mx.xml
│ ├── my.xml
│ ├── mz.xml
│ ├── na.xml
│ ├── nc.xml
│ ├── ne.xml
│ ├── nf.xml
│ ├── ng.xml
│ ├── ni.xml
│ ├── nl.xml
│ ├── no.xml
│ ├── np.xml
│ ├── nr.xml
│ ├── nu.xml
│ ├── nz.xml
│ ├── om.xml
│ ├── pa.xml
│ ├── pe.xml
│ ├── pf.xml
│ ├── pg.xml
│ ├── ph.xml
│ ├── pk.xml
│ ├── pl.xml
│ ├── pm.xml
│ ├── pn.xml
│ ├── pr.xml
│ ├── ps.xml
│ ├── pt.xml
│ ├── pw.xml
│ ├── py.xml
│ ├── qa.xml
│ ├── re.xml
│ ├── ro.xml
│ ├── rs.xml
│ ├── ru.xml
│ ├── rw.xml
│ ├── sa.xml
│ ├── sb.xml
│ ├── sc.xml
│ ├── sd.xml
│ ├── se.xml
│ ├── sg.xml
│ ├── sh.xml
│ ├── si.xml
│ ├── sj.xml
│ ├── sk.xml
│ ├── sl.xml
│ ├── sm.xml
│ ├── sn.xml
│ ├── so.xml
│ ├── sr.xml
│ ├── ss.xml
│ ├── st.xml
│ ├── sv.xml
│ ├── sx.xml
│ ├── sy.xml
│ ├── sz.xml
│ ├── tc.xml
│ ├── td.xml
│ ├── tf.xml
│ ├── tg.xml
│ ├── th.xml
│ ├── tj.xml
│ ├── tk.xml
│ ├── tl.xml
│ ├── tm.xml
│ ├── tn.xml
│ ├── to.xml
│ ├── tr.xml
│ ├── tt.xml
│ ├── tv.xml
│ ├── tw.xml
│ ├── tz.xml
│ ├── ua.xml
│ ├── ug.xml
│ ├── um.xml
│ ├── us.xml
│ ├── us_ca.xml
│ ├── uy.xml
│ ├── uz.xml
│ ├── va.xml
│ ├── vc.xml
│ ├── ve.xml
│ ├── vg.xml
│ ├── vi.xml
│ ├── vn.xml
│ ├── vu.xml
│ ├── wf.xml
│ ├── ws.xml
│ ├── xk.xml
│ ├── ye.xml
│ ├── yt.xml
│ ├── za.xml
│ ├── zm.xml
│ └── zw.xml
├── gradle.properties
├── gradle
├── androidx.versions.toml
├── compose.versions.toml
├── kotlinx.versions.toml
├── libs.versions.toml
├── sy.versions.toml
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── i18n-kmk
├── build.gradle.kts
└── src
│ └── commonMain
│ └── moko-resources
│ ├── ar
│ └── strings.xml
│ ├── as
│ └── strings.xml
│ ├── base
│ ├── plurals.xml
│ └── strings.xml
│ ├── ca
│ └── strings.xml
│ ├── cs
│ └── strings.xml
│ ├── da
│ └── strings.xml
│ ├── de
│ └── strings.xml
│ ├── el
│ └── strings.xml
│ ├── es
│ └── strings.xml
│ ├── fi
│ └── strings.xml
│ ├── fil
│ └── strings.xml
│ ├── fr
│ └── strings.xml
│ ├── hi
│ └── strings.xml
│ ├── hr
│ └── strings.xml
│ ├── in
│ └── strings.xml
│ ├── it
│ └── strings.xml
│ ├── ja
│ └── strings.xml
│ ├── ko
│ └── strings.xml
│ ├── nl
│ └── strings.xml
│ ├── pl
│ └── strings.xml
│ ├── pt-rBR
│ └── strings.xml
│ ├── pt
│ └── strings.xml
│ ├── ro
│ └── strings.xml
│ ├── ru
│ └── strings.xml
│ ├── sv
│ └── strings.xml
│ ├── tr
│ └── strings.xml
│ ├── uk
│ └── strings.xml
│ ├── vi
│ └── strings.xml
│ ├── zh-rCN
│ └── strings.xml
│ └── zh-rTW
│ └── strings.xml
├── i18n-sy
├── build.gradle.kts
└── src
│ └── commonMain
│ └── moko-resources
│ ├── ar
│ ├── plurals.xml
│ └── strings.xml
│ ├── as
│ ├── plurals.xml
│ └── strings.xml
│ ├── base
│ ├── plurals.xml
│ └── strings.xml
│ ├── de
│ ├── plurals.xml
│ └── strings.xml
│ ├── eo
│ ├── plurals.xml
│ └── strings.xml
│ ├── es
│ ├── plurals.xml
│ └── strings.xml
│ ├── fil
│ ├── plurals.xml
│ └── strings.xml
│ ├── fr
│ ├── plurals.xml
│ └── strings.xml
│ ├── hr
│ ├── plurals.xml
│ └── strings.xml
│ ├── hu
│ └── strings.xml
│ ├── in
│ ├── plurals.xml
│ └── strings.xml
│ ├── it
│ └── strings.xml
│ ├── ja
│ ├── plurals.xml
│ └── strings.xml
│ ├── ne
│ └── strings.xml
│ ├── pt-rBR
│ ├── plurals.xml
│ └── strings.xml
│ ├── pt
│ └── strings.xml
│ ├── ru
│ ├── plurals.xml
│ └── strings.xml
│ ├── ta
│ ├── plurals.xml
│ └── strings.xml
│ ├── tr
│ ├── plurals.xml
│ └── strings.xml
│ ├── uk
│ └── strings.xml
│ ├── vi
│ ├── plurals.xml
│ └── strings.xml
│ ├── zh-rCN
│ ├── plurals.xml
│ └── strings.xml
│ └── zh-rTW
│ ├── plurals.xml
│ └── strings.xml
├── i18n
├── README.md
├── build.gradle.kts
└── src
│ ├── androidMain
│ └── AndroidManifest.xml
│ └── commonMain
│ └── moko-resources
│ ├── am
│ ├── plurals.xml
│ └── strings.xml
│ ├── ar
│ ├── plurals.xml
│ └── strings.xml
│ ├── as
│ ├── plurals.xml
│ └── strings.xml
│ ├── base
│ ├── plurals.xml
│ └── strings.xml
│ ├── be
│ ├── plurals.xml
│ └── strings.xml
│ ├── bg
│ ├── plurals.xml
│ └── strings.xml
│ ├── bn
│ ├── plurals.xml
│ └── strings.xml
│ ├── ca
│ ├── plurals.xml
│ └── strings.xml
│ ├── ceb
│ ├── plurals.xml
│ └── strings.xml
│ ├── cs
│ ├── plurals.xml
│ └── strings.xml
│ ├── cv
│ ├── plurals.xml
│ └── strings.xml
│ ├── da
│ ├── plurals.xml
│ └── strings.xml
│ ├── de
│ ├── plurals.xml
│ └── strings.xml
│ ├── el
│ ├── plurals.xml
│ └── strings.xml
│ ├── eo
│ ├── plurals.xml
│ └── strings.xml
│ ├── es
│ ├── plurals.xml
│ └── strings.xml
│ ├── eu
│ ├── plurals.xml
│ └── strings.xml
│ ├── fa
│ ├── plurals.xml
│ └── strings.xml
│ ├── fi
│ ├── plurals.xml
│ └── strings.xml
│ ├── fil
│ ├── plurals.xml
│ └── strings.xml
│ ├── fr
│ ├── plurals.xml
│ └── strings.xml
│ ├── gl
│ ├── plurals.xml
│ └── strings.xml
│ ├── he
│ ├── plurals.xml
│ └── strings.xml
│ ├── hi
│ ├── plurals.xml
│ └── strings.xml
│ ├── hr
│ ├── plurals.xml
│ └── strings.xml
│ ├── hu
│ ├── plurals.xml
│ └── strings.xml
│ ├── in
│ ├── plurals.xml
│ └── strings.xml
│ ├── it
│ ├── plurals.xml
│ └── strings.xml
│ ├── ja
│ ├── plurals.xml
│ └── strings.xml
│ ├── jv
│ ├── plurals.xml
│ └── strings.xml
│ ├── ka-rGE
│ ├── plurals.xml
│ └── strings.xml
│ ├── kk
│ ├── plurals.xml
│ └── strings.xml
│ ├── km
│ ├── plurals.xml
│ └── strings.xml
│ ├── kn
│ ├── plurals.xml
│ └── strings.xml
│ ├── ko
│ ├── plurals.xml
│ └── strings.xml
│ ├── lt
│ ├── plurals.xml
│ └── strings.xml
│ ├── lv
│ ├── plurals.xml
│ └── strings.xml
│ ├── ml
│ ├── plurals.xml
│ └── strings.xml
│ ├── mr
│ ├── plurals.xml
│ └── strings.xml
│ ├── ms
│ ├── plurals.xml
│ └── strings.xml
│ ├── my
│ └── strings.xml
│ ├── nb-rNO
│ ├── plurals.xml
│ └── strings.xml
│ ├── ne
│ ├── plurals.xml
│ └── strings.xml
│ ├── nl
│ ├── plurals.xml
│ └── strings.xml
│ ├── nn
│ ├── plurals.xml
│ └── strings.xml
│ ├── pl
│ ├── plurals.xml
│ └── strings.xml
│ ├── pt-rBR
│ ├── plurals.xml
│ └── strings.xml
│ ├── pt
│ ├── plurals.xml
│ └── strings.xml
│ ├── ro
│ ├── plurals.xml
│ └── strings.xml
│ ├── ru
│ ├── plurals.xml
│ └── strings.xml
│ ├── sa
│ ├── plurals.xml
│ └── strings.xml
│ ├── sah
│ ├── plurals.xml
│ └── strings.xml
│ ├── sc
│ ├── plurals.xml
│ └── strings.xml
│ ├── sdh
│ ├── plurals.xml
│ └── strings.xml
│ ├── sk
│ ├── plurals.xml
│ └── strings.xml
│ ├── sq
│ ├── plurals.xml
│ └── strings.xml
│ ├── sr
│ ├── plurals.xml
│ └── strings.xml
│ ├── sv
│ ├── plurals.xml
│ └── strings.xml
│ ├── ta
│ └── strings.xml
│ ├── te
│ ├── plurals.xml
│ └── strings.xml
│ ├── th
│ ├── plurals.xml
│ └── strings.xml
│ ├── tr
│ ├── plurals.xml
│ └── strings.xml
│ ├── uk
│ ├── plurals.xml
│ └── strings.xml
│ ├── uz
│ ├── plurals.xml
│ └── strings.xml
│ ├── vi
│ ├── plurals.xml
│ └── strings.xml
│ ├── zh-rCN
│ ├── plurals.xml
│ └── strings.xml
│ └── zh-rTW
│ ├── plurals.xml
│ └── strings.xml
├── macrobenchmark
├── README.md
├── build.gradle.kts
└── src
│ └── main
│ ├── AndroidManifest.xml
│ └── java
│ └── tachiyomi
│ └── macrobenchmark
│ ├── BaselineProfileGenerator.kt
│ └── StartupBenchmark.kt
├── presentation-core
├── build.gradle.kts
├── consumer-rules.pro
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ ├── mihon
│ │ └── presentation
│ │ │ └── core
│ │ │ └── util
│ │ │ └── PagingDataUtil.kt
│ └── tachiyomi
│ │ └── presentation
│ │ └── core
│ │ ├── components
│ │ ├── ActionButton.kt
│ │ ├── AdaptiveSheet.kt
│ │ ├── Badges.kt
│ │ ├── CircularProgressIndicator.kt
│ │ ├── CollapsibleBox.kt
│ │ ├── LabeledCheckbox.kt
│ │ ├── LazyColumnWithAction.kt
│ │ ├── LazyGrid.kt
│ │ ├── LazyList.kt
│ │ ├── LinkIcon.kt
│ │ ├── ListGroupHeader.kt
│ │ ├── Pill.kt
│ │ ├── SectionCard.kt
│ │ ├── SettingsItems.kt
│ │ ├── TwoPanelBox.kt
│ │ ├── VerticalFastScroller.kt
│ │ ├── WheelPicker.kt
│ │ └── material
│ │ │ ├── AlertDialog.kt
│ │ │ ├── Button.kt
│ │ │ ├── Constants.kt
│ │ │ ├── FloatingActionButton.kt
│ │ │ ├── IconButtonTokens.kt
│ │ │ ├── IconToggleButton.kt
│ │ │ ├── NavigationBar.kt
│ │ │ ├── NavigationRail.kt
│ │ │ ├── PullRefresh.kt
│ │ │ ├── Scaffold.kt
│ │ │ ├── Slider.kt
│ │ │ ├── Surface.kt
│ │ │ └── Tabs.kt
│ │ ├── i18n
│ │ └── Localize.kt
│ │ ├── icons
│ │ ├── CustomIcons.kt
│ │ ├── Discord.kt
│ │ ├── Facebook.kt
│ │ ├── FlagEmoji.kt
│ │ ├── Github.kt
│ │ ├── Reddit.kt
│ │ └── X.kt
│ │ ├── screens
│ │ ├── EmptyScreen.kt
│ │ ├── InfoScreen.kt
│ │ └── LoadingScreen.kt
│ │ ├── theme
│ │ ├── Color.kt
│ │ └── Typography.kt
│ │ └── util
│ │ ├── Elevation.kt
│ │ ├── LazyListState.kt
│ │ ├── Modifier.kt
│ │ ├── PaddingValues.kt
│ │ ├── Preference.kt
│ │ └── Scrollbar.kt
│ └── res
│ ├── values-night
│ ├── colors.xml
│ ├── colors_cloudflare.xml
│ ├── colors_cottoncandy.xml
│ ├── colors_doom.xml
│ ├── colors_greenapple.xml
│ ├── colors_lavender.xml
│ ├── colors_matrix.xml
│ ├── colors_midnightdusk.xml
│ ├── colors_mocha.xml
│ ├── colors_monochrome.xml
│ ├── colors_nord.xml
│ ├── colors_sapphire.xml
│ ├── colors_strawberry.xml
│ ├── colors_tachiyomi.xml
│ ├── colors_tako.xml
│ ├── colors_tealturqoise.xml
│ ├── colors_tidalwave.xml
│ ├── colors_yinyang.xml
│ └── colors_yotsuba.xml
│ └── values
│ ├── colors.xml
│ ├── colors_cloudflare.xml
│ ├── colors_cottoncandy.xml
│ ├── colors_doom.xml
│ ├── colors_greenapple.xml
│ ├── colors_lavender.xml
│ ├── colors_matrix.xml
│ ├── colors_midnightdusk.xml
│ ├── colors_mocha.xml
│ ├── colors_monochrome.xml
│ ├── colors_nord.xml
│ ├── colors_sapphire.xml
│ ├── colors_strawberry.xml
│ ├── colors_tachiyomi.xml
│ ├── colors_tako.xml
│ ├── colors_tealturqoise.xml
│ ├── colors_tidalwave.xml
│ ├── colors_yinyang.xml
│ └── colors_yotsuba.xml
├── presentation-widget
├── build.gradle.kts
├── consumer-rules.pro
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── tachiyomi
│ │ └── presentation
│ │ └── widget
│ │ ├── BaseUpdatesGridGlanceWidget.kt
│ │ ├── UpdatesGridCoverScreenGlanceReceiver.kt
│ │ ├── UpdatesGridCoverScreenGlanceWidget.kt
│ │ ├── UpdatesGridGlanceReceiver.kt
│ │ ├── UpdatesGridGlanceWidget.kt
│ │ ├── WidgetManager.kt
│ │ ├── components
│ │ ├── LockedWidget.kt
│ │ ├── UpdatesMangaCover.kt
│ │ └── UpdatesWidget.kt
│ │ └── util
│ │ └── GlanceUtils.kt
│ └── res
│ ├── drawable-nodpi
│ ├── updates_grid_coverscreen_widget_preview.webp
│ └── updates_grid_widget_preview.webp
│ ├── drawable
│ ├── appwidget_background.xml
│ ├── appwidget_cover_error.xml
│ └── appwidget_coverscreen_background.xml
│ ├── layout
│ ├── appwidget_coverscreen_loading.xml
│ └── appwidget_loading.xml
│ ├── values-night-v31
│ └── colors_appwidget.xml
│ ├── values-v31
│ ├── colors_appwidget.xml
│ └── dimens.xml
│ ├── values
│ ├── colors_appwidget.xml
│ └── dimens.xml
│ └── xml
│ ├── updates_grid_homescreen_widget_info.xml
│ ├── updates_grid_lockscreen_widget_info.xml
│ └── updates_grid_samsung_cover_widget_info.xml
├── renovate.json
├── settings.gradle.kts
├── source-api
├── build.gradle.kts
├── consumer-proguard.pro
└── src
│ ├── androidMain
│ ├── AndroidManifest.xml
│ └── kotlin
│ │ └── eu
│ │ └── kanade
│ │ └── tachiyomi
│ │ ├── source
│ │ └── PreferenceScreen.kt
│ │ └── util
│ │ └── RxExtension.kt
│ └── commonMain
│ └── kotlin
│ ├── eu
│ └── kanade
│ │ └── tachiyomi
│ │ ├── source
│ │ ├── CatalogueSource.kt
│ │ ├── ConfigurableSource.kt
│ │ ├── PagePreviewSource.kt
│ │ ├── PreferenceScreen.kt
│ │ ├── Source.kt
│ │ ├── SourceFactory.kt
│ │ ├── UnmeteredSource.kt
│ │ ├── model
│ │ │ ├── Filter.kt
│ │ │ ├── FilterList.kt
│ │ │ ├── MangasPage.kt
│ │ │ ├── Page.kt
│ │ │ ├── SChapter.kt
│ │ │ ├── SChapterImpl.kt
│ │ │ ├── SManga.kt
│ │ │ ├── SMangaImpl.kt
│ │ │ └── UpdateStrategy.kt
│ │ └── online
│ │ │ ├── FollowsSource.kt
│ │ │ ├── HttpSource.kt
│ │ │ ├── LoginSource.kt
│ │ │ ├── MetadataSource.kt
│ │ │ ├── NamespaceSource.kt
│ │ │ ├── ParsedHttpSource.kt
│ │ │ ├── RandomMangaSource.kt
│ │ │ ├── ResolvableSource.kt
│ │ │ ├── UrlImportableSource.kt
│ │ │ └── all
│ │ │ └── EhBasedSource.kt
│ │ └── util
│ │ ├── JsoupExtensions.kt
│ │ └── RxExtension.kt
│ ├── exh
│ ├── md
│ │ └── utils
│ │ │ └── MangaDexRelation.kt
│ ├── metadata
│ │ ├── MetadataUtil.kt
│ │ ├── metadata
│ │ │ ├── EHentaiSearchMetadata.kt
│ │ │ ├── EightMusesSearchMetadata.kt
│ │ │ ├── HBrowseSearchMetadata.kt
│ │ │ ├── MangaDexSearchMetadata.kt
│ │ │ ├── NHentaiSearchMetadata.kt
│ │ │ ├── PururinSearchMetadata.kt
│ │ │ ├── RaisedSearchMetadata.kt
│ │ │ ├── TsuminoSearchMetadata.kt
│ │ │ └── base
│ │ │ │ ├── FlatMetadata.kt
│ │ │ │ ├── RaisedTag.kt
│ │ │ │ └── RaisedTitle.kt
│ │ └── sql
│ │ │ └── models
│ │ │ ├── SearchMetadata.kt
│ │ │ ├── SearchTag.kt
│ │ │ └── SearchTitle.kt
│ └── source
│ │ ├── DelegatedHttpSource.kt
│ │ ├── EnhancedHttpSource.kt
│ │ └── SourceIds.kt
│ └── xyz
│ └── nulldev
│ └── ts
│ └── api
│ └── http
│ └── serializer
│ ├── FilterSerializer.kt
│ └── FilterSerializerModels.kt
├── source-local
├── build.gradle.kts
├── consumer-rules.pro
├── proguard-rules.pro
└── src
│ ├── androidMain
│ ├── AndroidManifest.xml
│ └── kotlin
│ │ └── tachiyomi
│ │ └── source
│ │ └── local
│ │ ├── LocalSource.kt
│ │ ├── filter
│ │ └── OrderBy.kt
│ │ ├── image
│ │ └── LocalCoverManager.kt
│ │ ├── io
│ │ └── LocalSourceFileSystem.kt
│ │ └── metadata
│ │ └── EpubReaderExtensions.kt
│ └── commonMain
│ └── kotlin
│ └── tachiyomi
│ └── source
│ └── local
│ ├── LocalSource.kt
│ ├── image
│ └── LocalCoverManager.kt
│ └── io
│ ├── Archive.kt
│ ├── Format.kt
│ └── LocalSourceFileSystem.kt
└── telemetry
├── build.gradle.kts
└── src
├── firebase
└── kotlin
│ ├── exh
│ └── log
│ │ └── CrashlyticsPrinter.kt
│ └── mihon
│ └── telemetry
│ ├── PackageInfo.kt
│ └── TelemetryConfig.kt
├── main
└── AndroidManifest.xml
└── noop
├── AndroidManifest.xml
└── kotlin
├── exh
└── log
│ └── CrashlyticsPrinter.kt
└── mihon
└── telemetry
└── TelemetryConfig.kt
/.gemini/config.yaml:
--------------------------------------------------------------------------------
1 | have_fun: true
2 | code_review:
3 | disable: false
4 | comment_severity_threshold: LOW
5 | max_review_comments: -1
6 | pull_request_opened:
7 | help: false
8 | summary: true
9 | code_review: true
10 | ignore_patterns: []
11 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto
2 | * text eol=lf
3 |
4 | # Windows forced line-endings
5 | /.idea/* text eol=crlf
6 |
7 | # Gradle wrapper
8 | *.jar binary
9 |
10 | # Images
11 | *.webp binary
12 | *.png binary
13 | *.jpg binary
14 | *.jpeg binary
15 | *.gif binary
16 | *.ico binary
17 | *.gz binary
18 | *.zip binary
19 | *.7z binary
20 | *.ttf binary
21 | *.eot binary
22 | *.woff binary
23 | *.pyc binary
24 | *.swp binary
25 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
2 | contact_links:
3 | - name: ❌ Help with Extensions
4 | url: https://komikku-app.github.io/docs/faq/browse/extensions
5 | about: For extension-related questions/issues
6 | - name: 🖥️ Komikku website
7 | url: https://komikku-app.github.io/
8 | about: Guides, troubleshooting, and answers to common questions
9 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | # To get started with Dependabot version updates, you'll need to specify which
2 | # package ecosystems to update and where the package manifests are located.
3 | # Please see the documentation for all configuration options:
4 | # https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
5 |
6 | version: 2
7 | updates:
8 | - package-ecosystem: "github-actions"
9 | target-branch: "develop"
10 | directory: "/" # Location of package manifests
11 | schedule:
12 | interval: "weekly"
13 |
--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 |
13 |
--------------------------------------------------------------------------------
/.github/readme-images/app-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/.github/readme-images/app-icon.png
--------------------------------------------------------------------------------
/.github/readme-images/screens.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/.github/readme-images/screens.png
--------------------------------------------------------------------------------
/.github/workflows/update_website.yml:
--------------------------------------------------------------------------------
1 | name: Update website
2 |
3 | on:
4 | release:
5 | types:
6 | - published
7 | - deleted
8 | - edited
9 |
10 | jobs:
11 | update_website:
12 | runs-on: 'ubuntu-24.04'
13 |
14 | steps:
15 | - name: Update website on release
16 | uses: benc-uk/workflow-dispatch@e2e5e9a103e331dad343f381a29e654aea3cf8fc # v1.2.4
17 | with:
18 | workflow: Deploy
19 | repo: komikku-app/komikku-app.github.io
20 | ref: "refs/heads/main"
21 | token: "${{ secrets.BOT_PAT }}"
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Build files
2 | .gradle
3 | #.vscode
4 | .kotlin
5 | build
6 |
7 | # IDE files
8 | *.iml
9 | .idea/*
10 | !.idea/icon.png
11 | /captures
12 | .history
13 |
14 | # Configuration files
15 | local.properties
16 |
17 | # macOS specific files
18 | .DS_Store
19 |
20 | /app/client_secrets.json
21 | /app/google-services.json
22 | *.jks
23 | app/standard/preview/*
24 |
--------------------------------------------------------------------------------
/.idea/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/.idea/icon.png
--------------------------------------------------------------------------------
/.weblate:
--------------------------------------------------------------------------------
1 | [weblate]
2 | url = https://hosted.weblate.org/api/
3 | translation = komikku-app/komikku
4 |
--------------------------------------------------------------------------------
/app/src/beta/res/drawable/komikku.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/app/src/beta/res/drawable/komikku.png
--------------------------------------------------------------------------------
/app/src/beta/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #c837ab
4 |
5 |
--------------------------------------------------------------------------------
/app/src/debug/res/drawable/komikku.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/app/src/debug/res/drawable/komikku.png
--------------------------------------------------------------------------------
/app/src/debug/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #ffe680
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/core/preference/CheckboxState.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.core.preference
2 |
3 | import androidx.compose.ui.state.ToggleableState
4 | import tachiyomi.core.common.preference.CheckboxState
5 |
6 | fun CheckboxState.TriState.asToggleableState() = when (this) {
7 | is CheckboxState.TriState.Exclude -> ToggleableState.Indeterminate
8 | is CheckboxState.TriState.Include -> ToggleableState.On
9 | is CheckboxState.TriState.None -> ToggleableState.Off
10 | }
11 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/core/util/SourceUtil.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.core.util
2 |
3 | import androidx.compose.runtime.Composable
4 | import androidx.compose.runtime.collectAsState
5 | import androidx.compose.runtime.remember
6 | import tachiyomi.domain.source.service.SourceManager
7 | import uy.kohesive.injekt.Injekt
8 | import uy.kohesive.injekt.api.get
9 |
10 | @Composable
11 | fun ifSourcesLoaded(): Boolean {
12 | return remember { Injekt.get().isInitialized }.collectAsState().value
13 | }
14 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/domain/extension/model/Extensions.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.domain.extension.model
2 |
3 | import eu.kanade.tachiyomi.extension.model.Extension
4 |
5 | data class Extensions(
6 | val updates: List,
7 | val installed: List,
8 | val available: List,
9 | val untrusted: List,
10 | )
11 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/domain/manga/interactor/DeleteSortTag.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.domain.manga.interactor
2 |
3 | import tachiyomi.domain.library.service.LibraryPreferences
4 |
5 | class DeleteSortTag(
6 | private val preferences: LibraryPreferences,
7 | private val getSortTag: GetSortTag,
8 | ) {
9 |
10 | fun await(tag: String) {
11 | preferences.sortTagsForLibrary().set(
12 | (getSortTag.await() - tag).mapIndexed { index, s ->
13 | CreateSortTag.encodeTag(index, s)
14 | }.toSet(),
15 | )
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/domain/source/interactor/DeleteSourceCategory.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.domain.source.interactor
2 |
3 | import eu.kanade.domain.source.service.SourcePreferences
4 | import tachiyomi.core.common.preference.getAndSet
5 | import tachiyomi.core.common.preference.minusAssign
6 |
7 | class DeleteSourceCategory(private val preferences: SourcePreferences) {
8 |
9 | fun await(category: String) {
10 | preferences.sourcesTabSourcesInCategories().getAndSet { sourcesInCategories ->
11 | sourcesInCategories.filterNot { it.substringAfter("|") == category }.toSet()
12 | }
13 | preferences.sourcesTabCategories() -= category
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/domain/source/interactor/GetShowLatest.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.domain.source.interactor
2 |
3 | import eu.kanade.domain.ui.UiPreferences
4 | import kotlinx.coroutines.flow.Flow
5 | import kotlinx.coroutines.flow.map
6 |
7 | class GetShowLatest(
8 | private val preferences: UiPreferences,
9 | ) {
10 |
11 | fun subscribe(hasSmartSearchConfig: Boolean): Flow {
12 | return preferences.useNewSourceNavigation().changes()
13 | .map {
14 | !hasSmartSearchConfig && !it
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/domain/source/interactor/GetSourceCategories.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.domain.source.interactor
2 |
3 | import eu.kanade.domain.source.service.SourcePreferences
4 | import kotlinx.coroutines.flow.Flow
5 | import kotlinx.coroutines.flow.map
6 |
7 | class GetSourceCategories(
8 | private val preferences: SourcePreferences,
9 | ) {
10 |
11 | fun subscribe(): Flow> {
12 | return preferences.sourcesTabCategories().changes().map { it.sortedWith(String.CASE_INSENSITIVE_ORDER) }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/domain/source/interactor/SetMigrateSorting.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.domain.source.interactor
2 |
3 | import eu.kanade.domain.source.service.SourcePreferences
4 |
5 | class SetMigrateSorting(
6 | private val preferences: SourcePreferences,
7 | ) {
8 |
9 | fun await(mode: Mode, direction: Direction) {
10 | preferences.migrationSortingMode().set(mode)
11 | preferences.migrationSortingDirection().set(direction)
12 | }
13 |
14 | enum class Mode {
15 | ALPHABETICAL,
16 | TOTAL,
17 | }
18 |
19 | enum class Direction {
20 | ASCENDING,
21 | DESCENDING,
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/domain/source/interactor/ToggleIncognito.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.domain.source.interactor
2 |
3 | import eu.kanade.domain.source.service.SourcePreferences
4 | import tachiyomi.core.common.preference.getAndSet
5 |
6 | class ToggleIncognito(
7 | private val preferences: SourcePreferences,
8 | ) {
9 | fun await(extensions: String, enable: Boolean) {
10 | preferences.incognitoExtensions().getAndSet {
11 | if (enable) it.plus(extensions) else it.minus(extensions)
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/domain/source/interactor/ToggleLanguage.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.domain.source.interactor
2 |
3 | import eu.kanade.domain.source.service.SourcePreferences
4 | import tachiyomi.core.common.preference.getAndSet
5 |
6 | class ToggleLanguage(
7 | val preferences: SourcePreferences,
8 | ) {
9 |
10 | fun await(language: String) {
11 | val isEnabled = language in preferences.enabledLanguages().get()
12 | preferences.enabledLanguages().getAndSet { enabled ->
13 | if (isEnabled) enabled.minus(language) else enabled.plus(language)
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/domain/source/interactor/ToggleSourcePin.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.domain.source.interactor
2 |
3 | import eu.kanade.domain.source.service.SourcePreferences
4 | import tachiyomi.core.common.preference.getAndSet
5 | import tachiyomi.domain.source.model.Source
6 |
7 | class ToggleSourcePin(
8 | private val preferences: SourcePreferences,
9 | ) {
10 |
11 | fun await(source: Source) {
12 | val isPinned = source.id.toString() in preferences.pinnedSources().get()
13 | preferences.pinnedSources().getAndSet { pinned ->
14 | if (isPinned) pinned.minus("${source.id}") else pinned.plus("${source.id}")
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/domain/sync/models/SyncSettings.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.domain.sync.models
2 |
3 | data class SyncSettings(
4 | val libraryEntries: Boolean = true,
5 | val categories: Boolean = true,
6 | val chapters: Boolean = true,
7 | val tracking: Boolean = true,
8 | val history: Boolean = true,
9 | val appSettings: Boolean = true,
10 | val extensionRepoSettings: Boolean = true,
11 | val sourceSettings: Boolean = true,
12 | val privateSettings: Boolean = false,
13 |
14 | // SY -->
15 | val customInfo: Boolean = true,
16 | val readEntries: Boolean = true,
17 | val savedSearchesFeeds: Boolean = true,
18 | // SY <--
19 | )
20 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/domain/track/model/AutoTrackState.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.domain.track.model
2 |
3 | import dev.icerock.moko.resources.StringResource
4 | import tachiyomi.i18n.MR
5 |
6 | enum class AutoTrackState(val titleRes: StringResource) {
7 | ALWAYS(MR.strings.lock_always),
8 | ASK(MR.strings.default_category_summary),
9 | NEVER(MR.strings.lock_never),
10 | }
11 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/domain/ui/model/TabletUiMode.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.domain.ui.model
2 |
3 | import dev.icerock.moko.resources.StringResource
4 | import tachiyomi.i18n.MR
5 |
6 | enum class TabletUiMode(val titleRes: StringResource) {
7 | AUTOMATIC(MR.strings.automatic_background),
8 | ALWAYS(MR.strings.lock_always),
9 | LANDSCAPE(MR.strings.landscape),
10 | NEVER(MR.strings.lock_never),
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/domain/ui/model/ThemeMode.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.domain.ui.model
2 |
3 | import androidx.appcompat.app.AppCompatDelegate
4 |
5 | enum class ThemeMode {
6 | LIGHT,
7 | DARK,
8 | SYSTEM,
9 | }
10 |
11 | fun setAppCompatDelegateThemeMode(themeMode: ThemeMode) {
12 | AppCompatDelegate.setDefaultNightMode(
13 | when (themeMode) {
14 | ThemeMode.LIGHT -> AppCompatDelegate.MODE_NIGHT_NO
15 | ThemeMode.DARK -> AppCompatDelegate.MODE_NIGHT_YES
16 | ThemeMode.SYSTEM -> AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
17 | },
18 | )
19 | }
20 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/presentation/browse/components/BrowseBadges.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.presentation.browse.components
2 |
3 | import androidx.compose.material.icons.Icons
4 | import androidx.compose.material.icons.outlined.CollectionsBookmark
5 | import androidx.compose.runtime.Composable
6 | import tachiyomi.presentation.core.components.Badge
7 |
8 | @Composable
9 | internal fun InLibraryBadge(enabled: Boolean) {
10 | if (enabled) {
11 | Badge(
12 | imageVector = Icons.Outlined.CollectionsBookmark,
13 | )
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/presentation/manga/components/DotSeparatorText.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.presentation.manga.components
2 |
3 | import androidx.compose.material3.Text
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.ui.Modifier
6 |
7 | @Composable
8 | fun DotSeparatorText(
9 | modifier: Modifier = Modifier,
10 | ) {
11 | Text(
12 | text = " • ",
13 | modifier = modifier,
14 | )
15 | }
16 |
17 | @Composable
18 | fun DotSeparatorNoSpaceText(
19 | modifier: Modifier = Modifier,
20 | ) {
21 | Text(
22 | text = "•",
23 | modifier = modifier,
24 | )
25 | }
26 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/presentation/more/onboarding/OnboardingStep.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.presentation.more.onboarding
2 |
3 | import androidx.compose.runtime.Composable
4 |
5 | internal interface OnboardingStep {
6 |
7 | val isComplete: Boolean
8 |
9 | @Composable
10 | fun Content()
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/presentation/more/stats/StatsScreenState.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.presentation.more.stats
2 |
3 | import androidx.compose.runtime.Immutable
4 | import eu.kanade.presentation.more.stats.data.StatsData
5 |
6 | sealed interface StatsScreenState {
7 | @Immutable
8 | data object Loading : StatsScreenState
9 |
10 | @Immutable
11 | data class Success(
12 | val overview: StatsData.Overview,
13 | val titles: StatsData.Titles,
14 | val chapters: StatsData.Chapters,
15 | val trackers: StatsData.Trackers,
16 | ) : StatsScreenState
17 | }
18 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/presentation/util/ChapterNumberFormatter.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.presentation.util
2 |
3 | import java.text.DecimalFormat
4 | import java.text.DecimalFormatSymbols
5 |
6 | private val formatter = DecimalFormat(
7 | "#.###",
8 | DecimalFormatSymbols().apply { decimalSeparator = '.' },
9 | )
10 |
11 | fun formatChapterNumber(chapterNumber: Double): String {
12 | return formatter.format(chapterNumber)
13 | }
14 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/presentation/util/FastScrollAnimateItem.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.presentation.util
2 |
3 | import androidx.compose.foundation.lazy.LazyItemScope
4 | import androidx.compose.ui.Modifier
5 |
6 | // https://issuetracker.google.com/352584409
7 | context(LazyItemScope)
8 | fun Modifier.animateItemFastScroll() = this.animateItem(fadeInSpec = null, fadeOutSpec = null)
9 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/presentation/util/WindowSize.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.presentation.util
2 |
3 | import androidx.compose.runtime.Composable
4 | import androidx.compose.runtime.ReadOnlyComposable
5 | import androidx.compose.ui.platform.LocalConfiguration
6 | import eu.kanade.tachiyomi.util.system.isTabletUi
7 |
8 | @Composable
9 | @ReadOnlyComposable
10 | fun isTabletUi(): Boolean {
11 | return LocalConfiguration.current.isTabletUi()
12 | }
13 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/data/backup/models/BackupSource.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.data.backup.models
2 |
3 | import kotlinx.serialization.Serializable
4 | import kotlinx.serialization.protobuf.ProtoNumber
5 |
6 | @Serializable
7 | data class BackupSource(
8 | @ProtoNumber(1) var name: String = "",
9 | @ProtoNumber(2) var sourceId: Long,
10 | )
11 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/data/coil/PagePreviewKeyer.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.data.coil
2 |
3 | import coil3.key.Keyer
4 | import coil3.request.Options
5 | import eu.kanade.domain.manga.model.PagePreview
6 |
7 | class PagePreviewKeyer : Keyer {
8 | override fun key(data: PagePreview, options: Options): String {
9 | return data.imageUrl
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/data/track/DeletableTracker.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.data.track
2 |
3 | import tachiyomi.domain.track.model.Track
4 |
5 | /**
6 | * Tracker that support deleting am entry from a user's list.
7 | */
8 | interface DeletableTracker {
9 |
10 | suspend fun delete(track: Track)
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/dto/ALAddManga.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.data.track.anilist.dto
2 |
3 | import kotlinx.serialization.SerialName
4 | import kotlinx.serialization.Serializable
5 |
6 | @Serializable
7 | data class ALAddMangaResult(
8 | val data: ALAddMangaData,
9 | )
10 |
11 | @Serializable
12 | data class ALAddMangaData(
13 | @SerialName("SaveMediaListEntry")
14 | val entry: ALAddMangaEntry,
15 | )
16 |
17 | @Serializable
18 | data class ALAddMangaEntry(
19 | val id: Long,
20 | )
21 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/dto/ALFuzzyDate.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.data.track.anilist.dto
2 |
3 | import kotlinx.serialization.Serializable
4 | import java.time.LocalDate
5 | import java.time.ZoneId
6 |
7 | @Serializable
8 | data class ALFuzzyDate(
9 | val year: Int?,
10 | val month: Int?,
11 | val day: Int?,
12 | ) {
13 | fun toEpochMilli(): Long = try {
14 | LocalDate.of(year!!, month!!, day!!)
15 | .atStartOfDay(ZoneId.systemDefault())
16 | .toInstant()
17 | .toEpochMilli()
18 | } catch (_: Exception) {
19 | 0L
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/dto/ALMangaMetadata.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.data.track.anilist.dto
2 |
3 | import kotlinx.serialization.SerialName
4 | import kotlinx.serialization.Serializable
5 |
6 | @Serializable
7 | data class ALMangaMetadata(
8 | val data: ALMangaMetadataData,
9 | )
10 |
11 | @Serializable
12 | data class ALMangaMetadataData(
13 | @SerialName("Media")
14 | val media: ALMangaMetadataMedia,
15 | )
16 |
17 | @Serializable
18 | data class ALMangaMetadataMedia(
19 | val id: Long,
20 | val title: ALItemTitle,
21 | val coverImage: ItemCover,
22 | val description: String?,
23 | val staff: ALStaff,
24 | )
25 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/dto/ALOAuth.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.data.track.anilist.dto
2 |
3 | import kotlinx.serialization.SerialName
4 | import kotlinx.serialization.Serializable
5 |
6 | @Serializable
7 | data class ALOAuth(
8 | @SerialName("access_token")
9 | val accessToken: String,
10 | @SerialName("token_type")
11 | val tokenType: String,
12 | val expires: Long,
13 | @SerialName("expires_in")
14 | val expiresIn: Long,
15 | )
16 |
17 | fun ALOAuth.isExpired() = System.currentTimeMillis() > expires
18 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/dto/ALSearch.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.data.track.anilist.dto
2 |
3 | import kotlinx.serialization.SerialName
4 | import kotlinx.serialization.Serializable
5 |
6 | @Serializable
7 | data class ALSearchResult(
8 | val data: ALSearchPage,
9 | )
10 |
11 | @Serializable
12 | data class ALSearchPage(
13 | @SerialName("Page")
14 | val page: ALSearchMedia,
15 | )
16 |
17 | @Serializable
18 | data class ALSearchMedia(
19 | val media: List,
20 | )
21 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/dto/ALUser.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.data.track.anilist.dto
2 |
3 | import kotlinx.serialization.SerialName
4 | import kotlinx.serialization.Serializable
5 |
6 | @Serializable
7 | data class ALCurrentUserResult(
8 | val data: ALUserViewer,
9 | )
10 |
11 | @Serializable
12 | data class ALUserViewer(
13 | @SerialName("Viewer")
14 | val viewer: ALUserViewerData,
15 | )
16 |
17 | @Serializable
18 | data class ALUserViewerData(
19 | val id: Int,
20 | val mediaListOptions: ALUserListOptions,
21 | )
22 |
23 | @Serializable
24 | data class ALUserListOptions(
25 | val scoreFormat: String,
26 | )
27 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiUtils.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.data.track.bangumi
2 |
3 | import eu.kanade.tachiyomi.data.database.models.Track
4 |
5 | fun Track.toApiStatus() = when (status) {
6 | Bangumi.PLAN_TO_READ -> 1
7 | Bangumi.COMPLETED -> 2
8 | Bangumi.READING -> 3
9 | Bangumi.ON_HOLD -> 4
10 | Bangumi.DROPPED -> 5
11 | else -> 3
12 | }
13 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/dto/BGMUser.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.data.track.bangumi.dto
2 |
3 | import kotlinx.serialization.Serializable
4 |
5 | @Serializable
6 | // Incomplete DTO with only our needed attributes
7 | data class BGMUser(
8 | val username: String,
9 | )
10 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/data/track/kitsu/KitsuUtils.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.data.track.kitsu
2 |
3 | import eu.kanade.tachiyomi.data.database.models.Track
4 |
5 | fun Track.toApiStatus() = when (status) {
6 | Kitsu.READING -> "current"
7 | Kitsu.COMPLETED -> "completed"
8 | Kitsu.ON_HOLD -> "on_hold"
9 | Kitsu.DROPPED -> "dropped"
10 | Kitsu.PLAN_TO_READ -> "planned"
11 | else -> throw Exception("Unknown status")
12 | }
13 |
14 | fun Track.toApiScore(): String? {
15 | return if (score > 0) (score * 2).toInt().toString() else null
16 | }
17 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/data/track/kitsu/dto/KitsuAddManga.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.data.track.kitsu.dto
2 |
3 | import kotlinx.serialization.Serializable
4 |
5 | @Serializable
6 | data class KitsuAddMangaResult(
7 | val data: KitsuAddMangaItem,
8 | )
9 |
10 | @Serializable
11 | data class KitsuAddMangaItem(
12 | val id: Long,
13 | )
14 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/data/track/kitsu/dto/KitsuSearchItemCover.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.data.track.kitsu.dto
2 |
3 | import kotlinx.serialization.Serializable
4 |
5 | @Serializable
6 | data class KitsuSearchItemCover(
7 | val original: String?,
8 | )
9 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/data/track/kitsu/dto/KitsuUser.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.data.track.kitsu.dto
2 |
3 | import kotlinx.serialization.Serializable
4 |
5 | @Serializable
6 | data class KitsuCurrentUserResult(
7 | val data: List,
8 | )
9 |
10 | @Serializable
11 | data class KitsuUser(
12 | val id: String,
13 | )
14 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/data/track/mangaupdates/dto/MUContext.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.data.track.mangaupdates.dto
2 |
3 | import kotlinx.serialization.SerialName
4 | import kotlinx.serialization.Serializable
5 |
6 | @Serializable
7 | data class MUContext(
8 | @SerialName("session_token")
9 | val sessionToken: String,
10 | val uid: Long,
11 | )
12 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/data/track/mangaupdates/dto/MUImage.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.data.track.mangaupdates.dto
2 |
3 | import kotlinx.serialization.Serializable
4 |
5 | @Serializable
6 | data class MUImage(
7 | val url: MUUrl? = null,
8 | val height: Int? = null,
9 | val width: Int? = null,
10 | )
11 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/data/track/mangaupdates/dto/MULoginResponse.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.data.track.mangaupdates.dto
2 |
3 | import kotlinx.serialization.Serializable
4 |
5 | @Serializable
6 | data class MULoginResponse(
7 | val context: MUContext,
8 | )
9 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/data/track/mangaupdates/dto/MURating.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.data.track.mangaupdates.dto
2 |
3 | import eu.kanade.tachiyomi.data.database.models.Track
4 | import kotlinx.serialization.Serializable
5 |
6 | @Serializable
7 | data class MURating(
8 | val rating: Double? = null,
9 | )
10 |
11 | fun MURating.copyTo(track: Track): Track {
12 | return track.apply {
13 | this.score = rating ?: 0.0
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/data/track/mangaupdates/dto/MUSearch.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.data.track.mangaupdates.dto
2 |
3 | import kotlinx.serialization.Serializable
4 |
5 | @Serializable
6 | data class MUSearchResult(
7 | val results: List,
8 | )
9 |
10 | @Serializable
11 | data class MUSearchResultItem(
12 | val record: MURecord,
13 | )
14 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/data/track/mangaupdates/dto/MUSeries.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.data.track.mangaupdates.dto
2 |
3 | import kotlinx.serialization.Serializable
4 |
5 | @Serializable
6 | data class MUSeries(
7 | val id: Long? = null,
8 | val title: String? = null,
9 | )
10 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/data/track/mangaupdates/dto/MUStatus.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.data.track.mangaupdates.dto
2 |
3 | import kotlinx.serialization.Serializable
4 |
5 | @Serializable
6 | data class MUStatus(
7 | val volume: Int? = null,
8 | val chapter: Int? = null,
9 | )
10 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/data/track/mangaupdates/dto/MUUrl.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.data.track.mangaupdates.dto
2 |
3 | import kotlinx.serialization.Serializable
4 |
5 | @Serializable
6 | data class MUUrl(
7 | val original: String? = null,
8 | val thumb: String? = null,
9 | )
10 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/data/track/model/TrackMangaMetadata.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.data.track.model
2 |
3 | data class TrackMangaMetadata(
4 | val remoteId: Long? = null,
5 | val title: String? = null,
6 | val thumbnailUrl: String? = null,
7 | val description: String? = null,
8 | val authors: String? = null,
9 | val artists: String? = null,
10 | )
11 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/dto/MALSearch.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.data.track.myanimelist.dto
2 |
3 | import kotlinx.serialization.Serializable
4 |
5 | @Serializable
6 | data class MALSearchResult(
7 | val data: List,
8 | )
9 |
10 | @Serializable
11 | data class MALSearchResultNode(
12 | val node: MALSearchResultItem,
13 | )
14 |
15 | @Serializable
16 | data class MALSearchResultItem(
17 | val id: Int,
18 | )
19 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/dto/MALUser.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.data.track.myanimelist.dto
2 |
3 | import kotlinx.serialization.Serializable
4 |
5 | @Serializable
6 | data class MALUser(
7 | val name: String,
8 | )
9 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/dto/MALUserListSearch.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.data.track.myanimelist.dto
2 |
3 | import kotlinx.serialization.Serializable
4 |
5 | @Serializable
6 | data class MALUserSearchResult(
7 | val data: List,
8 | val paging: MALUserSearchPaging,
9 | )
10 |
11 | @Serializable
12 | data class MALUserSearchItem(
13 | val node: MALUserSearchItemNode,
14 | )
15 |
16 | @Serializable
17 | data class MALUserSearchPaging(
18 | val next: String?,
19 | )
20 |
21 | @Serializable
22 | data class MALUserSearchItemNode(
23 | val id: Int,
24 | val title: String,
25 | )
26 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/dto/SMAddMangaResponse.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.data.track.shikimori.dto
2 |
3 | import kotlinx.serialization.Serializable
4 |
5 | @Serializable
6 | data class SMAddMangaResponse(
7 | val id: Long,
8 | )
9 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/dto/SMUser.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.data.track.shikimori.dto
2 |
3 | import kotlinx.serialization.Serializable
4 |
5 | @Serializable
6 | data class SMUser(
7 | val id: Int,
8 | )
9 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/extension/model/InstallStep.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.extension.model
2 |
3 | enum class InstallStep {
4 | Idle,
5 | Pending,
6 | Downloading,
7 | Installing,
8 | Installed,
9 | Error,
10 | ;
11 |
12 | fun isCompleted(): Boolean {
13 | return this == Installed || this == Error || this == Idle
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/extension/model/LoadResult.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.extension.model
2 |
3 | sealed interface LoadResult {
4 | data class Success(val extension: Extension.Installed) : LoadResult
5 | data class Untrusted(val extension: Extension.Untrusted) : LoadResult
6 | data object Error : LoadResult
7 | }
8 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/advanced/process/MigrationProcedureConfig.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.ui.browse.migration.advanced.process
2 |
3 | import eu.kanade.tachiyomi.ui.browse.migration.advanced.design.MigrationType
4 | import java.io.Serializable
5 |
6 | data class MigrationProcedureConfig(
7 | var migration: MigrationType,
8 | val extraSearchParams: String?,
9 | ) : Serializable
10 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/ui/category/biometric/TimeRangeItem.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.ui.category.biometric
2 |
3 | data class TimeRangeItem(val timeRange: TimeRange, val formattedString: String)
4 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackItem.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.ui.manga.track
2 |
3 | import eu.kanade.tachiyomi.data.track.Tracker
4 | import tachiyomi.domain.track.model.Track
5 |
6 | data class TrackItem(val track: Track?, val tracker: Tracker)
7 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/ui/reader/chapter/ReaderChapterItem.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.ui.reader.chapter
2 |
3 | import tachiyomi.domain.chapter.model.Chapter
4 | import tachiyomi.domain.manga.model.Manga
5 | import java.time.format.DateTimeFormatter
6 |
7 | data class ReaderChapterItem(
8 | val chapter: Chapter,
9 | val manga: Manga,
10 | val isCurrent: Boolean,
11 | val dateFormat: DateTimeFormatter,
12 | )
13 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/ui/reader/model/InsertPage.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.ui.reader.model
2 |
3 | class InsertPage(val parent: ReaderPage) : ReaderPage(parent.index, parent.url, parent.imageUrl) {
4 |
5 | override var chapter: ReaderChapter = parent.chapter
6 |
7 | init {
8 | status = State.Ready
9 | stream = parent.stream
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/ui/reader/model/ReaderItem.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.ui.reader.model
2 |
3 | sealed interface ReaderItem
4 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/ui/reader/model/ViewerChapters.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.ui.reader.model
2 |
3 | data class ViewerChapters(
4 | val currChapter: ReaderChapter,
5 | val prevChapter: ReaderChapter?,
6 | val nextChapter: ReaderChapter?,
7 | ) {
8 |
9 | fun ref() {
10 | currChapter.ref()
11 | prevChapter?.ref()
12 | nextChapter?.ref()
13 | }
14 |
15 | fun unref() {
16 | currChapter.unref()
17 | prevChapter?.unref()
18 | nextChapter?.unref()
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/MissingChapters.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.ui.reader.viewer
2 |
3 | import eu.kanade.tachiyomi.data.database.models.toDomainChapter
4 | import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter
5 | import tachiyomi.domain.chapter.service.calculateChapterGap as domainCalculateChapterGap
6 |
7 | fun calculateChapterGap(higherReaderChapter: ReaderChapter?, lowerReaderChapter: ReaderChapter?): Int {
8 | return domainCalculateChapterGap(
9 | higherReaderChapter?.chapter?.toDomainChapter(),
10 | lowerReaderChapter?.chapter?.toDomainChapter(),
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/navigation/DisabledNavigation.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.ui.reader.viewer.navigation
2 |
3 | import eu.kanade.tachiyomi.ui.reader.viewer.ViewerNavigation
4 |
5 | /**
6 | * Visualization of default state without any inversion
7 | * +---+---+---+
8 | * | M | M | M | P: Previous
9 | * +---+---+---+
10 | * | M | M | M | M: Menu
11 | * +---+---+---+
12 | * | M | M | M | N: Next
13 | * +---+---+---+
14 | */
15 | class DisabledNavigation : ViewerNavigation() {
16 |
17 | override var regionList: List = emptyList()
18 | }
19 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/util/PkceUtil.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.util
2 |
3 | import java.security.SecureRandom
4 | import java.util.Base64
5 |
6 | object PkceUtil {
7 |
8 | fun generateCodeVerifier(): String {
9 | val codeVerifier = ByteArray(50)
10 | SecureRandom().nextBytes(codeVerifier)
11 | return Base64.getUrlEncoder()
12 | .withoutPadding()
13 | .encodeToString(codeVerifier)
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/util/chapter/ChapterRemoveDuplicates.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.util.chapter
2 |
3 | import tachiyomi.domain.chapter.model.Chapter
4 |
5 | /**
6 | * Returns a copy of the list with duplicate chapters removed
7 | */
8 | fun List.removeDuplicates(currentChapter: Chapter): List {
9 | return groupBy { it.chapterNumber }
10 | .map { (_, chapters) ->
11 | chapters.find { it.id == currentChapter.id }
12 | ?: chapters.find { it.scanlator == currentChapter.scanlator }
13 | ?: chapters.first()
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/util/system/AnimationExtensions.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.util.system
2 |
3 | import android.content.Context
4 | import android.provider.Settings
5 |
6 | /**
7 | * Gets the duration multiplier for general animations on the device
8 | * @see Settings.Global.ANIMATOR_DURATION_SCALE
9 | */
10 | val Context.animatorDurationScale: Float
11 | get() = Settings.Global.getFloat(this.contentResolver, Settings.Global.ANIMATOR_DURATION_SCALE, 1f)
12 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/util/system/DeviceUtilExtensions.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.util.system
2 |
3 | import android.os.Build
4 | import com.google.android.material.color.DynamicColors
5 |
6 | val DeviceUtil.isDynamicColorAvailable by lazy {
7 | DynamicColors.isDynamicColorAvailable() || (DeviceUtil.isSamsung && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
8 | }
9 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/util/system/DrawableExtensions.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.util.system
2 |
3 | import android.graphics.Bitmap
4 | import android.graphics.drawable.BitmapDrawable
5 | import android.graphics.drawable.Drawable
6 | import androidx.core.graphics.drawable.toBitmap
7 | import coil3.size.ScaleDrawable
8 |
9 | fun Drawable.getBitmapOrNull(): Bitmap? = when (this) {
10 | is BitmapDrawable -> bitmap
11 | is ScaleDrawable -> child.toBitmap()
12 | else -> null
13 | }
14 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/util/view/EditTextPreferenceExtensions.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package androidx.preference
4 |
5 | /**
6 | * Returns package-private [EditTextPreference.getOnBindEditTextListener]
7 | */
8 | fun EditTextPreference.getOnBindEditTextListener(): EditTextPreference.OnBindEditTextListener? {
9 | return onBindEditTextListener
10 | }
11 |
--------------------------------------------------------------------------------
/app/src/main/java/eu/kanade/tachiyomi/util/view/WindowExtensions.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.util.view
2 |
3 | import android.view.Window
4 | import android.view.WindowManager
5 |
6 | fun Window.setSecureScreen(enabled: Boolean) {
7 | if (enabled) {
8 | setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE)
9 | } else {
10 | clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/app/src/main/java/exh/assets/EhAssets.kt:
--------------------------------------------------------------------------------
1 | package exh.assets
2 |
3 | object EhAssets
4 |
--------------------------------------------------------------------------------
/app/src/main/java/exh/eh/EHentaiUpdaterStats.kt:
--------------------------------------------------------------------------------
1 | package exh.eh
2 |
3 | import kotlinx.serialization.Serializable
4 |
5 | @Serializable
6 | data class EHentaiUpdaterStats(
7 | val startTime: Long,
8 | val possibleUpdates: Int,
9 | val updateCount: Int,
10 | )
11 |
--------------------------------------------------------------------------------
/app/src/main/java/exh/eh/GalleryNotUpdatedException.kt:
--------------------------------------------------------------------------------
1 | package exh.eh
2 |
3 | class GalleryNotUpdatedException(val network: Boolean, cause: Throwable) : RuntimeException(cause)
4 |
--------------------------------------------------------------------------------
/app/src/main/java/exh/eh/tags/Reclass.kt:
--------------------------------------------------------------------------------
1 | package exh.eh.tags
2 |
3 | object Reclass : TagList {
4 | override fun getTags1(): List = listOf(
5 | "reclass:artistcg",
6 | "reclass:asianporn",
7 | "reclass:cosplay",
8 | "reclass:doujinshi",
9 | "reclass:gamecg",
10 | "reclass:imageset",
11 | "reclass:manga",
12 | "reclass:misc",
13 | "reclass:non-h",
14 | "reclass:western",
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/app/src/main/java/exh/eh/tags/TagList.kt:
--------------------------------------------------------------------------------
1 | package exh.eh.tags
2 |
3 | interface TagList {
4 | fun getTags1(): List
5 |
6 | fun getTags2(): List = emptyList()
7 |
8 | fun getTags3(): List = emptyList()
9 |
10 | fun getTags(): List> = listOf(
11 | getTags1(),
12 | getTags2(),
13 | getTags3(),
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/app/src/main/java/exh/md/dto/AtHomeDto.kt:
--------------------------------------------------------------------------------
1 | package exh.md.dto
2 |
3 | import kotlinx.serialization.Serializable
4 |
5 | @Serializable
6 | data class AtHomeDto(
7 | val baseUrl: String,
8 | val chapter: AtHomeChapterDto,
9 | )
10 |
11 | @Serializable
12 | data class AtHomeChapterDto(
13 | val hash: String,
14 | val data: List,
15 | val dataSaver: List,
16 | )
17 |
18 | @Serializable
19 | data class AtHomeImageReportDto(
20 | val url: String,
21 | val success: Boolean,
22 | val bytes: Int? = null,
23 | val cached: Boolean? = null,
24 | val duration: Long,
25 | )
26 |
--------------------------------------------------------------------------------
/app/src/main/java/exh/md/dto/ListCallDto.kt:
--------------------------------------------------------------------------------
1 | package exh.md.dto
2 |
3 | interface ListCallDto {
4 | val limit: Int
5 | val offset: Int
6 | val total: Int
7 | val data: List
8 | }
9 |
--------------------------------------------------------------------------------
/app/src/main/java/exh/md/dto/RatingDto.kt:
--------------------------------------------------------------------------------
1 | package exh.md.dto
2 |
3 | import kotlinx.serialization.Serializable
4 | import kotlinx.serialization.json.JsonElement
5 |
6 | @Serializable
7 | data class RatingResponseDto(
8 | val ratings: JsonElement,
9 | )
10 |
11 | @Serializable
12 | data class PersonalRatingDto(
13 | val rating: Int,
14 | val createdAt: String,
15 | )
16 |
17 | @Serializable
18 | data class RatingDto(val rating: Int)
19 |
--------------------------------------------------------------------------------
/app/src/main/java/exh/md/dto/ResultDto.kt:
--------------------------------------------------------------------------------
1 | package exh.md.dto
2 |
3 | import kotlinx.serialization.Serializable
4 |
5 | @Serializable
6 | data class ResultDto(
7 | val result: String,
8 | )
9 |
--------------------------------------------------------------------------------
/app/src/main/java/exh/md/dto/StatisticsDto.kt:
--------------------------------------------------------------------------------
1 | package exh.md.dto
2 |
3 | import kotlinx.serialization.Serializable
4 |
5 | @Serializable
6 | data class StatisticsDto(
7 | val statistics: Map,
8 | )
9 |
10 | @Serializable
11 | data class StatisticsMangaDto(
12 | val rating: StatisticsMangaRatingDto,
13 | )
14 |
15 | @Serializable
16 | data class StatisticsMangaRatingDto(
17 | val average: Double?,
18 | val bayesian: Double?,
19 | )
20 |
--------------------------------------------------------------------------------
/app/src/main/java/exh/md/follows/MangaDexFollowsPagingSource.kt:
--------------------------------------------------------------------------------
1 | package exh.md.follows
2 |
3 | import eu.kanade.tachiyomi.source.model.MangasPage
4 | import eu.kanade.tachiyomi.source.online.all.MangaDex
5 | import tachiyomi.data.source.BaseSourcePagingSource
6 |
7 | /**
8 | * LatestUpdatesPager inherited from the general Pager.
9 | */
10 | class MangaDexFollowsPagingSource(val mangadex: MangaDex) : BaseSourcePagingSource(mangadex) {
11 |
12 | override suspend fun requestNextPage(currentPage: Int): MangasPage {
13 | return mangadex.fetchFollows(currentPage)
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/app/src/main/java/exh/search/MultiWildcard.kt:
--------------------------------------------------------------------------------
1 | package exh.search
2 |
3 | class MultiWildcard(rawText: String) : TextComponent(rawText)
4 |
--------------------------------------------------------------------------------
/app/src/main/java/exh/search/Namespace.kt:
--------------------------------------------------------------------------------
1 | package exh.search
2 |
3 | class Namespace(
4 | var namespace: String,
5 | var tag: Text? = null,
6 | ) : QueryComponent()
7 |
--------------------------------------------------------------------------------
/app/src/main/java/exh/search/QueryComponent.kt:
--------------------------------------------------------------------------------
1 | package exh.search
2 |
3 | open class QueryComponent {
4 | var excluded = false
5 | var exact = false
6 | }
7 |
--------------------------------------------------------------------------------
/app/src/main/java/exh/search/SingleWildcard.kt:
--------------------------------------------------------------------------------
1 | package exh.search
2 |
3 | class SingleWildcard(rawText: String) : TextComponent(rawText)
4 |
--------------------------------------------------------------------------------
/app/src/main/java/exh/search/StringTextComponent.kt:
--------------------------------------------------------------------------------
1 | package exh.search
2 |
3 | class StringTextComponent(val value: String) : TextComponent(value)
4 |
--------------------------------------------------------------------------------
/app/src/main/java/exh/search/TextComponent.kt:
--------------------------------------------------------------------------------
1 | package exh.search
2 |
3 | open class TextComponent(val rawText: String)
4 |
--------------------------------------------------------------------------------
/app/src/main/java/exh/source/BlacklistedSources.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PropertyName")
2 |
3 | package exh.source
4 |
5 | object BlacklistedSources {
6 | val BLACKLISTED_EXT_SOURCES = EHENTAI_EXT_SOURCES.keys
7 |
8 | val BLACKLISTED_EXTENSIONS = arrayOf(
9 | "eu.kanade.tachiyomi.extension.all.ehentai",
10 | )
11 |
12 | var HIDDEN_SOURCES = setOf(
13 | MERGED_SOURCE_ID,
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/app/src/main/java/exh/uconfig/EHHathPerksResponse.kt:
--------------------------------------------------------------------------------
1 | package exh.uconfig
2 |
3 | class EHHathPerksResponse {
4 | var moreThumbs = false
5 | var thumbsUp = false
6 | var allThumbs = false
7 |
8 | var pagingEnlargementI = false
9 | var pagingEnlargementII = false
10 | var pagingEnlargementIII = false
11 |
12 | override fun toString() =
13 | "EHHathPerksResponse(moreThumbs=$moreThumbs, thumbsUp=$thumbsUp, allThumbs=$allThumbs, pagingEnlargementI=$pagingEnlargementI, pagingEnlargementII=$pagingEnlargementII, pagingEnlargementIII=$pagingEnlargementIII)"
14 | }
15 |
--------------------------------------------------------------------------------
/app/src/main/java/exh/util/Boolean.kt:
--------------------------------------------------------------------------------
1 | package exh.util
2 |
3 | infix fun > T.over(other: T) = this > other
4 |
5 | infix fun > T.overEq(other: T) = this >= other
6 |
7 | infix fun > T.under(other: T) = this < other
8 |
9 | infix fun > T.underEq(other: T) = this <= other
10 |
--------------------------------------------------------------------------------
/app/src/main/java/exh/util/CoroutineUtil.kt:
--------------------------------------------------------------------------------
1 | package exh.util
2 |
3 | import kotlinx.coroutines.ensureActive
4 | import kotlinx.coroutines.flow.Flow
5 | import kotlinx.coroutines.flow.onEach
6 | import kotlin.coroutines.coroutineContext
7 |
8 | fun Flow.cancellable() = onEach {
9 | coroutineContext.ensureActive()
10 | }
11 |
--------------------------------------------------------------------------------
/app/src/main/java/exh/util/ExceptionUtil.kt:
--------------------------------------------------------------------------------
1 | package exh.util
2 |
3 | inline fun ignore(expr: () -> T): T? {
4 | return try {
5 | expr()
6 | } catch (t: Throwable) {
7 | null
8 | }
9 | }
10 |
11 | fun T.withRootCause(cause: Throwable): T {
12 | val curCause = this.cause
13 |
14 | if (curCause == null) {
15 | this.initCause(cause)
16 | } else {
17 | curCause.withRootCause(cause)
18 | }
19 |
20 | return this
21 | }
22 |
--------------------------------------------------------------------------------
/app/src/main/java/exh/util/Math.kt:
--------------------------------------------------------------------------------
1 | package exh.util
2 |
3 | import kotlin.math.floor
4 |
5 | fun Float.floor(): Int = floor(this).toInt()
6 |
7 | fun Double.floor(): Int = floor(this).toInt()
8 |
9 | fun Int.nullIfZero() = takeUnless { it == 0 }
10 |
11 | fun Long.nullIfZero() = takeUnless { it == 0L }
12 |
--------------------------------------------------------------------------------
/app/src/main/java/exh/util/UriFilter.kt:
--------------------------------------------------------------------------------
1 | package exh.util
2 |
3 | import android.net.Uri
4 |
5 | /**
6 | * Uri filter
7 | */
8 | interface UriFilter {
9 | fun addToUri(builder: Uri.Builder)
10 | }
11 |
--------------------------------------------------------------------------------
/app/src/main/java/exh/util/UriGroup.kt:
--------------------------------------------------------------------------------
1 | package exh.util
2 |
3 | import android.net.Uri
4 | import eu.kanade.tachiyomi.source.model.Filter
5 |
6 | /**
7 | * UriGroup
8 | */
9 | open class UriGroup(name: String, state: List) : Filter.Group(name, state), UriFilter {
10 | override fun addToUri(builder: Uri.Builder) {
11 | state.forEach {
12 | if (it is UriFilter) it.addToUri(builder)
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/app/src/main/java/mihon/core/migration/MigrationCompletedListener.kt:
--------------------------------------------------------------------------------
1 | package mihon.core.migration
2 |
3 | typealias MigrationCompletedListener = () -> Unit
4 |
--------------------------------------------------------------------------------
/app/src/main/java/mihon/core/migration/MigrationContext.kt:
--------------------------------------------------------------------------------
1 | package mihon.core.migration
2 |
3 | import uy.kohesive.injekt.Injekt
4 |
5 | class MigrationContext(val dryrun: Boolean) {
6 |
7 | inline fun get(): T? {
8 | return Injekt.getInstanceOrNull(T::class.java)
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/app/src/main/java/mihon/core/migration/migrations/SetupBackupCreateMigration.kt:
--------------------------------------------------------------------------------
1 | package mihon.core.migration.migrations
2 |
3 | import android.app.Application
4 | import eu.kanade.tachiyomi.data.backup.create.BackupCreateJob
5 | import mihon.core.migration.Migration
6 | import mihon.core.migration.MigrationContext
7 |
8 | class SetupBackupCreateMigration : Migration {
9 | override val version: Float = Migration.ALWAYS
10 |
11 | override suspend fun invoke(migrationContext: MigrationContext): Boolean {
12 | val context = migrationContext.get() ?: return false
13 | BackupCreateJob.setupTask(context)
14 | return true
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/app/src/main/java/mihon/core/migration/migrations/SetupEHentaiUpdateMigration.kt:
--------------------------------------------------------------------------------
1 | package mihon.core.migration.migrations
2 |
3 | import android.app.Application
4 | import exh.eh.EHentaiUpdateWorker
5 | import mihon.core.migration.Migration
6 | import mihon.core.migration.MigrationContext
7 |
8 | class SetupEHentaiUpdateMigration : Migration {
9 | override val version: Float = Migration.ALWAYS
10 |
11 | override suspend fun invoke(migrationContext: MigrationContext): Boolean {
12 | val context = migrationContext.get() ?: return false
13 | EHentaiUpdateWorker.scheduleBackground(context)
14 | return true
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/app/src/main/java/mihon/core/migration/migrations/SetupLibraryUpdateMigration.kt:
--------------------------------------------------------------------------------
1 | package mihon.core.migration.migrations
2 |
3 | import android.app.Application
4 | import eu.kanade.tachiyomi.data.library.LibraryUpdateJob
5 | import mihon.core.migration.Migration
6 | import mihon.core.migration.MigrationContext
7 |
8 | class SetupLibraryUpdateMigration : Migration {
9 | override val version: Float = Migration.ALWAYS
10 |
11 | override suspend fun invoke(migrationContext: MigrationContext): Boolean {
12 | val context = migrationContext.get() ?: return false
13 | LibraryUpdateJob.setupTask(context)
14 | return true
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/app/src/main/java/mihon/core/migration/migrations/SetupSyncDataMigration.kt:
--------------------------------------------------------------------------------
1 | package mihon.core.migration.migrations
2 |
3 | import android.app.Application
4 | import eu.kanade.tachiyomi.data.sync.SyncDataJob
5 | import mihon.core.migration.Migration
6 | import mihon.core.migration.MigrationContext
7 |
8 | class SetupSyncDataMigration : Migration {
9 | override val version: Float = Migration.ALWAYS
10 |
11 | override suspend fun invoke(migrationContext: MigrationContext): Boolean {
12 | val context = migrationContext.get() ?: return false
13 | SyncDataJob.setupTask(context)
14 | return true
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/app/src/main/java/mihon/feature/upcoming/UpcomingUIModel.kt:
--------------------------------------------------------------------------------
1 | package mihon.feature.upcoming
2 |
3 | import tachiyomi.domain.manga.model.Manga
4 | import java.time.LocalDate
5 |
6 | sealed interface UpcomingUIModel {
7 | data class Header(val date: LocalDate, val mangaCount: Int) : UpcomingUIModel
8 | data class Item(val manga: Manga) : UpcomingUIModel
9 | }
10 |
--------------------------------------------------------------------------------
/app/src/main/res/anim-v33/shared_axis_x_pop_enter.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/anim-v33/shared_axis_x_pop_exit.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/anim-v33/shared_axis_x_push_enter.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/anim-v33/shared_axis_x_push_exit.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/fade_in_side.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/fade_in_side_left.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/fade_out_side.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/fade_out_side_left.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/shared_axis_x_pop_enter.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/shared_axis_x_pop_exit.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/shared_axis_x_push_enter.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/shared_axis_x_push_exit.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/color/draggable_card_foreground.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_page_next_outline_24dp.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_splash.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-nodpi/ic_manga_updates.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/app/src/main/res/drawable-nodpi/ic_manga_updates.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable-nodpi/ic_tracker_anilist.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/app/src/main/res/drawable-nodpi/ic_tracker_anilist.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable-nodpi/ic_tracker_bangumi.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/app/src/main/res/drawable-nodpi/ic_tracker_bangumi.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable-nodpi/ic_tracker_kavita.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/app/src/main/res/drawable-nodpi/ic_tracker_kavita.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable-nodpi/ic_tracker_kitsu.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/app/src/main/res/drawable-nodpi/ic_tracker_kitsu.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable-nodpi/ic_tracker_komga.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/app/src/main/res/drawable-nodpi/ic_tracker_komga.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable-nodpi/ic_tracker_mal.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/app/src/main/res/drawable-nodpi/ic_tracker_mal.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable-nodpi/ic_tracker_shikimori.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/app/src/main/res/drawable-nodpi/ic_tracker_shikimori.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable-nodpi/ic_tracker_suwayomi.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/app/src/main/res/drawable-nodpi/ic_tracker_suwayomi.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable/cover_error.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | -
5 |
6 |
7 |
8 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_add_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_book_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_browse_filled_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_close_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_crop_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_delete_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_done_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_done_prev_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_drag_handle_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_extension_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_flag_esperanto.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_folder_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_format_list_numbered_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_get_app_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_info_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_keyboard_arrow_down_white_32dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_keyboard_arrow_up_white_32dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_label_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launch.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_outline_sd_card_24.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_overflow_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_pause_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_photo_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_play_arrow_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_reader_vertical_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_reader_webtoon_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_refresh_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_save_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_splash.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_sync_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_system_update_alt_white_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_ungroup_24dp.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_warning_white_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/komikku.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/app/src/main/res/drawable/komikku.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/line_divider.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/material_popup_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 | -
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/rounded_rectangle.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/download_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/edit_merged_settings_dialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/pre_migration_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/pref_widget_switch_material.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_default_source.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/app/src/main/res/mipmap-hdpi/ic_default_source.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_ehentai_source.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/app/src/main/res/mipmap-hdpi/ic_ehentai_source.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_exhentai_source.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/app/src/main/res/mipmap-hdpi/ic_exhentai_source.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_local_source.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/app/src/main/res/mipmap-hdpi/ic_local_source.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_merged_source.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/app/src/main/res/mipmap-hdpi/ic_merged_source.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_default_source.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/app/src/main/res/mipmap-mdpi/ic_default_source.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_ehentai_source.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/app/src/main/res/mipmap-mdpi/ic_ehentai_source.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_exhentai_source.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/app/src/main/res/mipmap-mdpi/ic_exhentai_source.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_local_source.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/app/src/main/res/mipmap-mdpi/ic_local_source.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_merged_source.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/app/src/main/res/mipmap-mdpi/ic_merged_source.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_default_source.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/app/src/main/res/mipmap-xhdpi/ic_default_source.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_ehentai_source.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/app/src/main/res/mipmap-xhdpi/ic_ehentai_source.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_exhentai_source.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/app/src/main/res/mipmap-xhdpi/ic_exhentai_source.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_local_source.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/app/src/main/res/mipmap-xhdpi/ic_local_source.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_merged_source.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/app/src/main/res/mipmap-xhdpi/ic_merged_source.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_default_source.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/app/src/main/res/mipmap-xxhdpi/ic_default_source.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_ehentai_source.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/app/src/main/res/mipmap-xxhdpi/ic_ehentai_source.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_exhentai_source.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/app/src/main/res/mipmap-xxhdpi/ic_exhentai_source.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_local_source.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/app/src/main/res/mipmap-xxhdpi/ic_local_source.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_merged_source.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/app/src/main/res/mipmap-xxhdpi/ic_merged_source.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_default_source.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/app/src/main/res/mipmap-xxxhdpi/ic_default_source.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_ehentai_source.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/app/src/main/res/mipmap-xxxhdpi/ic_ehentai_source.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_exhentai_source.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/app/src/main/res/mipmap-xxxhdpi/ic_exhentai_source.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_local_source.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/app/src/main/res/mipmap-xxxhdpi/ic_local_source.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_merged_source.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/app/src/main/res/mipmap-xxxhdpi/ic_merged_source.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap/extension.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/app/src/main/res/mipmap/extension.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap/komikku.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/app/src/main/res/mipmap/komikku.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap/repo.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/app/src/main/res/mipmap/repo.jpeg
--------------------------------------------------------------------------------
/app/src/main/res/values-night/bools.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | false
4 | false
5 | true
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values-v27/bools.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | true
4 | true
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values-v27/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/values/bools.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | true
4 | false
5 | false
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #ff5555
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 | 16dp
3 | 12dp
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values/ids.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/provider_paths.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
9 |
12 |
15 |
16 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/searchable.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
--------------------------------------------------------------------------------
/build.gradle.kts:
--------------------------------------------------------------------------------
1 | buildscript {
2 | dependencies {
3 | // classpath(libs.android.shortcut.gradle)
4 | classpath(sylibs.gradleversionsx)
5 | }
6 | }
7 |
8 | plugins {
9 | alias(kotlinx.plugins.serialization) apply false
10 | alias(libs.plugins.aboutLibraries) apply false
11 | alias(libs.plugins.firebase.crashlytics) apply false
12 | alias(libs.plugins.google.services) apply false
13 | alias(libs.plugins.moko) apply false
14 | alias(libs.plugins.sqldelight) apply false
15 | }
16 |
17 | tasks.register("clean") {
18 | delete(rootProject.layout.buildDirectory)
19 | }
20 |
--------------------------------------------------------------------------------
/buildSrc/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | dependencyResolutionManagement {
2 | versionCatalogs {
3 | create("libs") {
4 | from(files("../gradle/libs.versions.toml"))
5 | }
6 | create("androidx") {
7 | from(files("../gradle/androidx.versions.toml"))
8 | }
9 | create("compose") {
10 | from(files("../gradle/compose.versions.toml"))
11 | }
12 | create("kotlinx") {
13 | from(files("../gradle/kotlinx.versions.toml"))
14 | }
15 | }
16 | }
17 |
18 | rootProject.name = "komikku-buildSrc"
19 |
--------------------------------------------------------------------------------
/buildSrc/src/main/kotlin/mihon.android.application.compose.gradle.kts:
--------------------------------------------------------------------------------
1 | import mihon.buildlogic.configureCompose
2 |
3 | plugins {
4 | id("com.android.application")
5 | kotlin("android")
6 |
7 | id("mihon.code.lint")
8 | }
9 |
10 | android {
11 | configureCompose(this)
12 | }
13 |
--------------------------------------------------------------------------------
/buildSrc/src/main/kotlin/mihon.android.application.gradle.kts:
--------------------------------------------------------------------------------
1 | import mihon.buildlogic.AndroidConfig
2 | import mihon.buildlogic.configureAndroid
3 | import mihon.buildlogic.configureTest
4 |
5 | plugins {
6 | id("com.android.application")
7 | kotlin("android")
8 |
9 | id("mihon.code.lint")
10 | }
11 |
12 | android {
13 | defaultConfig {
14 | targetSdk = AndroidConfig.TARGET_SDK
15 | }
16 | configureAndroid(this)
17 | configureTest()
18 | }
19 |
--------------------------------------------------------------------------------
/buildSrc/src/main/kotlin/mihon.benchmark.gradle.kts:
--------------------------------------------------------------------------------
1 | import mihon.buildlogic.configureAndroid
2 | import mihon.buildlogic.configureTest
3 |
4 | plugins {
5 | id("com.android.test")
6 | kotlin("android")
7 |
8 | id("mihon.code.lint")
9 | }
10 |
11 | android {
12 | configureAndroid(this)
13 | configureTest()
14 | }
15 |
--------------------------------------------------------------------------------
/buildSrc/src/main/kotlin/mihon.library.compose.gradle.kts:
--------------------------------------------------------------------------------
1 | import mihon.buildlogic.configureCompose
2 |
3 | plugins {
4 | id("com.android.library")
5 |
6 | id("mihon.code.lint")
7 | }
8 |
9 | android {
10 | configureCompose(this)
11 | }
12 |
--------------------------------------------------------------------------------
/buildSrc/src/main/kotlin/mihon.library.gradle.kts:
--------------------------------------------------------------------------------
1 | import mihon.buildlogic.configureAndroid
2 | import mihon.buildlogic.configureTest
3 |
4 | plugins {
5 | id("com.android.library")
6 |
7 | id("mihon.code.lint")
8 | }
9 |
10 | android {
11 | configureAndroid(this)
12 | configureTest()
13 | }
14 |
--------------------------------------------------------------------------------
/buildSrc/src/main/kotlin/mihon/buildlogic/AndroidConfig.kt:
--------------------------------------------------------------------------------
1 | package mihon.buildlogic
2 |
3 | import org.gradle.api.JavaVersion as GradleJavaVersion
4 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget as KotlinJvmTarget
5 |
6 | object AndroidConfig {
7 | const val COMPILE_SDK = 35
8 | const val TARGET_SDK = 34
9 | const val MIN_SDK = 26
10 | const val NDK = "27.1.12297006"
11 | const val BUILD_TOOLS = "35.0.1"
12 |
13 | // https://youtrack.jetbrains.com/issue/KT-66995/JvmTarget-and-JavaVersion-compatibility-for-easier-JVM-version-setup
14 | val JavaVersion = GradleJavaVersion.VERSION_17
15 | val JvmTarget = KotlinJvmTarget.JVM_17
16 | }
17 |
--------------------------------------------------------------------------------
/core-metadata/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("mihon.library")
3 | kotlin("android")
4 | kotlin("plugin.serialization")
5 | }
6 |
7 | android {
8 | namespace = "tachiyomi.core.metadata"
9 |
10 | defaultConfig {
11 | testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
12 | consumerProguardFiles("consumer-rules.pro")
13 | }
14 | }
15 |
16 | dependencies {
17 | implementation(projects.sourceApi)
18 |
19 | implementation(kotlinx.bundles.serialization)
20 | }
21 |
--------------------------------------------------------------------------------
/core-metadata/consumer-rules.pro:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/core-metadata/consumer-rules.pro
--------------------------------------------------------------------------------
/core-metadata/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/core-metadata/src/main/java/tachiyomi/core/metadata/tachiyomi/MangaDetails.kt:
--------------------------------------------------------------------------------
1 | package tachiyomi.core.metadata.tachiyomi
2 |
3 | import kotlinx.serialization.Serializable
4 |
5 | @Serializable
6 | class MangaDetails(
7 | val title: String? = null,
8 | val author: String? = null,
9 | val artist: String? = null,
10 | val description: String? = null,
11 | val genre: List? = null,
12 | val status: Int? = null,
13 | )
14 |
--------------------------------------------------------------------------------
/core/archive/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("mihon.library")
3 | kotlin("android")
4 | kotlin("plugin.serialization")
5 | }
6 |
7 | android {
8 | namespace = "mihon.core.archive"
9 | }
10 |
11 | dependencies {
12 | implementation(libs.jsoup)
13 | implementation(libs.libarchive)
14 | implementation(libs.unifile)
15 | // KMK -->
16 | implementation(projects.core.common)
17 | implementation(libs.injekt)
18 | // KMK <--
19 | }
20 |
--------------------------------------------------------------------------------
/core/archive/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/core/archive/src/main/kotlin/mihon/core/archive/ArchiveEntry.kt:
--------------------------------------------------------------------------------
1 | package mihon.core.archive
2 |
3 | class ArchiveEntry(
4 | val name: String,
5 | val isFile: Boolean,
6 | val isEncrypted: Boolean,
7 | )
8 |
--------------------------------------------------------------------------------
/core/archive/src/main/kotlin/mihon/core/archive/UniFileExtensions.kt:
--------------------------------------------------------------------------------
1 | package mihon.core.archive
2 |
3 | import android.content.Context
4 | import android.os.ParcelFileDescriptor
5 | import com.hippo.unifile.UniFile
6 |
7 | internal fun UniFile.openFileDescriptor(context: Context, mode: String): ParcelFileDescriptor =
8 | context.contentResolver.openFileDescriptor(uri, mode) ?: error("Failed to open file descriptor: ${filePath ?: uri}")
9 |
10 | fun UniFile.archiveReader(context: Context) = openFileDescriptor(context, "r").use { ArchiveReader(it) }
11 |
12 | fun UniFile.epubReader(context: Context) = EpubReader(archiveReader(context))
13 |
--------------------------------------------------------------------------------
/core/common/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/core/common/src/main/kotlin/eu/kanade/tachiyomi/core/security/PrivacyPreferences.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.core.security
2 |
3 | import tachiyomi.core.common.preference.PreferenceStore
4 |
5 | class PrivacyPreferences(
6 | private val preferenceStore: PreferenceStore,
7 | ) {
8 | fun crashlytics() = preferenceStore.getBoolean("crashlytics", true)
9 |
10 | fun analytics() = preferenceStore.getBoolean("analytics", true)
11 | }
12 |
--------------------------------------------------------------------------------
/core/common/src/main/kotlin/eu/kanade/tachiyomi/network/ProgressListener.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.network
2 |
3 | interface ProgressListener {
4 | fun update(bytesRead: Long, contentLength: Long, done: Boolean)
5 | }
6 |
--------------------------------------------------------------------------------
/core/common/src/main/kotlin/eu/kanade/tachiyomi/util/system/DensityExtensions.kt:
--------------------------------------------------------------------------------
1 | package eu.kanade.tachiyomi.util.system
2 |
3 | import android.content.res.Resources
4 |
5 | /**
6 | * Converts to px.
7 | */
8 | val Int.dpToPx: Int
9 | get() = (this * Resources.getSystem().displayMetrics.density).toInt()
10 |
--------------------------------------------------------------------------------
/core/common/src/main/kotlin/exh/pref/DelegateSourcePreferences.kt:
--------------------------------------------------------------------------------
1 | package exh.pref
2 |
3 | import tachiyomi.core.common.preference.PreferenceStore
4 |
5 | class DelegateSourcePreferences(
6 | private val preferenceStore: PreferenceStore,
7 | ) {
8 |
9 | fun delegateSources() = preferenceStore.getBoolean("eh_delegate_sources", true)
10 |
11 | fun useJapaneseTitle() = preferenceStore.getBoolean("use_jp_title", false)
12 | }
13 |
--------------------------------------------------------------------------------
/core/common/src/main/kotlin/exh/util/ListUtil.kt:
--------------------------------------------------------------------------------
1 | package exh.util
2 |
3 | fun , R> C.nullIfEmpty() = ifEmpty { null }
4 |
--------------------------------------------------------------------------------
/core/common/src/main/kotlin/exh/util/StringBuilderExtensions.kt:
--------------------------------------------------------------------------------
1 | package exh.util
2 |
3 | operator fun StringBuilder.plusAssign(other: String) {
4 | append(other)
5 | }
6 |
--------------------------------------------------------------------------------
/core/common/src/main/kotlin/tachiyomi/core/common/preference/TriState.kt:
--------------------------------------------------------------------------------
1 | package tachiyomi.core.common.preference
2 |
3 | enum class TriState {
4 | DISABLED, // Disable filter
5 | ENABLED_IS, // Enabled with "is" filter
6 | ENABLED_NOT, // Enabled with "not" filter
7 | ;
8 |
9 | fun next(): TriState {
10 | return when (this) {
11 | DISABLED -> ENABLED_IS
12 | ENABLED_IS -> ENABLED_NOT
13 | ENABLED_NOT -> DISABLED
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/core/common/src/main/kotlin/tachiyomi/core/common/storage/FolderProvider.kt:
--------------------------------------------------------------------------------
1 | package tachiyomi.core.common.storage
2 |
3 | import java.io.File
4 |
5 | interface FolderProvider {
6 |
7 | fun directory(): File
8 |
9 | fun path(): String
10 | }
11 |
--------------------------------------------------------------------------------
/core/common/src/main/kotlin/tachiyomi/core/common/storage/UniFileExtensions.kt:
--------------------------------------------------------------------------------
1 | package tachiyomi.core.common.storage
2 |
3 | import com.hippo.unifile.UniFile
4 |
5 | val UniFile.extension: String?
6 | get() = name?.substringAfterLast('.')
7 |
8 | val UniFile.nameWithoutExtension: String?
9 | get() = name?.substringBeforeLast('.')
10 |
11 | val UniFile.displayablePath: String
12 | get() = filePath ?: uri.toString()
13 |
--------------------------------------------------------------------------------
/core/common/src/main/kotlin/tachiyomi/core/common/util/lang/BooleanExtensions.kt:
--------------------------------------------------------------------------------
1 | package tachiyomi.core.common.util.lang
2 |
3 | fun Boolean.toLong() = if (this) 1L else 0L
4 |
--------------------------------------------------------------------------------
/core/common/src/main/kotlin/tachiyomi/core/common/util/lang/SortUtil.kt:
--------------------------------------------------------------------------------
1 | package tachiyomi.core.common.util.lang
2 |
3 | import java.text.Collator
4 | import java.util.Locale
5 |
6 | private val collator by lazy {
7 | val locale = Locale.getDefault()
8 | Collator.getInstance(locale).apply {
9 | strength = Collator.PRIMARY
10 | }
11 | }
12 |
13 | fun String.compareToWithCollator(other: String): Int {
14 | return collator.compare(this, other)
15 | }
16 |
--------------------------------------------------------------------------------
/data/consumer-rules.pro:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/data/consumer-rules.pro
--------------------------------------------------------------------------------
/data/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/data/src/main/java/tachiyomi/data/category/CategoryMapper.kt:
--------------------------------------------------------------------------------
1 | package tachiyomi.data.category
2 |
3 | import tachiyomi.domain.category.model.Category
4 |
5 | object CategoryMapper {
6 | fun mapCategory(
7 | id: Long,
8 | name: String,
9 | order: Long,
10 | flags: Long,
11 | // KMK -->
12 | hidden: Long,
13 | // KMK <--
14 | ): Category {
15 | return Category(
16 | id = id,
17 | name = name,
18 | order = order,
19 | flags = flags,
20 | // KMK -->
21 | hidden = hidden == 1L,
22 | // KMK <--
23 | )
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/data/src/main/java/tachiyomi/data/libraryUpdateError/LibraryUpdateErrorMapper.kt:
--------------------------------------------------------------------------------
1 | package tachiyomi.data.libraryUpdateError
2 |
3 | import tachiyomi.domain.libraryUpdateError.model.LibraryUpdateError
4 |
5 | val libraryUpdateErrorMapper: (Long, Long, Long, Long) -> LibraryUpdateError = { id, mangaId, messageId, lastUpdate ->
6 | LibraryUpdateError(
7 | id = id,
8 | mangaId = mangaId,
9 | messageId = messageId,
10 | lastUpdate = lastUpdate,
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/data/src/main/java/tachiyomi/data/libraryUpdateErrorMessage/LibraryUpdateErrorMessageMapper.kt:
--------------------------------------------------------------------------------
1 | package tachiyomi.data.libraryUpdateErrorMessage
2 |
3 | import tachiyomi.domain.libraryUpdateErrorMessage.model.LibraryUpdateErrorMessage
4 |
5 | val LibraryUpdateErrorMessageMapper: (Long, String) -> LibraryUpdateErrorMessage = { id, message ->
6 | LibraryUpdateErrorMessage(
7 | id = id,
8 | message = message,
9 | )
10 | }
11 |
--------------------------------------------------------------------------------
/data/src/main/java/tachiyomi/data/source/FeedSavedSearchMapper.kt:
--------------------------------------------------------------------------------
1 | package tachiyomi.data.source
2 |
3 | import tachiyomi.domain.source.model.FeedSavedSearch
4 |
5 | object FeedSavedSearchMapper {
6 | fun map(
7 | id: Long,
8 | source: Long,
9 | savedSearch: Long?,
10 | global: Boolean,
11 | feedOrder: Long,
12 | ): FeedSavedSearch {
13 | return FeedSavedSearch(
14 | id = id,
15 | source = source,
16 | savedSearch = savedSearch,
17 | global = global,
18 | feedOrder = feedOrder,
19 | )
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/data/src/main/java/tachiyomi/data/source/SavedSearchMapper.kt:
--------------------------------------------------------------------------------
1 | package tachiyomi.data.source
2 |
3 | import tachiyomi.domain.source.model.SavedSearch
4 |
5 | object SavedSearchMapper {
6 | fun map(
7 | id: Long,
8 | source: Long,
9 | name: String,
10 | query: String?,
11 | filtersJson: String?,
12 | ): SavedSearch {
13 | return SavedSearch(
14 | id = id,
15 | source = source,
16 | name = name,
17 | query = query,
18 | filtersJson = filtersJson,
19 | )
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/data/src/main/sqldelight/28.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/data/src/main/sqldelight/28.db
--------------------------------------------------------------------------------
/data/src/main/sqldelight/tachiyomi/data/sources.sq:
--------------------------------------------------------------------------------
1 | CREATE TABLE sources(
2 | _id INTEGER NOT NULL PRIMARY KEY,
3 | lang TEXT NOT NULL,
4 | name TEXT NOT NULL
5 | );
6 |
7 | findAll:
8 | SELECT *
9 | FROM sources;
10 |
11 | findOne:
12 | SELECT *
13 | FROM sources
14 | WHERE _id = :id;
15 |
16 | upsert:
17 | INSERT INTO sources(_id, lang, name)
18 | VALUES (:id, :lang, :name)
19 | ON CONFLICT(_id)
20 | DO UPDATE
21 | SET
22 | lang = :lang,
23 | name = :name
24 | WHERE _id = :id;
--------------------------------------------------------------------------------
/data/src/main/sqldelight/tachiyomi/migrations/1.sqm:
--------------------------------------------------------------------------------
1 | ALTER TABLE mangas
2 | ADD COLUMN cover_last_modified INTEGER NOT NULL DEFAULT 0;
--------------------------------------------------------------------------------
/data/src/main/sqldelight/tachiyomi/migrations/10.sqm:
--------------------------------------------------------------------------------
1 | CREATE TABLE eh_favorites (
2 | _id INTEGER NOT NULL PRIMARY KEY,
3 | title TEXT NOT NULL,
4 | gid TEXT NOT NULL,
5 | token TEXT NOT NULL,
6 | category INTEGER NOT NULL
7 | );
--------------------------------------------------------------------------------
/data/src/main/sqldelight/tachiyomi/migrations/11.sqm:
--------------------------------------------------------------------------------
1 | CREATE TABLE IF NOT EXISTS eh_favorites (
2 | _id INTEGER NOT NULL PRIMARY KEY,
3 | title TEXT NOT NULL,
4 | gid TEXT NOT NULL,
5 | token TEXT NOT NULL,
6 | category INTEGER NOT NULL
7 | );
--------------------------------------------------------------------------------
/data/src/main/sqldelight/tachiyomi/migrations/12.sqm:
--------------------------------------------------------------------------------
1 | CREATE TABLE saved_search(
2 | _id INTEGER NOT NULL PRIMARY KEY,
3 | source INTEGER NOT NULL,
4 | name TEXT NOT NULL,
5 | query TEXT,
6 | filters_json TEXT
7 | );
8 | CREATE TABLE feed_saved_search (
9 | _id INTEGER NOT NULL PRIMARY KEY,
10 | source INTEGER NOT NULL,
11 | saved_search INTEGER,
12 | global INTEGER AS Boolean NOT NULL,
13 | FOREIGN KEY(saved_search) REFERENCES saved_search (_id)
14 | ON DELETE CASCADE
15 | );
16 | CREATE INDEX feed_saved_search_saved_search_index ON feed_saved_search(saved_search);
--------------------------------------------------------------------------------
/data/src/main/sqldelight/tachiyomi/migrations/15.sqm:
--------------------------------------------------------------------------------
1 | CREATE TABLE sources(
2 | _id INTEGER NOT NULL PRIMARY KEY,
3 | lang TEXT NOT NULL,
4 | name TEXT NOT NULL
5 | );
--------------------------------------------------------------------------------
/data/src/main/sqldelight/tachiyomi/migrations/16.sqm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/data/src/main/sqldelight/tachiyomi/migrations/16.sqm
--------------------------------------------------------------------------------
/data/src/main/sqldelight/tachiyomi/migrations/18.sqm:
--------------------------------------------------------------------------------
1 | UPDATE mangas
2 | SET chapter_flags = 0
3 | WHERE chapter_flags = -1;
4 | UPDATE mangas
5 | SET viewer = 0
6 | WHERE viewer = -1;
7 | UPDATE mangas
8 | SET date_added = 0
9 | WHERE date_added = -1;
10 | UPDATE mangas
11 | SET cover_last_modified = 0
12 | WHERE cover_last_modified = -1;
13 | UPDATE mangas
14 | SET last_update = 0
15 | WHERE last_update = -1;
16 | UPDATE categories
17 | SET manga_order = "";
--------------------------------------------------------------------------------
/data/src/main/sqldelight/tachiyomi/migrations/2.sqm:
--------------------------------------------------------------------------------
1 | ALTER TABLE mangas
2 | ADD COLUMN date_added INTEGER NOT NULL DEFAULT 0;
3 |
4 | UPDATE mangas
5 | SET date_added = (
6 | SELECT MIN(date_fetch)
7 | FROM mangas M
8 | INNER JOIN chapters C
9 | ON M._id = C.manga_id
10 | GROUP BY M._id
11 | );
--------------------------------------------------------------------------------
/data/src/main/sqldelight/tachiyomi/migrations/20.sqm:
--------------------------------------------------------------------------------
1 | -- Insert Default category
2 | INSERT OR IGNORE INTO categories(_id, name, sort, flags, manga_order) VALUES (0, "", -1, 0, "");
3 | -- Disallow deletion of default category
4 | CREATE TRIGGER IF NOT EXISTS system_category_delete_trigger BEFORE DELETE
5 | ON categories
6 | BEGIN SELECT CASE
7 | WHEN old._id <= 0 THEN
8 | RAISE(ABORT, "System category can't be deleted")
9 | END;
10 | END;
--------------------------------------------------------------------------------
/data/src/main/sqldelight/tachiyomi/migrations/21.sqm:
--------------------------------------------------------------------------------
1 | UPDATE mangas
2 | SET filtered_scanlators = NULL
3 | WHERE filtered_scanlators = "";
--------------------------------------------------------------------------------
/data/src/main/sqldelight/tachiyomi/migrations/22.sqm:
--------------------------------------------------------------------------------
1 | ALTER TABLE mangas ADD COLUMN update_strategy INTEGER NOT NULL DEFAULT 0;
--------------------------------------------------------------------------------
/data/src/main/sqldelight/tachiyomi/migrations/25.sqm:
--------------------------------------------------------------------------------
1 | ALTER TABLE mangas ADD COLUMN calculate_interval INTEGER DEFAULT 0 NOT NULL;
--------------------------------------------------------------------------------
/data/src/main/sqldelight/tachiyomi/migrations/30.sqm:
--------------------------------------------------------------------------------
1 | UPDATE manga_sync
2 | SET score = max(score, 0)
3 | WHERE sync_id = 7;
--------------------------------------------------------------------------------
/data/src/main/sqldelight/tachiyomi/migrations/32.sqm:
--------------------------------------------------------------------------------
1 | -- Create ExtensionRepo table --
2 | CREATE TABLE extension_repos (
3 | base_url TEXT NOT NULL PRIMARY KEY,
4 | name TEXT NOT NULL,
5 | short_name TEXT,
6 | website TEXT NOT NULL,
7 | signing_key_fingerprint TEXT UNIQUE NOT NULL
8 | );
9 |
--------------------------------------------------------------------------------
/data/src/main/sqldelight/tachiyomi/migrations/33.sqm:
--------------------------------------------------------------------------------
1 | -- Add feed_order column to feed_saved_search --
2 | ALTER TABLE feed_saved_search ADD COLUMN feed_order INTEGER NOT NULL DEFAULT 0;
3 |
4 | -- Using ID as initial feed_order to existed order
5 | UPDATE feed_saved_search SET feed_order = _id;
--------------------------------------------------------------------------------
/data/src/main/sqldelight/tachiyomi/migrations/34.sqm:
--------------------------------------------------------------------------------
1 | ALTER TABLE categories ADD COLUMN hidden INTEGER DEFAULT 0 NOT NULL;
--------------------------------------------------------------------------------
/data/src/main/sqldelight/tachiyomi/migrations/36.sqm:
--------------------------------------------------------------------------------
1 | import kotlin.Boolean;
2 |
3 | -- Add private field for tracking
4 | ALTER TABLE manga_sync ADD COLUMN private INTEGER AS Boolean DEFAULT 0 NOT NULL;
5 |
--------------------------------------------------------------------------------
/data/src/main/sqldelight/tachiyomi/migrations/38.sqm:
--------------------------------------------------------------------------------
1 | -- Add notes column
2 | ALTER TABLE mangas
3 | ADD notes TEXT NOT NULL DEFAULT "";
4 |
--------------------------------------------------------------------------------
/data/src/main/sqldelight/tachiyomi/migrations/4.sqm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/data/src/main/sqldelight/tachiyomi/migrations/4.sqm
--------------------------------------------------------------------------------
/data/src/main/sqldelight/tachiyomi/migrations/5.sqm:
--------------------------------------------------------------------------------
1 | ALTER TABLE mangas
2 | ADD COLUMN filtered_scanlators TEXT;
--------------------------------------------------------------------------------
/data/src/main/sqldelight/tachiyomi/migrations/6.sqm:
--------------------------------------------------------------------------------
1 | DROP TABLE IF EXISTS manga_related;
--------------------------------------------------------------------------------
/data/src/main/sqldelight/tachiyomi/migrations/7.sqm:
--------------------------------------------------------------------------------
1 | ALTER TABLE mangas
2 | ADD COLUMN next_update INTEGER DEFAULT 0;
--------------------------------------------------------------------------------
/data/src/main/sqldelight/tachiyomi/migrations/9.sqm:
--------------------------------------------------------------------------------
1 | UPDATE chapters
2 | SET date_upload = date_fetch
3 | WHERE date_upload = 0;
--------------------------------------------------------------------------------
/data/src/main/sqldelight/tachiyomi/view/libraryUpdateErrorView.sq:
--------------------------------------------------------------------------------
1 | CREATE VIEW libraryUpdateErrorView AS
2 | SELECT
3 | mangas._id AS mangaId,
4 | mangas.title AS mangaTitle,
5 | mangas.source,
6 | mangas.favorite,
7 | mangas.thumbnail_url AS thumbnailUrl,
8 | mangas.cover_last_modified AS coverLastModified,
9 | libraryUpdateError._id AS errorId,
10 | libraryUpdateError.message_id AS messageId,
11 | libraryUpdateError.last_update AS lastUpdate
12 | FROM mangas JOIN libraryUpdateError
13 | ON mangas._id = libraryUpdateError.manga_id
14 | WHERE favorite = 1
15 | ORDER BY lastUpdate DESC;
16 |
17 | errors:
18 | SELECT *
19 | FROM libraryUpdateErrorView;
20 |
--------------------------------------------------------------------------------
/domain/consumer-rules.pro:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/komikku-app/komikku/1ab5f26e8b3ecbed364ae762008b283c1374b248/domain/consumer-rules.pro
--------------------------------------------------------------------------------
/domain/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/domain/src/main/java/mihon/domain/extensionrepo/exception/SaveExtensionRepoException.kt:
--------------------------------------------------------------------------------
1 | package mihon.domain.extensionrepo.exception
2 |
3 | import java.io.IOException
4 |
5 | /**
6 | * Exception to abstract over SQLiteException and SQLiteConstraintException for multiplatform.
7 | *
8 | * @param throwable the source throwable to include for tracing.
9 | */
10 | class SaveExtensionRepoException(throwable: Throwable) : IOException("Error Saving Repository to Database", throwable)
11 |
--------------------------------------------------------------------------------
/domain/src/main/java/mihon/domain/extensionrepo/interactor/DeleteExtensionRepo.kt:
--------------------------------------------------------------------------------
1 | package mihon.domain.extensionrepo.interactor
2 |
3 | import mihon.domain.extensionrepo.repository.ExtensionRepoRepository
4 |
5 | class DeleteExtensionRepo(
6 | private val repository: ExtensionRepoRepository,
7 | ) {
8 | suspend fun await(baseUrl: String) {
9 | repository.deleteRepo(baseUrl)
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/domain/src/main/java/mihon/domain/extensionrepo/interactor/GetExtensionRepo.kt:
--------------------------------------------------------------------------------
1 | package mihon.domain.extensionrepo.interactor
2 |
3 | import kotlinx.coroutines.flow.Flow
4 | import mihon.domain.extensionrepo.model.ExtensionRepo
5 | import mihon.domain.extensionrepo.repository.ExtensionRepoRepository
6 |
7 | class GetExtensionRepo(
8 | private val repository: ExtensionRepoRepository,
9 | ) {
10 | fun subscribeAll(): Flow> = repository.subscribeAll()
11 |
12 | suspend fun getAll(): List = repository.getAll()
13 | }
14 |
--------------------------------------------------------------------------------
/domain/src/main/java/mihon/domain/extensionrepo/interactor/GetExtensionRepoCount.kt:
--------------------------------------------------------------------------------
1 | package mihon.domain.extensionrepo.interactor
2 |
3 | import mihon.domain.extensionrepo.repository.ExtensionRepoRepository
4 |
5 | class GetExtensionRepoCount(
6 | private val repository: ExtensionRepoRepository,
7 | ) {
8 | fun subscribe() = repository.getCount()
9 | }
10 |
--------------------------------------------------------------------------------
/domain/src/main/java/mihon/domain/extensionrepo/interactor/ReplaceExtensionRepo.kt:
--------------------------------------------------------------------------------
1 | package mihon.domain.extensionrepo.interactor
2 |
3 | import mihon.domain.extensionrepo.model.ExtensionRepo
4 | import mihon.domain.extensionrepo.repository.ExtensionRepoRepository
5 |
6 | class ReplaceExtensionRepo(
7 | private val repository: ExtensionRepoRepository,
8 | ) {
9 | suspend fun await(repo: ExtensionRepo) {
10 | repository.replaceRepo(repo)
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/domain/src/main/java/mihon/domain/extensionrepo/model/ExtensionRepo.kt:
--------------------------------------------------------------------------------
1 | package mihon.domain.extensionrepo.model
2 |
3 | data class ExtensionRepo(
4 | val baseUrl: String,
5 | val name: String,
6 | val shortName: String?,
7 | val website: String,
8 | val signingKeyFingerprint: String,
9 | )
10 |
--------------------------------------------------------------------------------
/domain/src/main/java/tachiyomi/domain/category/interactor/GetCategoriesPerLibraryManga.kt:
--------------------------------------------------------------------------------
1 | package tachiyomi.domain.category.interactor
2 |
3 | import kotlinx.coroutines.flow.Flow
4 | import tachiyomi.domain.category.repository.CategoryRepository
5 |
6 | class GetCategoriesPerLibraryManga(
7 | private val categoryRepository: CategoryRepository,
8 | ) {
9 |
10 | fun subscribe(): Flow