├── app ├── .gitignore ├── src │ └── main │ │ ├── java │ │ └── com │ │ │ └── dokja │ │ │ └── mizumi │ │ │ ├── utils │ │ │ ├── Utils.kt │ │ │ ├── Extensions.kt │ │ │ ├── Constants.kt │ │ │ ├── CursorExtensions.kt │ │ │ ├── DeviceUtilExtensions.kt │ │ │ ├── FileImporter.kt │ │ │ ├── ExceptionHandling.kt │ │ │ ├── Importer.kt │ │ │ ├── TranslationManager.kt │ │ │ └── ThemingDelegate.kt │ │ │ ├── presentation │ │ │ ├── core │ │ │ │ ├── models │ │ │ │ │ └── StatusModel.kt │ │ │ │ └── components │ │ │ │ │ └── LazyList.kt │ │ │ ├── utils │ │ │ │ ├── view │ │ │ │ │ └── ViewExtensions.kt │ │ │ │ ├── Constants.kt │ │ │ │ ├── DebouncedAction.kt │ │ │ │ ├── ToastExtensions.kt │ │ │ │ ├── Compose.kt │ │ │ │ ├── SavedStateHandleDelegates.kt │ │ │ │ └── ContextExtensions.kt │ │ │ ├── book │ │ │ │ ├── components │ │ │ │ │ ├── BookToolBar.kt │ │ │ │ │ ├── BookScreenBody.kt │ │ │ │ │ ├── ChapterSettingsDialog.kt │ │ │ │ │ ├── ChapterHeader.kt │ │ │ │ │ ├── TernaryStateToggle.kt │ │ │ │ │ └── TriStateItem.kt │ │ │ │ └── BookScreenState.kt │ │ │ ├── more │ │ │ │ ├── settings │ │ │ │ │ ├── Preference.kt │ │ │ │ │ ├── PreferenceItem.kt │ │ │ │ │ ├── data │ │ │ │ │ │ └── SettingsDataScreen.kt │ │ │ │ │ └── widget │ │ │ │ │ │ └── AppThemeModePreferenceWidget.kt │ │ │ │ ├── MoreScreen.kt │ │ │ │ └── onboarding │ │ │ │ │ ├── OnBoardingEvent.kt │ │ │ │ │ ├── Page.kt │ │ │ │ │ ├── ThemeStep.kt │ │ │ │ │ ├── OnBoardingViewModel.kt │ │ │ │ │ └── StorageStep.kt │ │ │ ├── library │ │ │ │ ├── LibraryState.kt │ │ │ │ ├── LibraryViewModel.kt │ │ │ │ ├── components │ │ │ │ │ ├── LibraryGrid.kt │ │ │ │ │ └── LibraryTabs.kt │ │ │ │ └── LibraryScreen.kt │ │ │ ├── reader │ │ │ │ ├── components │ │ │ │ │ ├── bottomBar │ │ │ │ │ │ ├── MoreSettings.kt │ │ │ │ │ │ └── BottomReaderBarExtensions.kt │ │ │ │ │ ├── InitialChapterPosition.kt │ │ │ │ │ ├── FontLoader.kt │ │ │ │ │ ├── TextToItems.kt │ │ │ │ │ └── ReaderItemBinarySearch.kt │ │ │ │ ├── ReaderDomain.kt │ │ │ │ ├── ReaderState.kt │ │ │ │ └── ReaderItem.kt │ │ │ ├── auth │ │ │ │ ├── RegisterScreen.kt │ │ │ │ └── ViewModel.kt │ │ │ ├── browse │ │ │ │ └── BrowseScreen.kt │ │ │ ├── BaseViewModel.kt │ │ │ ├── history │ │ │ │ ├── HistoryScreen.kt │ │ │ │ └── HistoryViewModel.kt │ │ │ ├── theme │ │ │ │ ├── Color.kt │ │ │ │ ├── colorscheme │ │ │ │ │ ├── BaseColorScheme.kt │ │ │ │ │ └── TealTurqoiseColorScheme.kt │ │ │ │ └── Type.kt │ │ │ ├── Dimens.kt │ │ │ ├── common │ │ │ │ ├── screens │ │ │ │ │ └── LoadingScreen.kt │ │ │ │ ├── LazyLinkSate.kt │ │ │ │ └── material │ │ │ │ │ ├── button.kt │ │ │ │ │ ├── NavigationBar.kt │ │ │ │ │ └── PageIndicator.kt │ │ │ ├── model │ │ │ │ └── ThemeMode.kt │ │ │ └── navgraph │ │ │ │ ├── graphs │ │ │ │ ├── BrowseNavGraph.kt │ │ │ │ ├── OnboardingNavGraph.kt │ │ │ │ ├── AuthNavGraph.kt │ │ │ │ ├── MainNavGraph.kt │ │ │ │ └── LibraryNavGraph.kt │ │ │ │ └── Route.kt │ │ │ ├── notification │ │ │ └── NarratorMediaControl.kt │ │ │ ├── di │ │ │ ├── AppCoroutineScope.kt │ │ │ └── GlideModule.kt │ │ │ ├── MizumiApplication.kt │ │ │ ├── domain │ │ │ ├── usecases │ │ │ │ ├── AppEntryUseCases.kt │ │ │ │ ├── SaveAppEntry.kt │ │ │ │ └── ReadAppEntry.kt │ │ │ ├── ui │ │ │ │ ├── model │ │ │ │ │ └── AppTheme.kt │ │ │ │ └── UiPreferences.kt │ │ │ └── manager │ │ │ │ └── LocalUserManager.kt │ │ │ ├── data │ │ │ ├── network │ │ │ │ ├── models │ │ │ │ │ ├── Genre.kt │ │ │ │ │ ├── BookCategory.kt │ │ │ │ │ ├── User.kt │ │ │ │ │ ├── Book.kt │ │ │ │ │ └── UserBook.kt │ │ │ │ ├── MizuList.kt │ │ │ │ ├── MizuListApi.kt │ │ │ │ └── ApiModels.kt │ │ │ ├── local │ │ │ │ ├── chapter │ │ │ │ │ ├── ChapterBody.kt │ │ │ │ │ ├── Chapter.kt │ │ │ │ │ └── ChapterBodyDao.kt │ │ │ │ ├── tracker │ │ │ │ │ ├── Track.kt │ │ │ │ │ └── TrackerDao.kt │ │ │ │ ├── library │ │ │ │ │ └── LibraryItem.kt │ │ │ │ └── MizumiDatabase.kt │ │ │ ├── CommonDataClasses.kt │ │ │ └── Response.kt │ │ │ ├── AppContext.kt │ │ │ ├── BaseActivity.kt │ │ │ ├── AppPreferences.kt │ │ │ ├── epub │ │ │ ├── Epub.kt │ │ │ ├── EpubExtensions.kt │ │ │ ├── BookTextMapper.kt │ │ │ └── EpubImporter.kt │ │ │ ├── repository │ │ │ ├── TrackerRepository.kt │ │ │ └── ChapterBodyRepository.kt │ │ │ ├── services │ │ │ └── narrator │ │ │ │ ├── NarratorMediaControlService.kt │ │ │ │ └── NarratorMediaControlCallback.kt │ │ │ ├── MainViewModel.kt │ │ │ └── MainActivity.kt │ │ ├── ic_launcher-playstore.png │ │ └── res │ │ ├── font │ │ ├── poppins_bold.ttf │ │ ├── poppins_regular.ttf │ │ └── poppins_semibold.ttf │ │ ├── drawable │ │ ├── disclaimer.png │ │ ├── ic_tracker_mal.webp │ │ ├── ic_tracker_anilist.webp │ │ ├── ic_tracker_bangumi.webp │ │ ├── ic_tracker_kavita.webp │ │ ├── ic_tracker_kitsu.webp │ │ ├── ic_tracker_komga.webp │ │ ├── ic_tracker_shikimori.webp │ │ ├── ic_tracker_suwayomi.webp │ │ ├── google_translate_attribution_greyscale.png │ │ ├── ic_tachi_splash.xml │ │ ├── line_divider.xml │ │ ├── ic_play_arrow_24dp.xml │ │ ├── ic_drag_handle_24dp.xml │ │ ├── ic_pause_24dp.xml │ │ ├── ic_done_24dp.xml │ │ ├── ic_warning_white_24dp.xml │ │ ├── ic_crop_24dp.xml │ │ ├── ic_close_24dp.xml │ │ ├── ic_folder_24dp.xml │ │ ├── translucent_current_reading_text_background.xml │ │ ├── ic_twotone_format_size_24.xml │ │ ├── ic_photo_24dp.xml │ │ ├── ic_info_24dp.xml │ │ ├── ic_book_24dp.xml │ │ ├── ic_done_prev_24dp.xml │ │ ├── ic_overflow_24dp.xml │ │ ├── ic_twotone_check_box_outline_blank_24.xml │ │ ├── translucent_current_reading_loading_text_background.xml │ │ ├── ic_system_update_alt_white_24dp.xml │ │ ├── ic_refresh_24dp.xml │ │ ├── ic_reader_webtoon_24dp.xml │ │ ├── ic_extension_24dp.xml │ │ ├── ic_reader_vertical_24dp.xml │ │ ├── ic_twotone_bookmark_24.xml │ │ ├── ic_download_chapter_24dp.xml │ │ ├── ic_twotone_indeterminate_check_box_24.xml │ │ ├── ic_reader_continuous_vertical_24dp.xml │ │ ├── eyeglasses_fill0_wght400_grad0_opsz24.xml │ │ ├── ic_twotone_check_box_24.xml │ │ ├── ic_crop_off_24dp.xml │ │ ├── ic_share_24dp.xml │ │ ├── ic_reader_rtl_24dp.xml │ │ ├── ic_reader_ltr_24dp.xml │ │ ├── cover_error.xml │ │ ├── ic_glasses_24dp.xml │ │ ├── ic_tachi.xml │ │ ├── ic_reader_default_24dp.xml │ │ └── anim_history_enter.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── values │ │ ├── ic_launcher_background.xml │ │ ├── splash.xml │ │ ├── themes.xml │ │ ├── colors.xml │ │ ├── attrs.xml │ │ ├── dimens.xml │ │ ├── styles.xml │ │ └── tachiyomi_colors.xml │ │ ├── layout │ │ ├── progress_bar.xml │ │ ├── activity_reader_list_item_padding.xml │ │ ├── progress_bar_horizontal.xml │ │ ├── activity_reader_list_item_divider.xml │ │ ├── activity_reader_list_item_progress_bar.xml │ │ ├── activity_reader_list_item_translating.xml │ │ ├── activity_reader_list_item_special_title.xml │ │ ├── activity_reader_list_item_title.xml │ │ ├── activity_reader_list_item_body.xml │ │ ├── activity_reader_list_item_google_translate_attribution.xml │ │ ├── activity_reader.xml │ │ ├── activity_reader_list_item_error.xml │ │ ├── activity_reader_list_item_image.xml │ │ └── view_checkbox.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── values-v31 │ │ └── splash.xml │ │ ├── values-night-v31 │ │ └── splash.xml │ │ ├── values-night │ │ └── colors.xml │ │ └── xml │ │ ├── backup_rules.xml │ │ └── data_extraction_rules.xml ├── proguard-rules.pro └── schemas │ └── com.dokja.mizumi.data.local.MizumiDatabase │ └── 2.json ├── .idea ├── .gitignore ├── vcs.xml ├── compiler.xml ├── kotlinc.xml ├── discord.xml ├── migrations.xml ├── misc.xml ├── gradle.xml ├── deploymentTargetDropDown.xml ├── appInsightsSettings.xml └── inspectionProfiles │ └── Project_Default.xml ├── .github └── readme-images │ ├── app-icon.png │ └── screens.png ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitignore ├── settings.gradle.kts ├── README.md └── gradle.properties /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /.github/readme-images/app-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrimqy/Mizumi/HEAD/.github/readme-images/app-icon.png -------------------------------------------------------------------------------- /.github/readme-images/screens.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrimqy/Mizumi/HEAD/.github/readme-images/screens.png -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/utils/Utils.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.utils 2 | 3 | object Utils { 4 | 5 | } -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrimqy/Mizumi/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /app/src/main/ic_launcher-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrimqy/Mizumi/HEAD/app/src/main/ic_launcher-playstore.png -------------------------------------------------------------------------------- /app/src/main/res/font/poppins_bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrimqy/Mizumi/HEAD/app/src/main/res/font/poppins_bold.ttf -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/presentation/core/models/StatusModel.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.presentation.core.models 2 | 3 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/disclaimer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrimqy/Mizumi/HEAD/app/src/main/res/drawable/disclaimer.png -------------------------------------------------------------------------------- /app/src/main/res/font/poppins_regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrimqy/Mizumi/HEAD/app/src/main/res/font/poppins_regular.ttf -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/presentation/utils/view/ViewExtensions.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.presentation.utils.view 2 | 3 | -------------------------------------------------------------------------------- /app/src/main/res/font/poppins_semibold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrimqy/Mizumi/HEAD/app/src/main/res/font/poppins_semibold.ttf -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/presentation/book/components/BookToolBar.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.presentation.book.components 2 | 3 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_tracker_mal.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrimqy/Mizumi/HEAD/app/src/main/res/drawable/ic_tracker_mal.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrimqy/Mizumi/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrimqy/Mizumi/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrimqy/Mizumi/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_tracker_anilist.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrimqy/Mizumi/HEAD/app/src/main/res/drawable/ic_tracker_anilist.webp -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_tracker_bangumi.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrimqy/Mizumi/HEAD/app/src/main/res/drawable/ic_tracker_bangumi.webp -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_tracker_kavita.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrimqy/Mizumi/HEAD/app/src/main/res/drawable/ic_tracker_kavita.webp -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_tracker_kitsu.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrimqy/Mizumi/HEAD/app/src/main/res/drawable/ic_tracker_kitsu.webp -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_tracker_komga.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrimqy/Mizumi/HEAD/app/src/main/res/drawable/ic_tracker_komga.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrimqy/Mizumi/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrimqy/Mizumi/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/notification/NarratorMediaControl.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.notification 2 | 3 | class NarratorMediaControl { 4 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_tracker_shikimori.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrimqy/Mizumi/HEAD/app/src/main/res/drawable/ic_tracker_shikimori.webp -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_tracker_suwayomi.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrimqy/Mizumi/HEAD/app/src/main/res/drawable/ic_tracker_suwayomi.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrimqy/Mizumi/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrimqy/Mizumi/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrimqy/Mizumi/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrimqy/Mizumi/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrimqy/Mizumi/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/presentation/more/settings/Preference.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.presentation.more.settings 2 | 3 | class Preference { 4 | } -------------------------------------------------------------------------------- /app/src/main/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #262424 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/google_translate_attribution_greyscale.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrimqy/Mizumi/HEAD/app/src/main/res/drawable/google_translate_attribution_greyscale.png -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/di/AppCoroutineScope.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.di 2 | 3 | import kotlinx.coroutines.CoroutineScope 4 | 5 | interface AppCoroutineScope : CoroutineScope -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/presentation/library/LibraryState.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.presentation.library 2 | 3 | class LibraryState { 4 | val isLoading: Boolean = false 5 | } -------------------------------------------------------------------------------- /app/src/main/res/values/splash.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/kotlinc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/presentation/more/MoreScreen.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.presentation.more 2 | 3 | import androidx.compose.runtime.Composable 4 | 5 | @Composable 6 | fun MoreScreen() { 7 | 8 | } -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/MizumiApplication.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi 2 | 3 | import android.app.Application 4 | import dagger.hilt.android.HiltAndroidApp 5 | 6 | @HiltAndroidApp 7 | class MizumiApplication: Application() -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/domain/usecases/AppEntryUseCases.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.domain.usecases 2 | 3 | data class AppEntryUseCases( 4 | val readAppEntry: ReadAppEntry, 5 | val saveAppEntry: SaveAppEntry 6 | ) 7 | -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/presentation/more/onboarding/OnBoardingEvent.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.presentation.more.onboarding 2 | 3 | sealed class OnBoardingEvent { 4 | data object SaveAppEntry: OnBoardingEvent() 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/utils/Extensions.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.utils 2 | 3 | import android.view.LayoutInflater 4 | import android.view.View 5 | 6 | val View.inflater: LayoutInflater get() = LayoutInflater.from(context) -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/utils/Constants.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.utils 2 | 3 | object Constants { 4 | const val USER_SETTINGS = "userSettings" 5 | const val APP_ENTRY = "appEntry" 6 | const val DATABASE_NAME = "mizumi.db" 7 | } -------------------------------------------------------------------------------- /.idea/discord.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/presentation/reader/components/bottomBar/MoreSettings.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.presentation.reader.components.bottomBar 2 | 3 | import androidx.compose.runtime.Composable 4 | 5 | @Composable 6 | fun MoreSettings() { 7 | 8 | } -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/data/network/models/Genre.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.data.network.models 2 | 3 | import com.squareup.moshi.JsonClass 4 | 5 | @JsonClass(generateAdapter = true) 6 | data class Genre( 7 | val id: Int, 8 | val label: String 9 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/data/network/models/BookCategory.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.data.network.models 2 | 3 | import com.squareup.moshi.JsonClass 4 | 5 | @JsonClass(generateAdapter = true) 6 | data class BookCategory( 7 | val id: Int, 8 | val name: String 9 | ) -------------------------------------------------------------------------------- /app/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_crop_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/values-night-v31/splash.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_close_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_folder_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #000000 4 | #FF4E4B66 5 | #000000 6 | #4E4B66 7 | #FFF 8 | #A0A3BD 9 | #C3C3C3 10 | -------------------------------------------------------------------------------- /app/src/main/res/values-night/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFFFFFFF 4 | #FFB0B3B8 5 | #E4E6EB 6 | #B0B3B8 7 | #3A3B3C 8 | #DDDDDD 9 | #414243 10 | -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/presentation/history/HistoryScreen.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.presentation.history 2 | 3 | import androidx.compose.runtime.Composable 4 | import androidx.hilt.navigation.compose.hiltViewModel 5 | import com.dokja.mizumi.presentation.common.screens.EmptyScreen 6 | 7 | @Composable 8 | fun HistoryScreen() { 9 | val viewModel: HistoryViewModel = hiltViewModel() 10 | 11 | EmptyScreen(message = "Your library is empty") 12 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable/translucent_current_reading_text_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/presentation/more/settings/PreferenceItem.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.presentation.more.settings 2 | 3 | import androidx.compose.runtime.compositionLocalOf 4 | import androidx.compose.runtime.structuralEqualityPolicy 5 | import androidx.compose.ui.unit.dp 6 | 7 | val LocalPreferenceHighlighted = compositionLocalOf(structuralEqualityPolicy()) { false } 8 | val LocalPreferenceMinHeight = compositionLocalOf(structuralEqualityPolicy()) { 56.dp } -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_twotone_format_size_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/AppContext.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi 2 | 3 | val String.isLocalUri: Boolean get() = startsWith("local://") 4 | val String.isHttpsUrl: Boolean get() = startsWith("http://", true) || startsWith("https://", true) 5 | val String.removeLocalUriPrefix: String get() = removePrefix("local://") 6 | val String.addLocalUriPrefix: String get() = "local://${this}" 7 | 8 | val String.isContentUri: Boolean get() = startsWith("content://") 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_photo_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16dp 5 | 16dp 6 | 7 | 60dp 8 | 6dp 9 | 3dp 10 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_reader_list_item_progress_bar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/presentation/theme/Color.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.presentation.theme 2 | 3 | import androidx.compose.ui.graphics.Color 4 | 5 | val Black = Color(0xFF1C1E21) //Dark Background 6 | val Blue = Color(0xFF1877F2) //Primary 7 | 8 | val DarkRed = Color(0xFFC30052) //Dark Error 9 | val LightRed = Color(0xFFFF84B7) 10 | 11 | val LightBlack = Color(0xFF3A3B3C) //Dark Surface 12 | 13 | 14 | val BlueGray = Color(0xFFA0A3BD) 15 | val WhiteGray = Color(0xFFB0B3B8) -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/data/local/chapter/Chapter.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.data.local.chapter 2 | 3 | import androidx.room.Entity 4 | import androidx.room.PrimaryKey 5 | 6 | @Entity 7 | data class Chapter( 8 | val title: String?, 9 | @PrimaryKey val url: String, 10 | val bookUrl: String, 11 | val position: Int, 12 | val read: Boolean = false, 13 | val lastReadPosition: Int = 0, 14 | val lastReadOffset: Int = 0, 15 | val bookmark: Boolean = false 16 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/BaseActivity.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi 2 | 3 | import androidx.appcompat.app.AppCompatActivity 4 | import dagger.hilt.android.AndroidEntryPoint 5 | 6 | @AndroidEntryPoint 7 | open class BaseActivity : 8 | AppCompatActivity() 9 | // ThemingDelegate by ThemingDelegateImpl() 10 | { 11 | // 12 | // override fun onCreate(savedInstanceState: Bundle?) { 13 | // applyAppTheme(this) 14 | // super.onCreate(savedInstanceState) 15 | // } 16 | 17 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_info_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_done_prev_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/utils/FileImporter.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.utils 2 | 3 | import kotlinx.coroutines.Dispatchers 4 | import kotlinx.coroutines.withContext 5 | import java.io.File 6 | 7 | 8 | suspend fun fileImporter( 9 | targetFile: File, 10 | imageData: ByteArray, 11 | ) = withContext(Dispatchers.IO) { 12 | targetFile.parentFile?.also { parent -> 13 | parent.mkdirs() 14 | if (parent.exists()) { 15 | targetFile.writeBytes(imageData) 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_overflow_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_twotone_check_box_outline_blank_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/translucent_current_reading_loading_text_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_system_update_alt_white_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_reader_list_item_translating.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_refresh_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/xml/backup_rules.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 13 | -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/data/local/tracker/Track.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.data.local.tracker 2 | 3 | import androidx.room.Entity 4 | import androidx.room.PrimaryKey 5 | 6 | @Entity 7 | data class Track( 8 | @PrimaryKey (autoGenerate = true) 9 | val id: Int = 0, 10 | val title: String?, 11 | val libraryId: Int, 12 | val bookId: String, 13 | val bookCategory: Int, 14 | val userId: String, 15 | val chaptersRead: String?, 16 | val rating: String?, 17 | val completedAt: String?, 18 | val startedDate: String? 19 | ) 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/presentation/Dimens.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.presentation 2 | 3 | import androidx.compose.ui.unit.dp 4 | 5 | object Dimens { 6 | 7 | val ExtraSmallPadding = 3.dp 8 | val ExtraSmallPadding2 = 6.dp 9 | val MediumPadding1 = 24.dp 10 | val MediumPadding2 = 30.dp 11 | val MediumPadding3 = 40.dp 12 | 13 | val IndicatorSize = 14.dp 14 | 15 | val SmallIconSize = 11.dp 16 | val IconSize = 20.dp 17 | 18 | val ArticleCardSize = 96.dp 19 | 20 | val ArticleImageHeight = 248.dp 21 | val PageIndicatorWidth = 52.dp 22 | } -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/presentation/history/HistoryViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.presentation.history 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.lifecycle.ViewModel 5 | import com.dokja.mizumi.data.local.library.LibraryDao 6 | import com.dokja.mizumi.data.local.library.LibraryItem 7 | import dagger.hilt.android.lifecycle.HiltViewModel 8 | import javax.inject.Inject 9 | 10 | @HiltViewModel 11 | class HistoryViewModel @Inject constructor( 12 | private val libraryDao: LibraryDao, 13 | ) : ViewModel() { 14 | val allItems: LiveData> = libraryDao.getAllItems() 15 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_reader_webtoon_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_reader_list_item_special_title.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_extension_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/data/network/models/User.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.data.network.models 2 | 3 | import com.google.gson.annotations.SerializedName 4 | 5 | data class User( 6 | @SerializedName("id") 7 | val id: String, 8 | @SerializedName("username") 9 | val username: String, 10 | @SerializedName("avatar") 11 | val avatar: String?, 12 | @SerializedName("bio") 13 | val bio: String?, 14 | @SerializedName("createdAt") 15 | val createdAt: String, 16 | @SerializedName("updatedAt") 17 | val updatedAt: String, 18 | @SerializedName("userAuthToken") 19 | val userAuthToken: String? 20 | ) 21 | -------------------------------------------------------------------------------- /app/src/main/res/xml/data_extraction_rules.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 12 | 13 | 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/data/local/library/LibraryItem.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.data.local.library 2 | 3 | import androidx.room.Entity 4 | import androidx.room.PrimaryKey 5 | 6 | @Entity(tableName = "book_library") 7 | data class LibraryItem( 8 | val title: String, 9 | @PrimaryKey(autoGenerate = true) 10 | var libraryid: Int = 0, 11 | val url: String, 12 | val inLibrary: Boolean = false, 13 | val author: String? = "", 14 | val coverImageUrl: String = "", 15 | val description: String? = "", 16 | val completed: Boolean = false, 17 | val lastReadChapter: String? = null, 18 | val lastReadEpochTimeMilli: Long = 0, 19 | ) 20 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_reader_vertical_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/presentation/common/screens/LoadingScreen.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.presentation.common.screens 2 | 3 | import androidx.compose.foundation.layout.Box 4 | import androidx.compose.foundation.layout.fillMaxSize 5 | import androidx.compose.material3.CircularProgressIndicator 6 | import androidx.compose.runtime.Composable 7 | import androidx.compose.ui.Alignment 8 | import androidx.compose.ui.Modifier 9 | 10 | @Composable 11 | fun LoadingScreen(modifier: Modifier = Modifier) { 12 | Box( 13 | modifier = modifier.fillMaxSize(), 14 | contentAlignment = Alignment.Center, 15 | ) { 16 | CircularProgressIndicator() 17 | } 18 | } -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/presentation/utils/Constants.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.presentation.utils 2 | 3 | import androidx.compose.foundation.layout.PaddingValues 4 | import androidx.compose.material3.MaterialTheme 5 | import androidx.compose.ui.unit.dp 6 | 7 | val topSmallPaddingValues = PaddingValues(top = MaterialTheme.padding.small) 8 | 9 | const val ReadItemAlpha = .38f 10 | const val SecondaryItemAlpha = .78f 11 | 12 | class Padding { 13 | 14 | val extraLarge = 32.dp 15 | 16 | val large = 24.dp 17 | 18 | val medium = 16.dp 19 | 20 | val small = 8.dp 21 | 22 | val extraSmall = 4.dp 23 | } 24 | 25 | val MaterialTheme.padding: Padding 26 | get() = Padding() 27 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_twotone_bookmark_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/presentation/model/ThemeMode.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.presentation.model 2 | 3 | import android.util.Log 4 | import androidx.appcompat.app.AppCompatDelegate 5 | 6 | enum class ThemeMode { 7 | LIGHT, 8 | DARK, 9 | SYSTEM, 10 | } 11 | 12 | fun setAppCompatDelegateThemeMode(themeMode: ThemeMode) { 13 | Log.d("themeMode", "$themeMode") 14 | AppCompatDelegate.setDefaultNightMode( 15 | when (themeMode) { 16 | ThemeMode.LIGHT -> AppCompatDelegate.MODE_NIGHT_NO 17 | ThemeMode.DARK -> AppCompatDelegate.MODE_NIGHT_YES 18 | ThemeMode.SYSTEM -> AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM 19 | }, 20 | ) 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_reader_list_item_title.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_reader_list_item_body.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/data/network/MizuList.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.data.network 2 | 3 | import com.squareup.moshi.Moshi 4 | import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory 5 | import retrofit2.Retrofit 6 | import retrofit2.converter.moshi.MoshiConverterFactory 7 | 8 | object MizuList { 9 | 10 | 11 | 12 | private val moshi = Moshi.Builder() 13 | .add(KotlinJsonAdapterFactory()) 14 | .build() 15 | 16 | val api: MizuListApi by lazy { 17 | Retrofit.Builder() 18 | .baseUrl(Constants.BASE_URL) 19 | .addConverterFactory(MoshiConverterFactory.create(moshi)) 20 | .build() 21 | .create(MizuListApi::class.java) 22 | } 23 | } -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/utils/ExceptionHandling.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.utils 2 | 3 | import com.dokja.mizumi.data.Response 4 | import kotlin.coroutines.cancellation.CancellationException 5 | 6 | suspend inline fun tryAsResponse(crossinline call: suspend () -> T): Response = try { 7 | Response.Success(call()) 8 | } catch (e: CancellationException) { 9 | throw e 10 | } catch (e: Exception) { 11 | Response.Error(e.message ?: "", e) 12 | } 13 | 14 | inline fun runCatchingAsResponse(crossinline call: () -> T): Response = try { 15 | Response.Success(call()) 16 | } catch (e: CancellationException) { 17 | throw e 18 | } catch (e: Exception) { 19 | Response.Error(e.message ?: "", e) 20 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_download_chapter_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_twotone_indeterminate_check_box_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 15 | 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ![app icon](./.github/readme-images/app-icon.png) Mizumi 2 | 3 | An Android Epub Reader inspired by Tachiyomi/Mihon to provide a fair reading experience. 4 | 5 | ![screenshots of app](./.github/readme-images/screens.png) 6 | 7 | ## Features 8 | - Local source to read local EPUBs 9 | - Text to speech 10 | - View all chapters right in the reader 11 | - Automatic light and dark themes 12 | 13 | ## Acknowledgements 14 | Thanks to [Nina](https://github.com/nanihadesuka) as the [NovelDokusha](https://github.com/nanihadesuka/NovelDokusha) helped me a lot to learn and most of the codebase is built on that. 15 | Special thanks to JetBrains for creating Kotlin and to the Jetpack Compose team for providing a modern toolkit for building native Android UI. 16 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_reader_continuous_vertical_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/AppPreferences.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi 2 | 3 | import android.content.Context 4 | import dagger.hilt.android.qualifiers.ApplicationContext 5 | import javax.inject.Inject 6 | 7 | 8 | data class VoicePredefineState( 9 | val savedName: String, 10 | val voiceId: String, 11 | val pitch: Float, 12 | val speed: Float 13 | ) 14 | 15 | class AppPreferences @Inject constructor( 16 | @ApplicationContext val context: Context 17 | ) { 18 | 19 | enum class TERNARY_STATE { 20 | active, 21 | inverse, 22 | inactive; 23 | 24 | fun next() = when (this) { 25 | active -> inverse 26 | inverse -> inactive 27 | inactive -> active 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/domain/ui/model/AppTheme.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.domain.ui.model 2 | 3 | import com.dokja.mizumi.R 4 | 5 | enum class AppTheme(val titleRes: Int) { 6 | DEFAULT(R.string.label_default), 7 | MONET(R.string.theme_monet), 8 | GREEN_APPLE(R.string.theme_greenapple), 9 | LAVENDER(R.string.theme_lavender), 10 | MIDNIGHT_DUSK(R.string.theme_midnightdusk), 11 | 12 | // TODO: re-enable for preview 13 | NORD(R.string.theme_nord), 14 | STRAWBERRY_DAIQUIRI(R.string.theme_strawberrydaiquiri), 15 | TAKO(R.string.theme_tako), 16 | TEALTURQUOISE(R.string.theme_tealturquoise), 17 | TIDAL_WAVE(R.string.theme_tidalwave), 18 | YINYANG(R.string.theme_yinyang), 19 | YOTSUBA(R.string.theme_yotsuba), 20 | 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/presentation/theme/colorscheme/BaseColorScheme.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.presentation.theme.colorscheme 2 | 3 | import androidx.compose.material3.ColorScheme 4 | import androidx.compose.ui.graphics.Color 5 | 6 | internal abstract class BaseColorScheme { 7 | 8 | abstract val darkScheme: ColorScheme 9 | abstract val lightScheme: ColorScheme 10 | 11 | fun getColorScheme(isDark: Boolean, isAmoled: Boolean): ColorScheme { 12 | if (!isDark) return lightScheme 13 | 14 | if (!isAmoled) return darkScheme 15 | 16 | return darkScheme.copy( 17 | background = Color.Black, 18 | onBackground = Color.White, 19 | surface = Color.Black, 20 | onSurface = Color.White, 21 | ) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/eyeglasses_fill0_wght400_grad0_opsz24.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_reader_list_item_google_translate_attribution.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_twotone_check_box_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 15 | 16 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/presentation/utils/DebouncedAction.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.presentation.utils 2 | 3 | import androidx.compose.runtime.Composable 4 | import androidx.compose.runtime.LaunchedEffect 5 | import androidx.compose.runtime.getValue 6 | import androidx.compose.runtime.mutableStateOf 7 | import androidx.compose.runtime.saveable.rememberSaveable 8 | import androidx.compose.runtime.setValue 9 | import kotlinx.coroutines.delay 10 | 11 | @Composable 12 | fun debouncedAction(waitMillis: Long = 250, action: () -> Unit): () -> Unit { 13 | var ready by rememberSaveable { mutableStateOf(true) } 14 | LaunchedEffect(ready, waitMillis, action) { 15 | delay(waitMillis) 16 | ready = true 17 | } 18 | 19 | return { 20 | if (ready) { 21 | action() 22 | } 23 | ready = false 24 | } 25 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_crop_off_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/epub/Epub.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.epub 2 | 3 | data class EpubBook( 4 | val fileName: String, 5 | val title: String, 6 | val author: String?, 7 | val description: String?, 8 | val coverImage: Image?, 9 | val chapters: List, 10 | val images: List, 11 | val toc: List = emptyList() 12 | ) { 13 | data class Chapter( 14 | val absPath: String, 15 | val title: String?, 16 | val body: String 17 | ) 18 | 19 | data class Image( 20 | val absPath: String, 21 | val image: ByteArray 22 | ) 23 | 24 | data class ToCEntry( 25 | val chapterTitle: String, 26 | val chapterLink: String 27 | ) 28 | } 29 | data class ManifestItem( 30 | val id: String, 31 | val absPath: String, 32 | val mediaType: String, 33 | val properties: String 34 | ) 35 | 36 | 37 | -------------------------------------------------------------------------------- /.idea/deploymentTargetDropDown.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/presentation/book/components/BookScreenBody.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.presentation.book.components 2 | 3 | import androidx.compose.foundation.layout.PaddingValues 4 | import androidx.compose.foundation.lazy.LazyColumn 5 | import androidx.compose.foundation.lazy.LazyListState 6 | import androidx.compose.runtime.Composable 7 | import androidx.compose.ui.unit.dp 8 | import com.dokja.mizumi.data.ChapterWithContext 9 | import com.dokja.mizumi.presentation.book.BookScreenState 10 | 11 | @Composable 12 | fun BookScreenBody( 13 | state: BookScreenState, 14 | lazyListState: LazyListState, 15 | innerPadding: PaddingValues, 16 | onChapterClick: (chapter: ChapterWithContext) -> Unit, 17 | onChapterLongClick: (chapter: ChapterWithContext) -> Unit, 18 | ) { 19 | LazyColumn( 20 | state = lazyListState, 21 | contentPadding = PaddingValues(bottom = 100.dp) 22 | ) { 23 | 24 | } 25 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_share_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/utils/Importer.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.utils 2 | 3 | import android.util.Log 4 | import androidx.activity.compose.rememberLauncherForActivityResult 5 | import androidx.activity.result.contract.ActivityResultContracts 6 | import androidx.compose.runtime.Composable 7 | import androidx.compose.ui.platform.LocalContext 8 | import com.dokja.mizumi.services.EpubImportService 9 | 10 | @Composable 11 | fun onDoImportEPUB(): () -> Unit { 12 | val context = LocalContext.current 13 | val fileExplorer = rememberLauncherForActivityResult( 14 | contract = ActivityResultContracts.GetContent(), 15 | onResult = { uri -> 16 | if (uri != null) { 17 | EpubImportService.start(ctx = context, uri = uri) 18 | } else { 19 | Log.w("FileExplorer", "No URI selected") 20 | } 21 | } 22 | ) 23 | return { fileExplorer.launch("application/epub+zip") } 24 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_reader_rtl_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | 18 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/repository/TrackerRepository.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.repository 2 | 3 | import com.dokja.mizumi.data.local.tracker.Track 4 | import com.dokja.mizumi.data.local.tracker.TrackerDao 5 | 6 | class TrackerRepository( 7 | private val trackerDao: TrackerDao, 8 | ) { 9 | suspend fun insertTrack(track: Track) = trackerDao.insertTrack(track) 10 | 11 | suspend fun getTrack(libraryId: Int) = trackerDao.getTrackById(libraryId) 12 | 13 | fun getTrackByIdWithFlow(libraryId: Int) = trackerDao.getTrackByIdWithFlow(libraryId) 14 | 15 | suspend fun updateStatus(libraryId: Int, bookCategory: Int, chaptersRead: String?, rating: String?, startedDate: String?, completedAt: String?) = trackerDao.updateStatus(libraryId, bookCategory, chaptersRead, rating, completedAt, startedDate) 16 | 17 | suspend fun updateChapterRead(libraryId: Int, bookCategory: Int, chaptersRead: String?) = trackerDao.updateChapterRead(libraryId, bookCategory, chaptersRead) 18 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_reader_ltr_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | 18 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | #fff 9 | #71A30E 10 | #C81414 11 | 12 | 18 | 19 | 20 | 21 | 22 | 26 | -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/data/local/chapter/ChapterBodyDao.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.data.local.chapter 2 | 3 | import androidx.room.Dao 4 | import androidx.room.Insert 5 | import androidx.room.OnConflictStrategy 6 | import androidx.room.Query 7 | 8 | @Dao 9 | interface ChapterBodyDao { 10 | @Query("SELECT * FROM ChapterBody") 11 | suspend fun getAll(): List 12 | 13 | @Insert(onConflict = OnConflictStrategy.REPLACE) 14 | suspend fun insertReplace(chapterBody: ChapterBody) 15 | 16 | @Insert(onConflict = OnConflictStrategy.REPLACE) 17 | suspend fun insertReplace(chapterBody: List) 18 | 19 | @Query("SELECT * FROM ChapterBody WHERE url = :url") 20 | suspend fun get(url: String): ChapterBody? 21 | 22 | @Query("DELETE FROM ChapterBody WHERE ChapterBody.url NOT IN (SELECT Chapter.url FROM Chapter)") 23 | suspend fun removeAllNonChapterRows() 24 | 25 | @Query("DELETE FROM ChapterBody WHERE ChapterBody.url IN (:chaptersUrl)") 26 | suspend fun removeChapterRows(chaptersUrl: List) 27 | } -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/presentation/more/onboarding/Page.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.presentation.more.onboarding 2 | 3 | import androidx.annotation.DrawableRes 4 | import androidx.compose.runtime.Composable 5 | import com.dokja.mizumi.R 6 | 7 | 8 | data class Page( 9 | val title: String?, 10 | val description: String?, 11 | @DrawableRes val image: Int?, 12 | val content: @Composable () -> Unit = {} 13 | ) 14 | 15 | val pages = listOf( 16 | Page( 17 | title = "Welcome!", 18 | description = "Let's set some things up first.", 19 | image = R.drawable.ic_logo, 20 | ), 21 | // Page( 22 | // title = "Disclaimer", 23 | // description = "Our Reader does not endorse or support access to copyrighted content. Please use authorized platforms to obtain content for viewing and respect copyright laws.", 24 | // image = R.drawable.disclaimer 25 | // ), 26 | Page( 27 | title = null, 28 | description = null, 29 | image = null, 30 | content = { ThemeStep() } 31 | ), 32 | 33 | ) 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/presentation/navgraph/graphs/BrowseNavGraph.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.presentation.navgraph.graphs 2 | 3 | import androidx.navigation.NavGraphBuilder 4 | import androidx.navigation.NavHostController 5 | import androidx.navigation.compose.composable 6 | import androidx.navigation.compose.navigation 7 | import com.dokja.mizumi.presentation.browse.BrowseScreen 8 | import com.dokja.mizumi.presentation.navgraph.BrowseRouteScreen 9 | import com.dokja.mizumi.presentation.navgraph.Graph 10 | 11 | fun NavGraphBuilder.browseNavGraph(rootNavController: NavHostController) { 12 | navigation( 13 | route = Graph.BrowseScreenGraph, 14 | startDestination = BrowseRouteScreen.BrowseDetail.route, 15 | enterTransition = { enterTransition() }, 16 | exitTransition = { exitTransition() }, 17 | popEnterTransition = { popEnterTransition() }, 18 | popExitTransition = { popExitTransition() } 19 | ) { 20 | composable(route = BrowseRouteScreen.BrowseDetail.route, ) { 21 | BrowseScreen() 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/domain/manager/LocalUserManager.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.domain.manager 2 | 3 | import com.dokja.mizumi.data.manager.ReaderPreferences 4 | import com.dokja.mizumi.data.manager.SortOrder 5 | import com.dokja.mizumi.data.manager.ThemePreferences 6 | import com.dokja.mizumi.data.manager.UserPreferences 7 | import com.dokja.mizumi.presentation.model.ThemeMode 8 | import kotlinx.coroutines.flow.Flow 9 | 10 | interface LocalUserManager { 11 | suspend fun saveAppEntry() 12 | fun readAppEntry(): Flow 13 | 14 | fun userBookPreferences(): Flow 15 | fun userReaderPreferences(): Flow 16 | 17 | fun readAppTheme(): Flow 18 | suspend fun updateAppTheme(themePreferences: ThemePreferences) 19 | suspend fun updateThemeMode(themeMode: ThemeMode) 20 | suspend fun updateSort(sortOrder: SortOrder) 21 | suspend fun updateUnread(showUnread: Boolean) 22 | 23 | // User Token related methods 24 | suspend fun saveUserToken(token: String) 25 | fun readUserToken(): Flow 26 | } -------------------------------------------------------------------------------- /.idea/appInsightsSettings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 26 | 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/dokja/mizumi/data/network/models/Book.kt: -------------------------------------------------------------------------------- 1 | package com.dokja.mizumi.data.network.models 2 | 3 | import com.squareup.moshi.Json 4 | import com.squareup.moshi.JsonClass 5 | 6 | @JsonClass(generateAdapter = true) 7 | data class BookResponse( 8 | @Json(name = "books") 9 | val books: List 10 | ) 11 | 12 | @JsonClass(generateAdapter = true) 13 | data class Book( 14 | @Json(name = "Description") 15 | val description: String?, 16 | @Json(name = "authors") 17 | val authors: String?, 18 | @Json(name = "chapters") 19 | val chapters: String?, 20 | @Json(name = "coverUrl") 21 | val coverUrl: String?, 22 | @Json(name = "englishTitle") 23 | val englishTitle: String?, 24 | @Json(name = "firstPublished") 25 | val firstPublished: String?, 26 | @Json(name = "genres") 27 | val genres: List, 28 | @Json(name = "id") 29 | val id: String, 30 | @Json(name = "publicRating") 31 | val publicRating: Int, 32 | @Json(name = "ratingCount") 33 | val ratingCount: Int?, 34 | @Json(name = "romanizedTitle") 35 | val romanizedTitle: String? 36 | ) -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_reader.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 12 | 27 | 28 | 32 | 33 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_reader_list_item_error.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 12 |