Rename project from Tokusho to Etsudoku

tokusho means profit :trollface:
master
Zakhar Timoshenko 2 years ago
parent f0f25a4d48
commit 02cc6c8bf2
Signed by: Xtimms
SSH Key Fingerprint: SHA256:wH6spYepK/A5erBh7ZyAnr1ru9H4eaMVBEuiw6DSpxI

@ -18,7 +18,7 @@
</deviceKey>
</Target>
</targetSelectedWithDropDown>
<timeTargetWasSelectedWithDropDown value="2024-03-27T16:43:21.742325100Z" />
<timeTargetWasSelectedWithDropDown value="2024-03-30T18:28:38.815975400Z" />
</State>
</entry>
</value>

@ -1,4 +1,4 @@
# Tokusho
# Etsudoku
An attempt to write an Android manga reading application on Jetpack Compose using the [Kotatsu parser library](https://github.com/KotatsuApp/kotatsu-parsers).

@ -19,11 +19,11 @@ val acraAuthLogin: String = gradleLocalProperties(rootDir).getProperty("authLogi
val acraAuthPassword: String = gradleLocalProperties(rootDir).getProperty("authPassword") ?: "\"acra_password\""
android {
namespace = "org.xtimms.tokusho"
namespace = "org.xtimms.etsudoku"
compileSdk = 34
defaultConfig {
applicationId = "org.xtimms.tokusho"
applicationId = "org.xtimms.etsudoku"
minSdk = 26
targetSdk = 34
versionCode = 1
@ -37,7 +37,7 @@ android {
buildConfigField("String", "ACRA_AUTH_LOGIN", acraAuthLogin)
buildConfigField("String", "ACRA_AUTH_PASSWORD", acraAuthPassword)
testInstrumentationRunner = "org.xtimms.tokusho.HiltTestRunner"
testInstrumentationRunner = "org.xtimms.etsudoku.HiltTestRunner"
vectorDrawables {
useSupportLibrary = true
}
@ -73,6 +73,7 @@ android {
}
buildFeatures {
compose = true
viewBinding = true
buildConfig = true
}
composeOptions {
@ -100,7 +101,7 @@ dependencies {
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.ui:ui-graphics")
implementation("androidx.compose.ui:ui-tooling-preview")
implementation("androidx.compose.material:material-icons-extended:1.6.3")
implementation("androidx.compose.material:material-icons-extended:1.6.5")
implementation("androidx.compose.material3:material3-android:1.2.1")
implementation("androidx.compose.material3:material3-window-size-class:1.2.1")
implementation("androidx.hilt:hilt-navigation-compose:1.2.0")

@ -1,4 +1,4 @@
package org.xtimms.tokusho
package org.xtimms.etsudoku
import android.app.Application
import android.content.Context

@ -1,4 +1,4 @@
package org.xtimms.tokusho
package org.xtimms.etsudoku
import android.app.Instrumentation
import kotlin.coroutines.resume

@ -1,4 +1,4 @@
package org.xtimms.tokusho
package org.xtimms.etsudoku
import androidx.test.platform.app.InstrumentationRegistry
import com.squareup.moshi.FromJson
@ -11,7 +11,7 @@ import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
import okio.buffer
import okio.source
import org.koitharu.kotatsu.parsers.model.Manga
import org.xtimms.tokusho.core.model.FavouriteCategory
import org.xtimms.etsudoku.core.model.FavouriteCategory
import java.util.Date
import kotlin.reflect.KClass

@ -1,4 +1,4 @@
package org.xtimms.tokusho.sections.settings.backup
package org.xtimms.etsudoku.sections.settings.backup
import android.content.res.AssetManager
import androidx.test.ext.junit.runners.AndroidJUnit4
@ -12,12 +12,12 @@ import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.xtimms.tokusho.SampleData
import org.xtimms.tokusho.core.database.TokushoDatabase
import org.xtimms.tokusho.core.database.entity.toMangaTags
import org.xtimms.tokusho.data.repository.FavouritesRepository
import org.xtimms.tokusho.data.repository.HistoryRepository
import org.xtimms.tokusho.data.repository.backup.BackupRepository
import org.xtimms.etsudoku.SampleData
import org.xtimms.etsudoku.core.database.EtsudokuDatabase
import org.xtimms.etsudoku.core.database.entity.toMangaTags
import org.xtimms.etsudoku.data.repository.FavouritesRepository
import org.xtimms.etsudoku.data.repository.HistoryRepository
import org.xtimms.etsudoku.data.repository.backup.BackupRepository
import java.io.File
import javax.inject.Inject
@ -38,7 +38,7 @@ class AppBackupAgentTest {
lateinit var backupRepository: BackupRepository
@Inject
lateinit var database: TokushoDatabase
lateinit var database: EtsudokuDatabase
@Before
fun setUp() {

@ -35,7 +35,7 @@
android:label="@string/app_name"
android:largeHeap="true"
android:supportsRtl="true"
android:theme="@style/Theme.Tokusho.Starting"
android:theme="@style/Theme.Etsudoku.Starting"
android:networkSecurityConfig="@xml/network_security_config"
tools:targetApi="tiramisu">
@ -43,7 +43,7 @@
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="@style/Theme.Tokusho">
android:theme="@style/Theme.Etsudoku">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

@ -1,4 +1,4 @@
package org.xtimms.tokusho
package org.xtimms.etsudoku
import android.app.Application
import android.content.Context
@ -20,12 +20,12 @@ import org.acra.data.StringFormat
import org.acra.ktx.initAcra
import org.acra.sender.HttpSender
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.xtimms.tokusho.core.database.TokushoDatabase
import org.xtimms.tokusho.core.prefs.AppSettings
import org.xtimms.tokusho.core.prefs.KotatsuAppSettings
import org.xtimms.tokusho.core.updates.Updater
import org.xtimms.tokusho.utils.lang.processLifecycleScope
import org.xtimms.tokusho.work.WorkScheduleManager
import org.xtimms.etsudoku.core.database.EtsudokuDatabase
import org.xtimms.etsudoku.core.prefs.AppSettings
import org.xtimms.etsudoku.core.prefs.KotatsuAppSettings
import org.xtimms.etsudoku.core.updates.Updater
import org.xtimms.etsudoku.utils.lang.processLifecycleScope
import org.xtimms.etsudoku.work.WorkScheduleManager
import javax.inject.Inject
import javax.inject.Provider
@ -33,7 +33,7 @@ import javax.inject.Provider
class App : Application(), Configuration.Provider {
@Inject
lateinit var database: Provider<TokushoDatabase>
lateinit var database: Provider<EtsudokuDatabase>
@Inject
lateinit var settings: KotatsuAppSettings

@ -1,4 +1,4 @@
package org.xtimms.tokusho
package org.xtimms.etsudoku
import android.os.Build
import androidx.compose.foundation.layout.PaddingValues
@ -11,13 +11,13 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import org.xtimms.tokusho.ui.theme.SEED
import org.xtimms.tokusho.core.prefs.AppSettings
import org.xtimms.tokusho.core.prefs.DarkThemePreference
import org.xtimms.tokusho.core.prefs.paletteStyles
import org.xtimms.tokusho.ui.monet.LocalTonalPalettes
import org.xtimms.tokusho.ui.monet.PaletteStyle
import org.xtimms.tokusho.ui.monet.TonalPalettes.Companion.toTonalPalettes
import org.xtimms.etsudoku.ui.theme.SEED
import org.xtimms.etsudoku.core.prefs.AppSettings
import org.xtimms.etsudoku.core.prefs.DarkThemePreference
import org.xtimms.etsudoku.core.prefs.paletteStyles
import org.xtimms.etsudoku.ui.monet.LocalTonalPalettes
import org.xtimms.etsudoku.ui.monet.PaletteStyle
import org.xtimms.etsudoku.ui.monet.TonalPalettes.Companion.toTonalPalettes
data class BottomSheetScrollState(
val topPadding: Dp,

@ -1,4 +1,4 @@
package org.xtimms.tokusho
package org.xtimms.etsudoku
import android.app.Application
import android.content.Context
@ -20,28 +20,28 @@ import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import okhttp3.OkHttpClient
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.xtimms.tokusho.core.cache.CacheDir
import org.xtimms.tokusho.core.cache.ContentCache
import org.xtimms.tokusho.core.cache.MemoryContentCache
import org.xtimms.tokusho.core.cache.StubContentCache
import org.xtimms.tokusho.core.database.TokushoDatabase
import org.xtimms.tokusho.core.model.LocalManga
import org.xtimms.tokusho.core.network.MangaHttpClient
import org.xtimms.tokusho.core.network.interceptors.ImageProxyInterceptor
import org.xtimms.tokusho.core.os.NetworkState
import org.xtimms.tokusho.core.parser.MangaLoaderContextImpl
import org.xtimms.tokusho.core.parser.MangaRepository
import org.xtimms.tokusho.core.parser.favicon.FaviconFetcher
import org.xtimms.tokusho.core.parser.local.LocalStorageChanges
import org.xtimms.tokusho.sections.reader.thumbnails.MangaPageFetcher
import org.xtimms.tokusho.utils.CoilImageGetter
import org.xtimms.tokusho.utils.system.connectivityManager
import org.xtimms.tokusho.utils.system.isLowRamDevice
import org.xtimms.etsudoku.core.cache.CacheDir
import org.xtimms.etsudoku.core.cache.ContentCache
import org.xtimms.etsudoku.core.cache.MemoryContentCache
import org.xtimms.etsudoku.core.cache.StubContentCache
import org.xtimms.etsudoku.core.database.EtsudokuDatabase
import org.xtimms.etsudoku.core.model.LocalManga
import org.xtimms.etsudoku.core.network.MangaHttpClient
import org.xtimms.etsudoku.core.network.interceptors.ImageProxyInterceptor
import org.xtimms.etsudoku.core.os.NetworkState
import org.xtimms.etsudoku.core.parser.MangaLoaderContextImpl
import org.xtimms.etsudoku.core.parser.MangaRepository
import org.xtimms.etsudoku.core.parser.favicon.FaviconFetcher
import org.xtimms.etsudoku.core.parser.local.LocalStorageChanges
import org.xtimms.etsudoku.sections.reader.thumbnails.MangaPageFetcher
import org.xtimms.etsudoku.utils.CoilImageGetter
import org.xtimms.etsudoku.utils.system.connectivityManager
import org.xtimms.etsudoku.utils.system.isLowRamDevice
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
interface TokushoModule {
interface EtsudokuModule {
@Binds
fun bindMangaLoaderContext(mangaLoaderContextImpl: MangaLoaderContextImpl): MangaLoaderContext
@ -61,8 +61,8 @@ interface TokushoModule {
@Singleton
fun provideMangaDatabase(
@ApplicationContext context: Context,
): TokushoDatabase {
return TokushoDatabase(context)
): EtsudokuDatabase {
return EtsudokuDatabase(context)
}
@Provides

@ -1,4 +1,4 @@
package org.xtimms.tokusho
package org.xtimms.etsudoku
import android.Manifest
import android.content.Intent
@ -11,6 +11,7 @@ import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.foundation.layout.PaddingValues
@ -24,9 +25,12 @@ import androidx.compose.foundation.layout.only
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.lazy.grid.LazyGridState
import androidx.compose.foundation.lazy.grid.rememberLazyGridState
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.surfaceColorAtElevation
import androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi
import androidx.compose.material3.windowsizeclass.WindowWidthSizeClass
import androidx.compose.material3.windowsizeclass.calculateWindowSizeClass
@ -35,15 +39,14 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.unit.dp
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
@ -55,18 +58,18 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import org.xtimms.tokusho.core.Navigation
import org.xtimms.tokusho.core.components.BottomNavBar
import org.xtimms.tokusho.core.components.ContinueReadingButton
import org.xtimms.tokusho.core.components.NavigationRail
import org.xtimms.tokusho.core.components.TopAppBar
import org.xtimms.tokusho.core.logs.FileLogger
import org.xtimms.tokusho.core.prefs.AppSettings
import org.xtimms.tokusho.core.screens.UpdateDialogImpl
import org.xtimms.tokusho.core.updates.Updater
import org.xtimms.tokusho.ui.theme.TokushoTheme
import org.xtimms.tokusho.utils.system.setLanguage
import org.xtimms.tokusho.utils.system.suspendToast
import org.xtimms.etsudoku.core.Navigation
import org.xtimms.etsudoku.core.components.BottomNavBar
import org.xtimms.etsudoku.core.components.ContinueReadingButton
import org.xtimms.etsudoku.core.components.NavigationRail
import org.xtimms.etsudoku.core.components.TopAppBar
import org.xtimms.etsudoku.core.logs.FileLogger
import org.xtimms.etsudoku.core.prefs.AppSettings
import org.xtimms.etsudoku.core.screens.UpdateDialogImpl
import org.xtimms.etsudoku.core.updates.Updater
import org.xtimms.etsudoku.ui.theme.EtsudokuTheme
import org.xtimms.etsudoku.utils.system.setLanguage
import org.xtimms.etsudoku.utils.system.suspendToast
import javax.inject.Inject
@OptIn(ExperimentalMaterial3WindowSizeClassApi::class)
@ -139,7 +142,7 @@ class MainActivity : ComponentActivity() {
}
if (isReady.value) {
SettingsProvider {
TokushoTheme(
EtsudokuTheme(
darkTheme = LocalDarkTheme.current.isDarkTheme(),
isDynamicColorEnabled = LocalDynamicColorSwitch.current,
isHighContrastModeEnabled = LocalDarkTheme.current.isHighContrastModeEnabled,
@ -218,6 +221,7 @@ class MainActivity : ComponentActivity() {
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MainView(
coil: ImageLoader,
@ -225,13 +229,10 @@ fun MainView(
isCompactScreen: Boolean,
navController: NavHostController,
) {
val density = LocalDensity.current
val bottomBarState = remember { mutableStateOf(true) }
var topBarHeightPx by remember { mutableFloatStateOf(0f) }
val topBarOffsetY = remember { Animatable(0f) }
val scroll: LazyGridState = rememberLazyGridState()
val scroll = rememberLazyListState()
Scaffold(
topBar = {
@ -243,12 +244,17 @@ fun MainView(
if (isScrolled) 1f else 0f,
label = "Top Bar Background",
)
val animatedSearchBarColor by animateColorAsState(
if (isScrolled) MaterialTheme.colorScheme.surface else MaterialTheme.colorScheme.surfaceColorAtElevation(6.dp),
label = "Top Bar Background",
)
TopAppBar(
navController = navController,
modifier = Modifier
.statusBarsPadding()
.padding(0.dp, 16.dp),
backgroundAlphaProvider = { animatedBgAlpha },
searchBarColorProvider = { animatedSearchBarColor }
)
}
},
@ -280,21 +286,17 @@ fun MainView(
loggers = loggers,
navController = navController,
isCompactScreen = false,
modifier = Modifier,
modifier = Modifier.nestedScroll(TopAppBarDefaults.pinnedScrollBehavior().nestedScrollConnection),
padding = PaddingValues(
start = padding.calculateStartPadding(LocalLayoutDirection.current),
top = systemBarsPadding.calculateTopPadding(),
end = padding.calculateEndPadding(LocalLayoutDirection.current),
bottom = systemBarsPadding.calculateBottomPadding()
),
topBarHeightPx = topBarHeightPx,
listState = scroll
)
}
} else {
LaunchedEffect(padding) {
topBarHeightPx = density.run { padding.calculateTopPadding().toPx() }
}
Navigation(
coil = coil,
loggers = loggers,
@ -305,7 +307,6 @@ fun MainView(
end = padding.calculateEndPadding(LocalLayoutDirection.current),
),
padding = padding,
topBarHeightPx = topBarHeightPx,
listState = scroll
)
}

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core
package org.xtimms.etsudoku.core
import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable
@ -14,8 +14,8 @@ import androidx.compose.ui.res.painterResource
import coil.ImageLoader
import coil.compose.AsyncImage
import coil.compose.AsyncImagePainter
import org.xtimms.tokusho.R
import org.xtimms.tokusho.utils.composable.rememberResourceBitmapPainter
import org.xtimms.etsudoku.R
import org.xtimms.etsudoku.utils.composable.rememberResourceBitmapPainter
@Composable
fun AsyncImageImpl(

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core
package org.xtimms.etsudoku.core
import androidx.annotation.StringRes
import androidx.compose.material.icons.Icons
@ -11,10 +11,10 @@ import androidx.compose.material.icons.outlined.LocalLibrary
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import org.xtimms.tokusho.R
import org.xtimms.tokusho.sections.explore.EXPLORE_DESTINATION
import org.xtimms.tokusho.sections.history.HISTORY_DESTINATION
import org.xtimms.tokusho.sections.shelf.SHELF_DESTINATION
import org.xtimms.etsudoku.R
import org.xtimms.etsudoku.sections.explore.EXPLORE_DESTINATION
import org.xtimms.etsudoku.sections.history.HISTORY_DESTINATION
import org.xtimms.etsudoku.sections.shelf.SHELF_DESTINATION
sealed class BottomNavDestination(
val value: String,

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core
package org.xtimms.etsudoku.core
import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.AnimationVector1D

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core
package org.xtimms.etsudoku.core
import android.graphics.Path
import android.view.animation.PathInterpolator
@ -9,7 +9,7 @@ import androidx.compose.animation.fadeOut
import androidx.compose.animation.slideInHorizontally
import androidx.compose.animation.slideOutHorizontally
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.lazy.grid.LazyGridState
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.IntOffset
@ -20,69 +20,69 @@ import androidx.navigation.compose.composable
import androidx.navigation.navArgument
import coil.ImageLoader
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.xtimms.tokusho.core.logs.FileLogger
import org.xtimms.tokusho.sections.details.DETAILS_DESTINATION
import org.xtimms.tokusho.sections.details.DetailsView
import org.xtimms.tokusho.sections.details.FULL_POSTER_DESTINATION
import org.xtimms.tokusho.sections.details.FullImageView
import org.xtimms.tokusho.sections.details.MANGA_ID_ARGUMENT
import org.xtimms.tokusho.sections.details.PICTURES_ARGUMENT
import org.xtimms.tokusho.sections.explore.ExploreView
import org.xtimms.tokusho.sections.feed.FEED_DESTINATION
import org.xtimms.tokusho.sections.feed.FeedView
import org.xtimms.tokusho.sections.history.HistoryView
import org.xtimms.tokusho.sections.list.LIST_DESTINATION
import org.xtimms.tokusho.sections.list.MangaListView
import org.xtimms.tokusho.sections.list.PROVIDER_ARGUMENT
import org.xtimms.tokusho.sections.reader.READER_DESTINATION
import org.xtimms.tokusho.sections.reader.ReaderView
import org.xtimms.tokusho.sections.search.SEARCH_DESTINATION
import org.xtimms.tokusho.sections.search.SearchHostView
import org.xtimms.tokusho.sections.settings.SETTINGS_DESTINATION
import org.xtimms.tokusho.sections.settings.SettingsView
import org.xtimms.tokusho.sections.settings.about.ABOUT_DESTINATION
import org.xtimms.tokusho.sections.settings.about.AboutView
import org.xtimms.tokusho.sections.settings.about.LICENSES_DESTINATION
import org.xtimms.tokusho.sections.settings.about.LICENSE_CONTENT_ARGUMENT
import org.xtimms.tokusho.sections.settings.about.LICENSE_DESTINATION
import org.xtimms.tokusho.sections.settings.about.LICENSE_NAME_ARGUMENT
import org.xtimms.tokusho.sections.settings.about.LICENSE_WEBSITE_ARGUMENT
import org.xtimms.tokusho.sections.settings.about.LicenseView
import org.xtimms.tokusho.sections.settings.about.OpenSourceLicensesView
import org.xtimms.tokusho.sections.settings.about.UPDATES_DESTINATION
import org.xtimms.tokusho.sections.settings.about.UpdateView
import org.xtimms.tokusho.sections.settings.advanced.ADVANCED_DESTINATION
import org.xtimms.tokusho.sections.settings.advanced.AdvancedView
import org.xtimms.tokusho.sections.settings.appearance.APPEARANCE_DESTINATION
import org.xtimms.tokusho.sections.settings.appearance.AppearanceView
import org.xtimms.tokusho.sections.settings.appearance.DARK_THEME_DESTINATION
import org.xtimms.tokusho.sections.settings.appearance.DarkThemeView
import org.xtimms.tokusho.sections.settings.appearance.LANGUAGES_DESTINATION
import org.xtimms.tokusho.sections.settings.appearance.LanguagesView
import org.xtimms.tokusho.sections.settings.backup.BACKUP_RESTORE_DESTINATION
import org.xtimms.tokusho.sections.settings.backup.BackupRestoreView
import org.xtimms.tokusho.sections.settings.backup.RESTORE_ARGUMENT
import org.xtimms.tokusho.sections.settings.backup.RESTORE_DESTINATION
import org.xtimms.tokusho.sections.settings.backup.RestoreItemsView
import org.xtimms.tokusho.sections.settings.network.NETWORK_DESTINATION
import org.xtimms.tokusho.sections.settings.network.NetworkView
import org.xtimms.tokusho.sections.settings.shelf.SHELF_SETTINGS_DESTINATION
import org.xtimms.tokusho.sections.settings.shelf.ShelfSettingsView
import org.xtimms.tokusho.sections.settings.shelf.categories.CATEGORIES_DESTINATION
import org.xtimms.tokusho.sections.settings.shelf.categories.CategoriesView
import org.xtimms.tokusho.sections.settings.sources.SOURCES_DESTINATION
import org.xtimms.tokusho.sections.settings.sources.SourcesView
import org.xtimms.tokusho.sections.settings.sources.catalog.CATALOG_DESTINATION
import org.xtimms.tokusho.sections.settings.sources.catalog.SourcesCatalogView
import org.xtimms.tokusho.sections.settings.storage.STORAGE_DESTINATION
import org.xtimms.tokusho.sections.settings.storage.StorageView
import org.xtimms.tokusho.sections.shelf.ShelfView
import org.xtimms.tokusho.sections.stats.STATS_DESTINATION
import org.xtimms.tokusho.sections.stats.StatsView
import org.xtimms.tokusho.sections.suggestions.SUGGESTIONS_DESTINATION
import org.xtimms.tokusho.sections.suggestions.SuggestionsView
import org.xtimms.tokusho.utils.StringArrayNavType
import org.xtimms.tokusho.utils.lang.removeFirstAndLast
import org.xtimms.etsudoku.core.logs.FileLogger
import org.xtimms.etsudoku.sections.details.DETAILS_DESTINATION
import org.xtimms.etsudoku.sections.details.DetailsView
import org.xtimms.etsudoku.sections.details.FULL_POSTER_DESTINATION
import org.xtimms.etsudoku.sections.details.FullImageView
import org.xtimms.etsudoku.sections.details.MANGA_ID_ARGUMENT
import org.xtimms.etsudoku.sections.details.PICTURES_ARGUMENT
import org.xtimms.etsudoku.sections.explore.ExploreView
import org.xtimms.etsudoku.sections.feed.FEED_DESTINATION
import org.xtimms.etsudoku.sections.feed.FeedView
import org.xtimms.etsudoku.sections.history.HistoryView
import org.xtimms.etsudoku.sections.list.LIST_DESTINATION
import org.xtimms.etsudoku.sections.list.MangaListView
import org.xtimms.etsudoku.sections.list.PROVIDER_ARGUMENT
import org.xtimms.etsudoku.sections.reader.READER_DESTINATION
import org.xtimms.etsudoku.sections.reader.ReaderView
import org.xtimms.etsudoku.sections.search.SEARCH_DESTINATION
import org.xtimms.etsudoku.sections.search.SearchHostView
import org.xtimms.etsudoku.sections.settings.SETTINGS_DESTINATION
import org.xtimms.etsudoku.sections.settings.SettingsView
import org.xtimms.etsudoku.sections.settings.about.ABOUT_DESTINATION
import org.xtimms.etsudoku.sections.settings.about.AboutView
import org.xtimms.etsudoku.sections.settings.about.LICENSES_DESTINATION
import org.xtimms.etsudoku.sections.settings.about.LICENSE_CONTENT_ARGUMENT
import org.xtimms.etsudoku.sections.settings.about.LICENSE_DESTINATION
import org.xtimms.etsudoku.sections.settings.about.LICENSE_NAME_ARGUMENT
import org.xtimms.etsudoku.sections.settings.about.LICENSE_WEBSITE_ARGUMENT
import org.xtimms.etsudoku.sections.settings.about.LicenseView
import org.xtimms.etsudoku.sections.settings.about.OpenSourceLicensesView
import org.xtimms.etsudoku.sections.settings.about.UPDATES_DESTINATION
import org.xtimms.etsudoku.sections.settings.about.UpdateView
import org.xtimms.etsudoku.sections.settings.advanced.ADVANCED_DESTINATION
import org.xtimms.etsudoku.sections.settings.advanced.AdvancedView
import org.xtimms.etsudoku.sections.settings.appearance.APPEARANCE_DESTINATION
import org.xtimms.etsudoku.sections.settings.appearance.AppearanceView
import org.xtimms.etsudoku.sections.settings.appearance.DARK_THEME_DESTINATION
import org.xtimms.etsudoku.sections.settings.appearance.DarkThemeView
import org.xtimms.etsudoku.sections.settings.appearance.LANGUAGES_DESTINATION
import org.xtimms.etsudoku.sections.settings.appearance.LanguagesView
import org.xtimms.etsudoku.sections.settings.backup.BACKUP_RESTORE_DESTINATION
import org.xtimms.etsudoku.sections.settings.backup.BackupRestoreView
import org.xtimms.etsudoku.sections.settings.backup.RESTORE_ARGUMENT
import org.xtimms.etsudoku.sections.settings.backup.RESTORE_DESTINATION
import org.xtimms.etsudoku.sections.settings.backup.RestoreItemsView
import org.xtimms.etsudoku.sections.settings.network.NETWORK_DESTINATION
import org.xtimms.etsudoku.sections.settings.network.NetworkView
import org.xtimms.etsudoku.sections.settings.shelf.SHELF_SETTINGS_DESTINATION
import org.xtimms.etsudoku.sections.settings.shelf.ShelfSettingsView
import org.xtimms.etsudoku.sections.settings.shelf.categories.CATEGORIES_DESTINATION
import org.xtimms.etsudoku.sections.settings.shelf.categories.CategoriesView
import org.xtimms.etsudoku.sections.settings.sources.SOURCES_DESTINATION
import org.xtimms.etsudoku.sections.settings.sources.SourcesView
import org.xtimms.etsudoku.sections.settings.sources.catalog.CATALOG_DESTINATION
import org.xtimms.etsudoku.sections.settings.sources.catalog.SourcesCatalogView
import org.xtimms.etsudoku.sections.settings.storage.STORAGE_DESTINATION
import org.xtimms.etsudoku.sections.settings.storage.StorageView
import org.xtimms.etsudoku.sections.shelf.ShelfView
import org.xtimms.etsudoku.sections.stats.STATS_DESTINATION
import org.xtimms.etsudoku.sections.stats.StatsView
import org.xtimms.etsudoku.sections.suggestions.SUGGESTIONS_DESTINATION
import org.xtimms.etsudoku.sections.suggestions.SuggestionsView
import org.xtimms.etsudoku.utils.StringArrayNavType
import org.xtimms.etsudoku.utils.lang.removeFirstAndLast
const val DURATION_ENTER = 400
const val DURATION_EXIT = 200
@ -100,8 +100,7 @@ fun Navigation(
isCompactScreen: Boolean,
modifier: Modifier,
padding: PaddingValues,
topBarHeightPx: Float,
listState: LazyGridState,
listState: LazyListState,
) {
val navigateBack: () -> Unit = { navController.popBackStack() }
@ -166,9 +165,8 @@ fun Navigation(
currentPage = { 2 },
showPageTabs = true,
padding = padding,
topBarHeightPx = topBarHeightPx,
navigateToDetails = navigateToDetails,
onRefresh = { true }
onRefresh = { true },
)
}
@ -176,9 +174,9 @@ fun Navigation(
HistoryView(
coil = coil,
padding = padding,
topBarHeightPx = topBarHeightPx,
navigateToDetails = navigateToDetails,
navigateToReader = { navController.navigate(READER_DESTINATION) }
navigateToReader = { navController.navigate(READER_DESTINATION) },
listState = listState
)
}
@ -193,7 +191,6 @@ fun Navigation(
},
navigateToSuggestions = { navController.navigate(SUGGESTIONS_DESTINATION) },
padding = padding,
topBarHeightPx = topBarHeightPx,
listState = listState
)
}

@ -0,0 +1,64 @@
package org.xtimms.etsudoku.core.base
import android.app.Dialog
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.annotation.CallSuper
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.DialogFragment
import androidx.viewbinding.ViewBinding
import com.google.android.material.dialog.MaterialAlertDialogBuilder
abstract class AlertDialogFragment<B : ViewBinding> : DialogFragment() {
var viewBinding: B? = null
private set
@Deprecated("", ReplaceWith("requireViewBinding()"))
protected val binding: B
get() = requireViewBinding()
final override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val binding = onCreateViewBinding(layoutInflater, null)
viewBinding = binding
return MaterialAlertDialogBuilder(requireContext(), theme)
.setView(binding.root)
.run(::onBuildDialog)
.create()
.also(::onDialogCreated)
}
final override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
) = viewBinding?.root
final override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
onViewBindingCreated(requireViewBinding(), savedInstanceState)
}
@CallSuper
override fun onDestroyView() {
viewBinding = null
super.onDestroyView()
}
open fun onBuildDialog(builder: MaterialAlertDialogBuilder): MaterialAlertDialogBuilder = builder
open fun onDialogCreated(dialog: AlertDialog) = Unit
@Deprecated("", ReplaceWith("viewBinding"))
protected fun bindingOrNull() = viewBinding
fun requireViewBinding(): B = checkNotNull(viewBinding) {
"Fragment $this did not return a ViewBinding from onCreateView() or this was called before onCreateView()."
}
protected abstract fun onCreateViewBinding(inflater: LayoutInflater, container: ViewGroup?): B
protected open fun onViewBindingCreated(binding: B, savedInstanceState: Bundle?) = Unit
}

@ -0,0 +1,76 @@
package org.xtimms.etsudoku.core.base
import android.content.Intent
import android.content.res.Configuration
import android.graphics.Color
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.WindowCompat
import androidx.viewbinding.ViewBinding
@Suppress("LeakingThis")
abstract class BaseActivity<B : ViewBinding> :
AppCompatActivity() {
lateinit var viewBinding: B
private set
private var defaultStatusBarColor = Color.TRANSPARENT
override fun onCreate(savedInstanceState: Bundle?) {
putDataToExtras(intent)
super.onCreate(savedInstanceState)
WindowCompat.setDecorFitsSystemWindows(window, false)
}
override fun onNewIntent(intent: Intent?) {
putDataToExtras(intent)
super.onNewIntent(intent)
}
@Deprecated("Use ViewBinding", level = DeprecationLevel.ERROR)
override fun setContentView(layoutResID: Int) {
super.setContentView(layoutResID)
}
@Deprecated("Use ViewBinding", level = DeprecationLevel.ERROR)
override fun setContentView(view: View?) {
super.setContentView(view)
}
protected fun setContentView(binding: B) {
this.viewBinding = binding
super.setContentView(binding.root)
}
override fun onSupportNavigateUp(): Boolean {
dispatchNavigateUp()
return true
}
protected fun isDarkAmoledTheme(): Boolean {
val uiMode = resources.configuration.uiMode
return uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES
}
protected open fun dispatchNavigateUp() {
val upIntent = parentActivityIntent
if (upIntent != null) {
if (!navigateUpTo(upIntent)) {
startActivity(upIntent)
}
} else {
finishAfterTransition()
}
}
private fun putDataToExtras(intent: Intent?) {
intent?.putExtra(EXTRA_DATA, intent.data)
}
companion object {
const val EXTRA_DATA = "data"
}
}

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.base.event
package org.xtimms.etsudoku.core.base.event
interface PagedUiEvent : UiEvent {
fun loadMore()

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.base.event
package org.xtimms.etsudoku.core.base.event
interface UiEvent {
fun showMessage(message: String?)

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.base.state
package org.xtimms.etsudoku.core.base.state
abstract class PagedUiState : UiState() {

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.base.state
package org.xtimms.etsudoku.core.base.state
abstract class UiState {
abstract val isLoading: Boolean

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.base.viewmodel
package org.xtimms.etsudoku.core.base.viewmodel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
@ -11,11 +11,11 @@ import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import org.xtimms.tokusho.core.base.event.UiEvent
import org.xtimms.tokusho.core.base.state.UiState
import org.xtimms.tokusho.utils.lang.EventFlow
import org.xtimms.tokusho.utils.lang.MutableEventFlow
import org.xtimms.tokusho.utils.lang.call
import org.xtimms.etsudoku.core.base.event.UiEvent
import org.xtimms.etsudoku.core.base.state.UiState
import org.xtimms.etsudoku.utils.lang.EventFlow
import org.xtimms.etsudoku.utils.lang.MutableEventFlow
import org.xtimms.etsudoku.utils.lang.call
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
import kotlin.coroutines.cancellation.CancellationException

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.base.viewmodel
package org.xtimms.etsudoku.core.base.viewmodel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
@ -17,9 +17,9 @@ import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import org.xtimms.tokusho.utils.lang.EventFlow
import org.xtimms.tokusho.utils.lang.MutableEventFlow
import org.xtimms.tokusho.utils.lang.call
import org.xtimms.etsudoku.utils.lang.EventFlow
import org.xtimms.etsudoku.utils.lang.MutableEventFlow
import org.xtimms.etsudoku.utils.lang.call
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
import kotlin.coroutines.cancellation.CancellationException

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.cache
package org.xtimms.etsudoku.core.cache
enum class CacheDir(val dir: String) {

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.cache
package org.xtimms.etsudoku.core.cache
import org.koitharu.kotatsu.parsers.model.Manga
import org.koitharu.kotatsu.parsers.model.MangaPage

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.cache
package org.xtimms.etsudoku.core.cache
import androidx.collection.LruCache
import java.util.concurrent.TimeUnit

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.cache
package org.xtimms.etsudoku.core.cache
import android.os.SystemClock
import java.util.concurrent.TimeUnit

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.cache
package org.xtimms.etsudoku.core.cache
import android.app.Application
import android.content.ComponentCallbacks2

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.cache
package org.xtimms.etsudoku.core.cache
import android.content.Context
import android.graphics.Bitmap
@ -13,13 +13,13 @@ import okio.buffer
import okio.sink
import org.koitharu.kotatsu.parsers.util.SuspendLazy
import org.koitharu.kotatsu.parsers.util.runCatchingCancellable
import org.xtimms.tokusho.utils.FileSize
import org.xtimms.tokusho.utils.lang.longHashCode
import org.xtimms.tokusho.utils.lang.writeAllCancellable
import org.xtimms.tokusho.utils.system.compressToPNG
import org.xtimms.tokusho.utils.system.subdir
import org.xtimms.tokusho.utils.system.takeIfReadable
import org.xtimms.tokusho.utils.system.takeIfWriteable
import org.xtimms.etsudoku.utils.FileSize
import org.xtimms.etsudoku.utils.lang.longHashCode
import org.xtimms.etsudoku.utils.lang.writeAllCancellable
import org.xtimms.etsudoku.utils.system.compressToPNG
import org.xtimms.etsudoku.utils.system.subdir
import org.xtimms.etsudoku.utils.system.takeIfReadable
import org.xtimms.etsudoku.utils.system.takeIfWriteable
import java.io.File
import javax.inject.Inject
import javax.inject.Singleton

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.cache
package org.xtimms.etsudoku.core.cache
import kotlinx.coroutines.Deferred

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.cache
package org.xtimms.etsudoku.core.cache
import org.koitharu.kotatsu.parsers.model.Manga
import org.koitharu.kotatsu.parsers.model.MangaPage

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.components
package org.xtimms.etsudoku.core.components
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.foundation.ExperimentalFoundationApi
@ -31,7 +31,7 @@ import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.min
import org.xtimms.tokusho.ui.theme.TokushoTheme
import org.xtimms.etsudoku.ui.theme.EtsudokuTheme
import java.lang.Integer.MAX_VALUE
import kotlin.math.min
@ -105,7 +105,7 @@ fun AnimatedButton(
@Preview(name = "Icon")
@Composable
private fun PreviewWithIcon() {
TokushoTheme {
EtsudokuTheme {
AnimatedButton(
type = ButtonType.PRIMARY,
icon = Icons.Outlined.Edit

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.components
package org.xtimms.etsudoku.core.components
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.SizeTransform

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.components
package org.xtimms.etsudoku.core.components
import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.TweenSpec
@ -14,19 +14,25 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.times
import org.xtimms.tokusho.core.components.shape.WavyShape
import org.xtimms.tokusho.utils.lang.clamp
import org.xtimms.etsudoku.core.components.shape.WavyShape
import org.xtimms.etsudoku.utils.lang.clamp
@Composable
fun BackgroundProgress(
color: Color,
alpha: Float,
percent: Float,
) {
val percentWithNewSpent = 0.2f // TODO
val animatedAlpha = animateFloatAsState(
label = "alpha",
targetValue = alpha,
animationSpec = TweenSpec(500)
).value
val percentWithNewSpentAnimated = animateFloatAsState(
label = "percentWithNewSpentAnimated",
targetValue = percentWithNewSpent,
val percentAnimated = animateFloatAsState(
label = "percentAnimated",
targetValue = percent,
animationSpec = TweenSpec(300),
).value
@ -36,15 +42,15 @@ fun BackgroundProgress(
Box(
modifier = Modifier
.background(
color.copy(alpha = 0.33f),
color.copy(alpha = animatedAlpha),
shape = WavyShape(
period = 30.dp,
amplitude = percentWithNewSpentAnimated.clamp(0.96f, 1f) * 2.dp,
amplitude = percentAnimated.clamp(0.96f, 1f) * 2.dp,
shift = shift.value,
),
)
.fillMaxHeight()
.fillMaxWidth(percentWithNewSpentAnimated),
.fillMaxWidth(percentAnimated),
)
}
}

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.components
package org.xtimms.etsudoku.core.components
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.Animatable
@ -19,11 +19,11 @@ import androidx.navigation.NavController
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.compose.currentBackStackEntryAsState
import kotlinx.coroutines.launch
import org.xtimms.tokusho.core.BottomNavDestination
import org.xtimms.tokusho.core.BottomNavDestination.Companion.Icon
import org.xtimms.tokusho.sections.explore.EXPLORE_DESTINATION
import org.xtimms.tokusho.sections.history.HISTORY_DESTINATION
import org.xtimms.tokusho.sections.shelf.SHELF_DESTINATION
import org.xtimms.etsudoku.core.BottomNavDestination
import org.xtimms.etsudoku.core.BottomNavDestination.Companion.Icon
import org.xtimms.etsudoku.sections.explore.EXPLORE_DESTINATION
import org.xtimms.etsudoku.sections.history.HISTORY_DESTINATION
import org.xtimms.etsudoku.sections.shelf.SHELF_DESTINATION
@Composable
fun BottomNavBar(

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.components
package org.xtimms.etsudoku.core.components
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
@ -12,7 +12,7 @@ import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import org.xtimms.tokusho.R
import org.xtimms.etsudoku.R
@Composable
fun ConfirmButton(

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.components
package org.xtimms.etsudoku.core.components
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.components
package org.xtimms.etsudoku.core.components
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.animateFloatAsState
@ -23,9 +23,9 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import androidx.navigation.compose.currentBackStackEntryAsState
import org.xtimms.tokusho.R
import org.xtimms.tokusho.sections.history.HISTORY_DESTINATION
import org.xtimms.tokusho.sections.reader.READER_DESTINATION
import org.xtimms.etsudoku.R
import org.xtimms.etsudoku.sections.history.HISTORY_DESTINATION
import org.xtimms.etsudoku.sections.reader.READER_DESTINATION
@Composable
fun ContinueReadingButton(

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.components
package org.xtimms.etsudoku.core.components
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.foundation.background

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.components
package org.xtimms.etsudoku.core.components
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
@ -34,7 +34,7 @@ private val ButtonsCrossAxisSpacing = Arrangement.spacedBy(12.dp, Alignment.Top)
@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class)
@Composable
fun TokushoDialog(
fun EtsudokuDialog(
onDismissRequest: () -> Unit,
confirmButton: @Composable () -> Unit,
modifier: Modifier = Modifier,

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.components
package org.xtimms.etsudoku.core.components
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.components
package org.xtimms.etsudoku.core.components
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.height

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.components
package org.xtimms.etsudoku.core.components
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.CubicBezierEasing

@ -0,0 +1,144 @@
package org.xtimms.etsudoku.core.components
import android.text.Spanned
import android.text.style.BulletSpan
import android.text.style.ForegroundColorSpan
import android.text.style.RelativeSizeSpan
import android.text.style.StrikethroughSpan
import android.text.style.StyleSpan
import android.text.style.SubscriptSpan
import android.text.style.SuperscriptSpan
import android.text.style.TypefaceSpan
import android.text.style.URLSpan
import android.text.style.UnderlineSpan
import android.widget.TextView
import androidx.compose.foundation.text.ClickableText
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.TextLayoutResult
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.sp
import androidx.core.text.HtmlCompat
import org.xtimms.etsudoku.utils.spanStyle
private const val URL_TAG = "url_tag"
@Composable
fun HtmlTextField(
text: String,
modifier: Modifier = Modifier,
style: TextStyle = TextStyle.Default,
softWrap: Boolean = true,
overflow: TextOverflow = TextOverflow.Clip,
maxLines: Int = Int.MAX_VALUE,
onTextLayout: (TextLayoutResult) -> Unit = {},
linkClicked: ((String) -> Unit)? = null,
fontSize: TextUnit = 14.sp,
flags: Int = HtmlCompat.FROM_HTML_MODE_COMPACT,
urlSpanStyle: SpanStyle = SpanStyle(
color = linkTextColor(),
textDecoration = TextDecoration.Underline
),
customSpannedHandler: ((Spanned) -> AnnotatedString)? = null
) {
val content = text.asHTML(fontSize, flags, urlSpanStyle, customSpannedHandler)
if (linkClicked != null) {
ClickableText(
modifier = modifier,
text = content,
style = style,
softWrap = softWrap,
overflow = overflow,
maxLines = maxLines,
onTextLayout = onTextLayout,
onClick = {
content
.getStringAnnotations(URL_TAG, it, it)
.firstOrNull()
?.let { stringAnnotation -> linkClicked(stringAnnotation.item) }
}
)
} else {
Text(
modifier = modifier,
text = content,
style = style,
softWrap = softWrap,
overflow = overflow,
maxLines = maxLines,
onTextLayout = onTextLayout
)
}
}
@Composable
private fun linkTextColor() = Color(
TextView(LocalContext.current).linkTextColors.defaultColor
)
@Composable
private fun String.asHTML(
fontSize: TextUnit,
flags: Int,
URLSpanStyle: SpanStyle,
customSpannedHandler: ((Spanned) -> AnnotatedString)? = null
) = buildAnnotatedString {
val spanned = HtmlCompat.fromHtml(this@asHTML, flags)
val spans = spanned.getSpans(0, spanned.length, Any::class.java)
if (customSpannedHandler != null) {
append(customSpannedHandler(spanned))
} else {
append(spanned.toString())
}
spans
.filter { it !is BulletSpan }
.forEach { span ->
val start = spanned.getSpanStart(span)
val end = spanned.getSpanEnd(span)
when (span) {
is RelativeSizeSpan -> span.spanStyle(fontSize)
is StyleSpan -> span.spanStyle()
is UnderlineSpan -> span.spanStyle()
is ForegroundColorSpan -> span.spanStyle()
is TypefaceSpan -> span.spanStyle()
is StrikethroughSpan -> span.spanStyle()
is SuperscriptSpan -> span.spanStyle()
is SubscriptSpan -> span.spanStyle()
is URLSpan -> {
addStringAnnotation(
tag = URL_TAG,
annotation = span.url,
start = start,
end = end
)
URLSpanStyle
}
else -> {
null
}
}?.let { spanStyle ->
addStyle(spanStyle, start, end)
}
}
}
internal fun UnderlineSpan.spanStyle(): SpanStyle =
SpanStyle(textDecoration = TextDecoration.Underline)
internal fun ForegroundColorSpan.spanStyle(): SpanStyle =
SpanStyle(color = Color(foregroundColor))
internal fun StrikethroughSpan.spanStyle(): SpanStyle =
SpanStyle(textDecoration = TextDecoration.LineThrough)

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.components
package org.xtimms.etsudoku.core.components
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
@ -14,7 +14,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import org.xtimms.tokusho.R
import org.xtimms.etsudoku.R
@Composable
fun BackIconButton(

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.components
package org.xtimms.etsudoku.core.components
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.components
package org.xtimms.etsudoku.core.components
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
@ -14,7 +14,7 @@ import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.semantics.Role
import coil.ImageLoader
import coil.compose.AsyncImage
import org.xtimms.tokusho.core.AsyncImageImpl
import org.xtimms.etsudoku.core.AsyncImageImpl
enum class MangaCover(val ratio: Float) {
Square(1f / 1f),

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.components
package org.xtimms.etsudoku.core.components
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
@ -33,7 +33,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import coil.ImageLoader
import org.koitharu.kotatsu.parsers.model.Manga
import org.xtimms.tokusho.core.AsyncImageImpl
import org.xtimms.etsudoku.core.AsyncImageImpl
private const val GridSelectedCoverAlpha = 0.76f

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.components
package org.xtimms.etsudoku.core.components
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
@ -19,9 +19,9 @@ import androidx.compose.ui.res.stringResource
import androidx.navigation.NavController
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.compose.currentBackStackEntryAsState
import org.xtimms.tokusho.core.BottomNavDestination
import org.xtimms.tokusho.core.BottomNavDestination.Companion.Icon
import org.xtimms.tokusho.sections.search.SEARCH_DESTINATION
import org.xtimms.etsudoku.core.BottomNavDestination
import org.xtimms.etsudoku.core.BottomNavDestination.Companion.Icon
import org.xtimms.etsudoku.sections.search.SEARCH_DESTINATION
@Composable
fun NavigationRail(

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.components
package org.xtimms.etsudoku.core.components
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.padding

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.components
package org.xtimms.etsudoku.core.components
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.SizeTransform
@ -65,14 +65,14 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import org.xtimms.tokusho.ui.theme.FixedAccentColors
import org.xtimms.tokusho.R
import org.xtimms.tokusho.ui.monet.LocalTonalPalettes
import org.xtimms.tokusho.ui.monet.TonalPalettes.Companion.toTonalPalettes
import org.xtimms.tokusho.ui.theme.PreviewThemeLight
import org.xtimms.tokusho.ui.theme.TokushoTheme
import org.xtimms.tokusho.ui.theme.applyOpacity
import org.xtimms.tokusho.utils.FileSize
import org.xtimms.etsudoku.ui.theme.FixedAccentColors
import org.xtimms.etsudoku.R
import org.xtimms.etsudoku.ui.monet.LocalTonalPalettes
import org.xtimms.etsudoku.ui.monet.TonalPalettes.Companion.toTonalPalettes
import org.xtimms.etsudoku.ui.theme.PreviewThemeLight
import org.xtimms.etsudoku.ui.theme.EtsudokuTheme
import org.xtimms.etsudoku.ui.theme.applyOpacity
import org.xtimms.etsudoku.utils.FileSize
private const val horizontal = 8
private const val vertical = 16
@ -754,7 +754,7 @@ fun PreferenceStorageItem(
@Composable
@Preview(showBackground = true)
fun PreferenceStorageHeaderPreview() {
TokushoTheme {
EtsudokuTheme {
PreferenceStorageHeader()
}
}
@ -762,7 +762,7 @@ fun PreferenceStorageHeaderPreview() {
@Composable
@Preview(showBackground = true)
fun PreferenceStorageItemPreview() {
TokushoTheme {
EtsudokuTheme {
PreferenceStorageItem(title = "Saved manga", icon = Icons.Outlined.Save, total = 0F)
}
}

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.components
package org.xtimms.etsudoku.core.components
import androidx.compose.animation.core.animate
import androidx.compose.foundation.layout.Box

@ -0,0 +1,244 @@
package org.xtimms.etsudoku.core.components
import android.content.res.Configuration.UI_MODE_NIGHT_YES
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.FloatTweenSpec
import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.RepeatMode
import androidx.compose.animation.core.TweenSpec
import androidx.compose.animation.core.VectorConverter
import androidx.compose.animation.core.animateValue
import androidx.compose.animation.core.infiniteRepeatable
import androidx.compose.animation.core.rememberInfiniteTransition
import androidx.compose.animation.core.tween
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawWithContent
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.BlendMode
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.ContentDrawScope
import androidx.compose.ui.graphics.nativeCanvas
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.launch
import org.xtimms.etsudoku.R
import org.xtimms.etsudoku.core.model.MangaHistory
import org.xtimms.etsudoku.sections.details.model.HistoryInfo
import org.xtimms.etsudoku.ui.theme.EtsudokuTheme
import java.time.Instant
@Composable
fun RowScope.ReadButton(
info: HistoryInfo,
estimatedReadTime: String
) {
val shift = remember { Animatable(0f) }
val coroutineScope = rememberCoroutineScope()
val animatedCardContainerColor = animateColorAsState(
label = "animatedCardContainerColor",
targetValue = if (info.totalChapters == 0) MaterialTheme.colorScheme.errorContainer else MaterialTheme.colorScheme.primaryContainer,
animationSpec = TweenSpec(500)
).value
val animatedCardContentColor = animateColorAsState(
label = "animatedCardContentColor",
targetValue = if (info.totalChapters == 0) MaterialTheme.colorScheme.onErrorContainer else MaterialTheme.colorScheme.onPrimaryContainer,
animationSpec = TweenSpec(500)
).value
LaunchedEffect(Unit) {
fun anim() {
coroutineScope.launch {
shift.animateTo(
1f,
animationSpec = FloatTweenSpec(4000, 0, LinearEasing)
)
shift.snapTo(0f)
anim()
}
}
anim()
}
Card(
modifier = Modifier
.weight(1F)
.height(54.dp),
shape = CircleShape,
colors = CardDefaults.cardColors(
containerColor = animatedCardContainerColor,
contentColor = animatedCardContentColor,
),
onClick = {
// todo
}
) {
Box(
modifier = Modifier.fillMaxHeight(),
contentAlignment = Alignment.CenterEnd,
) {
BackgroundProgress(
if (info.totalChapters == 0) MaterialTheme.colorScheme.error else MaterialTheme.colorScheme.primary,
if (!info.isValid) 0.1f else 0.33f,
info.history?.percent?.coerceIn(0f, 1f) ?: 0f
)
Column(
modifier = Modifier
.fillMaxSize()
.drawWithLayer {
drawContent()
val leftOffset = size.width - 20.dp.toPx()
drawRect(
topLeft = Offset(leftOffset, 0f),
size = Size(
20.dp.toPx(),
size.height,
),
blendMode = BlendMode.SrcIn,
brush = Brush.horizontalGradient(
colors = listOf(
Color.Black,
Color.Black.copy(alpha = 0f),
),
startX = leftOffset,
endX = leftOffset + 14.dp.toPx()
)
)
},
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
) {
val infiniteTransition by rememberInfiniteTransition("infiniteTransition").animateValue(
label = "infiniteTransition",
initialValue = 0,
targetValue = 2,
typeConverter = Int.VectorConverter,
animationSpec = infiniteRepeatable(tween(15000), RepeatMode.Restart)
)
val chaptersSubtitle = when {
!info.isValid -> stringResource(R.string.loading_)
info.currentChapter >= 0 -> when (infiniteTransition) {
1 -> stringResource(
R.string.chapter_d_of_d,
info.currentChapter + 1,
info.totalChapters,
)
0 -> estimatedReadTime
else -> estimatedReadTime
}
info.totalChapters == 0 -> stringResource(R.string.no_chapters)
else -> LocalContext.current.resources.getQuantityString(
R.plurals.chapters,
info.totalChapters,
info.totalChapters,
)
}
Text(
text = if (info.history != null) {
stringResource(R.string.continue_reading)
} else {
stringResource(R.string.read)
},
)
AnimatedContent(targetState = chaptersSubtitle, label = "Subtitle animation") {
Text(
text = it,
style = MaterialTheme.typography.labelMedium,
)
}
}
}
}
}
fun ContentDrawScope.drawWithLayer(block: ContentDrawScope.() -> Unit) {
with(drawContext.canvas.nativeCanvas) {
val checkPoint = saveLayer(null, null)
block()
restoreToCount(checkPoint)
}
}
fun Modifier.drawWithLayer(block: ContentDrawScope.() -> Unit) = this.then(
Modifier.drawWithContent {
drawWithLayer {
block()
}
}
)
@Preview
@Composable
private fun Preview() {
EtsudokuTheme {
Row {
ReadButton(
HistoryInfo(
100,
33,
MangaHistory(
Instant.now(),
Instant.now(),
1,
3,
1,
50f
)
),
"123"
)
}
}
}
@Preview(name = "Night mode", uiMode = UI_MODE_NIGHT_YES)
@Composable
private fun PreviewNightMode() {
EtsudokuTheme {
Row {
ReadButton(
HistoryInfo(
100,
33,
MangaHistory(
Instant.now(),
Instant.now(),
1,
3,
1,
50f
)
),
"123"
)
}
}
}

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.components
package org.xtimms.etsudoku.core.components
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.RowScope

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.components
package org.xtimms.etsudoku.core.components
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
@ -15,9 +15,9 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import org.xtimms.tokusho.R
import org.xtimms.tokusho.ui.theme.TokushoTheme
import org.xtimms.tokusho.utils.lang.toStringPositiveValueOrUnknown
import org.xtimms.etsudoku.R
import org.xtimms.etsudoku.ui.theme.EtsudokuTheme
import org.xtimms.etsudoku.utils.lang.toStringPositiveValueOrUnknown
@Composable
fun SmallScoreIndicator(
@ -48,7 +48,7 @@ fun SmallScoreIndicator(
@Preview(showBackground = true)
@Composable
fun SmallScoreIndicatorPreview() {
TokushoTheme {
EtsudokuTheme {
SmallScoreIndicator(score = 1f)
}
}

@ -0,0 +1,116 @@
package org.xtimms.etsudoku.core.components
import androidx.compose.animation.animateContentSize
import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.spring
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.rounded.ArrowBack
import androidx.compose.material.icons.outlined.Close
import androidx.compose.material.icons.outlined.Search
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SearchBar
import androidx.compose.material3.SearchBarDefaults
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import org.xtimms.etsudoku.R
@Composable
@OptIn(ExperimentalMaterial3Api::class)
fun EmbeddedSearchBar(
onQueryChange: (String) -> Unit,
isSearchActive: Boolean,
onActiveChanged: (Boolean) -> Unit,
modifier: Modifier = Modifier,
onSearch: ((String) -> Unit)? = null,
) {
var searchQuery by rememberSaveable { mutableStateOf("") }
val activeChanged: (Boolean) -> Unit = { active ->
searchQuery = ""
onQueryChange("")
onActiveChanged(active)
}
SearchBar(
query = searchQuery,
onQueryChange = { query ->
searchQuery = query
onQueryChange(query)
},
onSearch = onSearch ?: { activeChanged(false) },
active = isSearchActive,
onActiveChange = activeChanged,
modifier = if (isSearchActive) {
modifier
.animateContentSize(spring(stiffness = Spring.StiffnessHigh))
} else {
modifier
.fillMaxWidth()
.animateContentSize(spring(stiffness = Spring.StiffnessHigh))
},
placeholder = { Text("Search") },
leadingIcon = {
if (isSearchActive) {
IconButton(
onClick = { activeChanged(false) },
) {
Icon(
imageVector = Icons.AutoMirrored.Rounded.ArrowBack,
contentDescription = null,
tint = MaterialTheme.colorScheme.primary,
)
}
} else {
Icon(
imageVector = Icons.Outlined.Search,
contentDescription = null,
tint = MaterialTheme.colorScheme.onSurfaceVariant,
)
}
},
trailingIcon = if (isSearchActive && searchQuery.isNotEmpty()) {
{
IconButton(
onClick = {
searchQuery = ""
onQueryChange("")
},
) {
Icon(
imageVector = Icons.Outlined.Close,
contentDescription = null,
tint = MaterialTheme.colorScheme.primary,
)
}
}
} else {
null
},
colors = SearchBarDefaults.colors(
containerColor = if (isSearchActive) {
MaterialTheme.colorScheme.background
} else {
MaterialTheme.colorScheme.surfaceContainerLow
},
),
tonalElevation = 0.dp,
windowInsets = if (isSearchActive) {
SearchBarDefaults.windowInsets
} else {
WindowInsets(0.dp)
}
) {
// Search suggestions or results
}
}

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.components
package org.xtimms.etsudoku.core.components
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.SizeTransform
@ -20,7 +20,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.unit.dp
import org.xtimms.tokusho.ui.theme.applyOpacity
import org.xtimms.etsudoku.ui.theme.applyOpacity
@Composable
fun SettingTitle(text: String) {

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.components
package org.xtimms.etsudoku.core.components
import android.net.Uri
import androidx.compose.foundation.clickable
@ -24,8 +24,8 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.core.net.toUri
import coil.ImageLoader
import org.xtimms.tokusho.core.AsyncImageImpl
import org.xtimms.tokusho.ui.theme.TokushoTheme
import org.xtimms.etsudoku.core.AsyncImageImpl
import org.xtimms.etsudoku.ui.theme.EtsudokuTheme
@Composable
fun SourceItem(
@ -38,15 +38,15 @@ fun SourceItem(
) {
Column(
modifier = modifier
.width(96.dp)
.width(88.dp)
.clip(RoundedCornerShape(8.dp))
.clickable(onClick = onClick)
.padding(start = 8.dp, end = 8.dp),
horizontalAlignment = Alignment.Start
) {
Card(
modifier = modifier
.size(96.dp)
modifier = Modifier
.size(88.dp)
.clip(MaterialTheme.shapes.large)
.aspectRatio(1f)
) {
@ -55,7 +55,7 @@ fun SourceItem(
model = faviconUrl,
contentDescription = "favicon",
contentScale = ContentScale.Crop,
modifier = modifier
modifier = Modifier
.fillMaxSize()
.clip(MaterialTheme.shapes.large)
)
@ -77,7 +77,7 @@ fun SourceItem(
@Preview
@Composable
fun SourceItemPreview() {
TokushoTheme {
EtsudokuTheme {
SourceItem(
coil = ImageLoader(LocalContext.current),
faviconUrl = "".toUri(),

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.components
package org.xtimms.etsudoku.core.components
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Row

@ -1,8 +1,12 @@
package org.xtimms.tokusho.core.components
package org.xtimms.etsudoku.core.components
import android.graphics.Path
import android.view.animation.PathInterpolator
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.core.FastOutLinearInEasing
import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.spring
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
@ -10,15 +14,28 @@ import androidx.compose.animation.slideInHorizontally
import androidx.compose.animation.slideOutHorizontally
import androidx.compose.foundation.background
import androidx.compose.foundation.basicMarquee
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.WindowInsetsSides
import androidx.compose.foundation.layout.consumeWindowInsets
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.only
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape
@ -26,6 +43,7 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Menu
import androidx.compose.material.icons.outlined.RssFeed
import androidx.compose.material.icons.outlined.Search
import androidx.compose.material.icons.outlined.SentimentSatisfiedAlt
import androidx.compose.material.icons.outlined.Settings
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
@ -36,11 +54,14 @@ import androidx.compose.material3.LargeTopAppBar
import androidx.compose.material3.LocalMinimumInteractiveComponentEnforcement
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.MediumTopAppBar
import androidx.compose.material3.Scaffold
import androidx.compose.material3.SuggestionChip
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarColors
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.TopAppBarScrollBehavior
import androidx.compose.material3.rememberTopAppBarState
import androidx.compose.material3.surfaceColorAtElevation
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
@ -49,34 +70,42 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Color.Companion.Blue
import androidx.compose.ui.graphics.Color.Companion.DarkGray
import androidx.compose.ui.graphics.lerp
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import androidx.navigation.NavHostController
import androidx.navigation.compose.currentBackStackEntryAsState
import kotlinx.collections.immutable.persistentListOf
import org.xtimms.tokusho.R
import org.xtimms.tokusho.core.DURATION_ENTER
import org.xtimms.tokusho.core.DURATION_EXIT
import org.xtimms.tokusho.core.initialOffset
import org.xtimms.tokusho.core.motion.materialSharedAxisXIn
import org.xtimms.tokusho.core.motion.materialSharedAxisXOut
import org.xtimms.tokusho.core.toEasing
import org.xtimms.tokusho.sections.explore.EXPLORE_DESTINATION
import org.xtimms.tokusho.sections.feed.FEED_DESTINATION
import org.xtimms.tokusho.sections.history.HISTORY_DESTINATION
import org.xtimms.tokusho.sections.search.SEARCH_DESTINATION
import org.xtimms.tokusho.sections.settings.SETTINGS_DESTINATION
import org.xtimms.tokusho.sections.shelf.SHELF_DESTINATION
import org.xtimms.tokusho.ui.theme.TokushoTheme
import org.xtimms.etsudoku.R
import org.xtimms.etsudoku.core.DURATION_ENTER
import org.xtimms.etsudoku.core.DURATION_EXIT
import org.xtimms.etsudoku.core.initialOffset
import org.xtimms.etsudoku.core.toEasing
import org.xtimms.etsudoku.sections.explore.EXPLORE_DESTINATION
import org.xtimms.etsudoku.sections.feed.FEED_DESTINATION
import org.xtimms.etsudoku.sections.history.HISTORY_DESTINATION
import org.xtimms.etsudoku.sections.search.SEARCH_DESTINATION
import org.xtimms.etsudoku.sections.settings.SETTINGS_DESTINATION
import org.xtimms.etsudoku.sections.shelf.SHELF_DESTINATION
import org.xtimms.etsudoku.ui.theme.EtsudokuTheme
import java.time.LocalDate
import java.time.format.DateTimeFormatter
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun TopAppBar(
navController: NavController,
modifier: Modifier = Modifier,
backgroundAlphaProvider: () -> Float,
searchBarColorProvider: () -> Color,
) {
val navBackStackEntry by navController.currentBackStackEntryAsState()
@ -91,6 +120,12 @@ fun TopAppBar(
}
}
val aprilFoolsDay = LocalDate.of(LocalDate.now().year, 4, 1)
val dtStart = aprilFoolsDay.format(DateTimeFormatter.ISO_DATE)
val currentDt = LocalDate.now()
val isAprilFoolsDay = currentDt.format(DateTimeFormatter.ISO_DATE).equals(dtStart)
val path = Path().apply {
moveTo(0f, 0f)
cubicTo(0.05F, 0F, 0.133333F, 0.06F, 0.166666F, 0.4F)
@ -133,9 +168,7 @@ fun TopAppBar(
.height(56.dp)
.padding(start = 16.dp),
shape = RoundedCornerShape(50),
colors = CardDefaults.cardColors(
containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(6.dp)
),
colors = CardDefaults.cardColors().copy(containerColor = searchBarColorProvider()),
) {
Row(
modifier = Modifier
@ -145,7 +178,7 @@ fun TopAppBar(
verticalAlignment = Alignment.CenterVertically
) {
Icon(
imageVector = Icons.Outlined.Search,
imageVector = if (isAprilFoolsDay) Icons.Outlined.SentimentSatisfiedAlt else Icons.Outlined.Search,
contentDescription = "search",
tint = MaterialTheme.colorScheme.outline
)
@ -202,7 +235,7 @@ fun DefaultTopAppBar(
)
}
@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class)
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SmallTopAppBarWithChips(
title: String,
@ -295,78 +328,4 @@ fun AppBarTitle(
)
}
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Preview
@Composable
fun DefaultTopAppBarPreview() {
TokushoTheme {
DefaultTopAppBar(
title = "Tokusho",
actions = {
IconButton(onClick = { /*TODO*/ }) {
Icon(
imageVector = Icons.Filled.Menu,
contentDescription = "Localized description"
)
}
},
navigateBack = {}
)
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Preview
@Composable
fun DefaultTopAppBarWithChipsPreview() {
TokushoTheme {
SmallTopAppBarWithChips(
title = "Tokusho",
chips = listOf(
"Chip 1",
"Chip 2",
"Chip 3",
"Chip 4",
"Chip 1",
"Chip 2",
"Chip 3",
"Chip 4"
),
navigateBack = {}
)
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Preview
@Composable
fun SmallTopAppBarPreview() {
TokushoTheme {
SmallTopAppBar(
title = "Tokusho",
navigateBack = {}
)
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Preview
@Composable
fun ClassicTopAppBarPreview() {
TokushoTheme {
ClassicTopAppBar(
title = "Tokusho",
navigateBack = {},
actions = {
IconButton(onClick = { /*TODO*/ }) {
Icon(
imageVector = Icons.Filled.Menu,
contentDescription = "Localized description"
)
}
}
)
}
}

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.components.effects
package org.xtimms.etsudoku.core.components.effects
import android.annotation.SuppressLint
import androidx.compose.animation.AnimatedVisibility
@ -22,7 +22,7 @@ import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListUpdateCallback
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.xtimms.tokusho.core.model.ListModel
import org.xtimms.etsudoku.core.model.ListModel
import java.time.Instant
enum class RowEntityType { Header, Item }

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.components.effects
package org.xtimms.etsudoku.core.components.effects
import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.RepeatMode

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.components.icons
package org.xtimms.etsudoku.core.components.icons
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.materialIcon

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.components.icons
package org.xtimms.etsudoku.core.components.icons
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.materialIcon

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.components.icons
package org.xtimms.etsudoku.core.components.icons
import androidx.compose.material.icons.Icons
import androidx.compose.ui.graphics.Color

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.components.shape
package org.xtimms.etsudoku.core.components.shape
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Rect

@ -1,10 +1,10 @@
package org.xtimms.tokusho.core.database
package org.xtimms.etsudoku.core.database
import android.content.res.Resources
import androidx.room.RoomDatabase
import androidx.sqlite.db.SupportSQLiteDatabase
import org.koitharu.kotatsu.parsers.model.SortOrder
import org.xtimms.tokusho.R
import org.xtimms.etsudoku.R
class DatabasePrePopulateCallback(private val resources: Resources) : RoomDatabase.Callback() {

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.database
package org.xtimms.etsudoku.core.database
import android.content.Context
import androidx.room.Database
@ -10,28 +10,28 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import org.xtimms.tokusho.core.database.dao.BookmarksDao
import org.xtimms.tokusho.core.database.dao.FavouriteCategoriesDao
import org.xtimms.tokusho.core.database.dao.FavouritesDao
import org.xtimms.tokusho.core.database.dao.HistoryDao
import org.xtimms.tokusho.core.database.dao.MangaDao
import org.xtimms.tokusho.core.database.dao.MangaSourcesDao
import org.xtimms.tokusho.core.database.dao.SuggestionDao
import org.xtimms.tokusho.core.database.dao.TagsDao
import org.xtimms.tokusho.core.database.dao.TrackLogsDao
import org.xtimms.tokusho.core.database.dao.TracksDao
import org.xtimms.tokusho.core.database.entity.BookmarkEntity
import org.xtimms.tokusho.core.database.entity.FavouriteCategoryEntity
import org.xtimms.tokusho.core.database.entity.FavouriteEntity
import org.xtimms.tokusho.core.database.entity.HistoryEntity
import org.xtimms.tokusho.core.database.entity.MangaEntity
import org.xtimms.tokusho.core.database.entity.MangaSourceEntity
import org.xtimms.tokusho.core.database.entity.MangaTagsEntity
import org.xtimms.tokusho.core.database.entity.SuggestionEntity
import org.xtimms.tokusho.core.database.entity.TagEntity
import org.xtimms.tokusho.core.database.entity.TrackEntity
import org.xtimms.tokusho.core.database.entity.TrackLogEntity
import org.xtimms.tokusho.utils.lang.processLifecycleScope
import org.xtimms.etsudoku.core.database.dao.BookmarksDao
import org.xtimms.etsudoku.core.database.dao.FavouriteCategoriesDao
import org.xtimms.etsudoku.core.database.dao.FavouritesDao
import org.xtimms.etsudoku.core.database.dao.HistoryDao
import org.xtimms.etsudoku.core.database.dao.MangaDao
import org.xtimms.etsudoku.core.database.dao.MangaSourcesDao
import org.xtimms.etsudoku.core.database.dao.SuggestionDao
import org.xtimms.etsudoku.core.database.dao.TagsDao
import org.xtimms.etsudoku.core.database.dao.TrackLogsDao
import org.xtimms.etsudoku.core.database.dao.TracksDao
import org.xtimms.etsudoku.core.database.entity.BookmarkEntity
import org.xtimms.etsudoku.core.database.entity.FavouriteCategoryEntity
import org.xtimms.etsudoku.core.database.entity.FavouriteEntity
import org.xtimms.etsudoku.core.database.entity.HistoryEntity
import org.xtimms.etsudoku.core.database.entity.MangaEntity
import org.xtimms.etsudoku.core.database.entity.MangaSourceEntity
import org.xtimms.etsudoku.core.database.entity.MangaTagsEntity
import org.xtimms.etsudoku.core.database.entity.SuggestionEntity
import org.xtimms.etsudoku.core.database.entity.TagEntity
import org.xtimms.etsudoku.core.database.entity.TrackEntity
import org.xtimms.etsudoku.core.database.entity.TrackLogEntity
import org.xtimms.etsudoku.utils.lang.processLifecycleScope
const val DATABASE_VERSION = 1
@ -51,7 +51,7 @@ const val DATABASE_VERSION = 1
],
version = DATABASE_VERSION
)
abstract class TokushoDatabase : RoomDatabase() {
abstract class EtsudokuDatabase : RoomDatabase() {
abstract fun getTagsDao(): TagsDao
@ -75,8 +75,8 @@ abstract class TokushoDatabase : RoomDatabase() {
}
fun TokushoDatabase(context: Context): TokushoDatabase = Room
.databaseBuilder(context, TokushoDatabase::class.java, "tokusho-db")
fun EtsudokuDatabase(context: Context): EtsudokuDatabase = Room
.databaseBuilder(context, EtsudokuDatabase::class.java, "etsudoku-db")
.addCallback(DatabasePrePopulateCallback(context.resources))
.build()

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.database
package org.xtimms.etsudoku.core.database
const val TABLE_MANGA = "manga"
const val TABLE_TAGS = "tags"

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.database.dao
package org.xtimms.etsudoku.core.database.dao
import androidx.room.Dao
import androidx.room.Delete
@ -7,8 +7,8 @@ import androidx.room.Query
import androidx.room.Transaction
import androidx.room.Upsert
import kotlinx.coroutines.flow.Flow
import org.xtimms.tokusho.core.database.entity.BookmarkEntity
import org.xtimms.tokusho.core.database.entity.MangaWithTags
import org.xtimms.etsudoku.core.database.entity.BookmarkEntity
import org.xtimms.etsudoku.core.database.entity.MangaWithTags
@Dao
abstract class BookmarksDao {

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.database.dao
package org.xtimms.etsudoku.core.database.dao
import androidx.room.Dao
import androidx.room.Insert
@ -6,7 +6,7 @@ import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Upsert
import kotlinx.coroutines.flow.Flow
import org.xtimms.tokusho.core.database.entity.FavouriteCategoryEntity
import org.xtimms.etsudoku.core.database.entity.FavouriteCategoryEntity
@Dao
abstract class FavouriteCategoriesDao {

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.database.dao
package org.xtimms.etsudoku.core.database.dao
import androidx.room.Dao
import androidx.room.Insert
@ -11,10 +11,10 @@ import androidx.sqlite.db.SimpleSQLiteQuery
import androidx.sqlite.db.SupportSQLiteQuery
import kotlinx.coroutines.flow.Flow
import org.intellij.lang.annotations.Language
import org.xtimms.tokusho.core.database.entity.FavouriteEntity
import org.xtimms.tokusho.core.database.entity.MangaEntity
import org.xtimms.tokusho.core.model.ListSortOrder
import org.xtimms.tokusho.sections.shelf.FavouriteManga
import org.xtimms.etsudoku.core.database.entity.FavouriteEntity
import org.xtimms.etsudoku.core.database.entity.MangaEntity
import org.xtimms.etsudoku.core.model.ListSortOrder
import org.xtimms.etsudoku.sections.shelf.FavouriteManga
@Dao
abstract class FavouritesDao {

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.database.dao
package org.xtimms.etsudoku.core.database.dao
import androidx.room.Dao
import androidx.room.Insert
@ -10,11 +10,11 @@ import androidx.sqlite.db.SimpleSQLiteQuery
import androidx.sqlite.db.SupportSQLiteQuery
import kotlinx.coroutines.flow.Flow
import org.intellij.lang.annotations.Language
import org.xtimms.tokusho.core.database.entity.HistoryEntity
import org.xtimms.tokusho.core.database.entity.HistoryWithManga
import org.xtimms.tokusho.core.database.entity.MangaEntity
import org.xtimms.tokusho.core.database.entity.TagEntity
import org.xtimms.tokusho.core.model.ListSortOrder
import org.xtimms.etsudoku.core.database.entity.HistoryEntity
import org.xtimms.etsudoku.core.database.entity.HistoryWithManga
import org.xtimms.etsudoku.core.database.entity.MangaEntity
import org.xtimms.etsudoku.core.database.entity.TagEntity
import org.xtimms.etsudoku.core.model.ListSortOrder
@Dao
abstract class HistoryDao {

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.database.dao
package org.xtimms.etsudoku.core.database.dao
import androidx.room.Dao
import androidx.room.Delete
@ -8,10 +8,10 @@ import androidx.room.Query
import androidx.room.Transaction
import androidx.room.Update
import androidx.room.Upsert
import org.xtimms.tokusho.core.database.entity.MangaEntity
import org.xtimms.tokusho.core.database.entity.MangaTagsEntity
import org.xtimms.tokusho.core.database.entity.MangaWithTags
import org.xtimms.tokusho.core.database.entity.TagEntity
import org.xtimms.etsudoku.core.database.entity.MangaEntity
import org.xtimms.etsudoku.core.database.entity.MangaTagsEntity
import org.xtimms.etsudoku.core.database.entity.MangaWithTags
import org.xtimms.etsudoku.core.database.entity.TagEntity
@Dao
abstract class MangaDao {

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.database.dao
package org.xtimms.etsudoku.core.database.dao
import androidx.room.Dao
import androidx.room.Query
@ -9,8 +9,8 @@ import androidx.sqlite.db.SimpleSQLiteQuery
import androidx.sqlite.db.SupportSQLiteQuery
import kotlinx.coroutines.flow.Flow
import org.intellij.lang.annotations.Language
import org.xtimms.tokusho.core.database.entity.MangaSourceEntity
import org.xtimms.tokusho.sections.explore.data.SourcesSortOrder
import org.xtimms.etsudoku.core.database.entity.MangaSourceEntity
import org.xtimms.etsudoku.sections.explore.data.SourcesSortOrder
@Dao
abstract class MangaSourcesDao {

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.database.dao
package org.xtimms.etsudoku.core.database.dao
import androidx.room.Dao
import androidx.room.Insert
@ -7,8 +7,8 @@ import androidx.room.Query
import androidx.room.Transaction
import androidx.room.Update
import kotlinx.coroutines.flow.Flow
import org.xtimms.tokusho.core.database.entity.SuggestionEntity
import org.xtimms.tokusho.core.database.entity.SuggestionWithManga
import org.xtimms.etsudoku.core.database.entity.SuggestionEntity
import org.xtimms.etsudoku.core.database.entity.SuggestionWithManga
@Dao
abstract class SuggestionDao {

@ -1,9 +1,9 @@
package org.xtimms.tokusho.core.database.dao
package org.xtimms.etsudoku.core.database.dao
import androidx.room.Dao
import androidx.room.Query
import androidx.room.Upsert
import org.xtimms.tokusho.core.database.entity.TagEntity
import org.xtimms.etsudoku.core.database.entity.TagEntity
@Dao
abstract class TagsDao {

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.database.dao
package org.xtimms.etsudoku.core.database.dao
import androidx.room.Dao
import androidx.room.Insert
@ -6,8 +6,8 @@ import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Transaction
import kotlinx.coroutines.flow.Flow
import org.xtimms.tokusho.core.database.entity.TrackLogEntity
import org.xtimms.tokusho.core.database.entity.TrackLogWithManga
import org.xtimms.etsudoku.core.database.entity.TrackLogEntity
import org.xtimms.etsudoku.core.database.entity.TrackLogWithManga
@Dao
interface TrackLogsDao {

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.database.dao
package org.xtimms.etsudoku.core.database.dao
import androidx.room.Dao
import androidx.room.MapColumn
@ -6,8 +6,8 @@ import androidx.room.Query
import androidx.room.Transaction
import androidx.room.Upsert
import kotlinx.coroutines.flow.Flow
import org.xtimms.tokusho.core.database.entity.MangaWithTags
import org.xtimms.tokusho.core.database.entity.TrackEntity
import org.xtimms.etsudoku.core.database.entity.MangaWithTags
import org.xtimms.etsudoku.core.database.entity.TrackEntity
@Dao
abstract class TracksDao {

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.database.entity
package org.xtimms.etsudoku.core.database.entity
import androidx.room.ColumnInfo
import androidx.room.Entity

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.database.entity
package org.xtimms.etsudoku.core.database.entity
import org.koitharu.kotatsu.parsers.model.Manga
import org.koitharu.kotatsu.parsers.model.MangaState
@ -6,14 +6,14 @@ import org.koitharu.kotatsu.parsers.model.MangaTag
import org.koitharu.kotatsu.parsers.model.SortOrder
import org.koitharu.kotatsu.parsers.util.mapToSet
import org.koitharu.kotatsu.parsers.util.toTitleCase
import org.xtimms.tokusho.core.model.Bookmark
import org.xtimms.tokusho.core.model.FavouriteCategory
import org.xtimms.tokusho.core.model.ListSortOrder
import org.xtimms.tokusho.core.model.MangaHistory
import org.xtimms.tokusho.core.model.MangaSource
import org.xtimms.tokusho.core.tracker.model.TrackingLogItem
import org.xtimms.tokusho.sections.shelf.FavouriteManga
import org.xtimms.tokusho.utils.lang.longHashCode
import org.xtimms.etsudoku.core.model.Bookmark
import org.xtimms.etsudoku.core.model.FavouriteCategory
import org.xtimms.etsudoku.core.model.ListSortOrder
import org.xtimms.etsudoku.core.model.MangaHistory
import org.xtimms.etsudoku.core.model.MangaSource
import org.xtimms.etsudoku.core.tracker.model.TrackingLogItem
import org.xtimms.etsudoku.sections.shelf.FavouriteManga
import org.xtimms.etsudoku.utils.lang.longHashCode
import java.time.Instant
// Entity to model

@ -1,9 +1,9 @@
package org.xtimms.tokusho.core.database.entity
package org.xtimms.etsudoku.core.database.entity
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import org.xtimms.tokusho.core.database.TABLE_FAVOURITE_CATEGORIES
import org.xtimms.etsudoku.core.database.TABLE_FAVOURITE_CATEGORIES
@Entity(tableName = TABLE_FAVOURITE_CATEGORIES)
data class FavouriteCategoryEntity(

@ -1,9 +1,9 @@
package org.xtimms.tokusho.core.database.entity
package org.xtimms.etsudoku.core.database.entity
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.ForeignKey
import org.xtimms.tokusho.core.database.TABLE_FAVOURITES
import org.xtimms.etsudoku.core.database.TABLE_FAVOURITES
@Entity(
tableName = TABLE_FAVOURITES,

@ -1,10 +1,10 @@
package org.xtimms.tokusho.core.database.entity
package org.xtimms.etsudoku.core.database.entity
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.PrimaryKey
import org.xtimms.tokusho.core.database.TABLE_HISTORY
import org.xtimms.etsudoku.core.database.TABLE_HISTORY
@Entity(
tableName = TABLE_HISTORY,

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.database.entity
package org.xtimms.etsudoku.core.database.entity
import androidx.room.Embedded
import androidx.room.Junction

@ -1,9 +1,9 @@
package org.xtimms.tokusho.core.database.entity
package org.xtimms.etsudoku.core.database.entity
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import org.xtimms.tokusho.core.database.TABLE_MANGA
import org.xtimms.etsudoku.core.database.TABLE_MANGA
@Entity(tableName = TABLE_MANGA)
data class MangaEntity(

@ -1,9 +1,9 @@
package org.xtimms.tokusho.core.database.entity
package org.xtimms.etsudoku.core.database.entity
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import org.xtimms.tokusho.core.database.TABLE_SOURCES
import org.xtimms.etsudoku.core.database.TABLE_SOURCES
@Entity(tableName = TABLE_SOURCES)
data class MangaSourceEntity(

@ -1,9 +1,9 @@
package org.xtimms.tokusho.core.database.entity
package org.xtimms.etsudoku.core.database.entity
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.ForeignKey
import org.xtimms.tokusho.core.database.TABLE_MANGA_TAGS
import org.xtimms.etsudoku.core.database.TABLE_MANGA_TAGS
@Entity(
tableName = TABLE_MANGA_TAGS,

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.database.entity
package org.xtimms.etsudoku.core.database.entity
import androidx.room.Embedded
import androidx.room.Junction

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.database.entity
package org.xtimms.etsudoku.core.database.entity
import androidx.annotation.FloatRange
import androidx.room.ColumnInfo

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.database.entity
package org.xtimms.etsudoku.core.database.entity
import androidx.room.Embedded
import androidx.room.Junction

@ -1,9 +1,9 @@
package org.xtimms.tokusho.core.database.entity
package org.xtimms.etsudoku.core.database.entity
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import org.xtimms.tokusho.core.database.TABLE_TAGS
import org.xtimms.etsudoku.core.database.TABLE_TAGS
@Entity(tableName = TABLE_TAGS)
data class TagEntity(

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.database.entity
package org.xtimms.etsudoku.core.database.entity
import androidx.room.ColumnInfo
import androidx.room.Entity

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.database.entity
package org.xtimms.etsudoku.core.database.entity
import androidx.room.ColumnInfo
import androidx.room.Entity

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.database.entity
package org.xtimms.etsudoku.core.database.entity
import androidx.room.Embedded
import androidx.room.Junction

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.exceptions
package org.xtimms.etsudoku.core.exceptions
import okhttp3.Headers
import okio.IOException

@ -0,0 +1,6 @@
package org.xtimms.etsudoku.core.exceptions
class SyncApiException(
message: String,
val code: Int,
) : RuntimeException(message)

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.exceptions
package org.xtimms.etsudoku.core.exceptions
import okio.IOException
import java.time.Instant

@ -1,4 +1,4 @@
package org.xtimms.tokusho.core.logs
package org.xtimms.etsudoku.core.logs
import android.content.Context
import androidx.annotation.WorkerThread
@ -14,9 +14,9 @@ import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withContext
import org.koitharu.kotatsu.parsers.util.runCatchingCancellable
import org.xtimms.tokusho.core.prefs.AppSettings
import org.xtimms.tokusho.utils.lang.processLifecycleScope
import org.xtimms.tokusho.utils.system.subdir
import org.xtimms.etsudoku.core.prefs.AppSettings
import org.xtimms.etsudoku.utils.lang.processLifecycleScope
import org.xtimms.etsudoku.utils.system.subdir
import java.io.File
import java.io.FileOutputStream
import java.time.LocalDateTime

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save