🚀 Full reformat of presentation and domain layers
* Implemented new custom Navigation based on Voyager * Bug fixes * Scrollbars for almost all screens * Better structure for screens * Smoother animations * Various small UI changes
This commit is contained in:
parent
85712cf566
commit
8ddb378f47
464 changed files with 12824 additions and 11768 deletions
|
|
@ -24,7 +24,7 @@
|
||||||
android:roundIcon="@mipmap/app_icon_round"
|
android:roundIcon="@mipmap/app_icon_round"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/Theme.Start.Splash"
|
android:theme="@style/Splash"
|
||||||
android:requestLegacyExternalStorage="true"
|
android:requestLegacyExternalStorage="true"
|
||||||
android:enableOnBackInvokedCallback="true"
|
android:enableOnBackInvokedCallback="true"
|
||||||
android:usesCleartextTraffic="false"
|
android:usesCleartextTraffic="false"
|
||||||
|
|
@ -33,11 +33,11 @@
|
||||||
tools:ignore="DataExtractionRules">
|
tools:ignore="DataExtractionRules">
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".Activity"
|
android:name=".ui.main.MainActivity"
|
||||||
android:windowSoftInputMode="adjustResize"
|
android:windowSoftInputMode="adjustResize"
|
||||||
android:configChanges="orientation|screenSize|screenLayout|smallestScreenSize|locale|density|uiMode"
|
android:configChanges="orientation|screenSize|screenLayout|smallestScreenSize|locale|density|uiMode"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:theme="@style/Theme.Start.Splash">
|
android:theme="@style/Splash">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
|
|
||||||
|
|
@ -1,224 +0,0 @@
|
||||||
package ua.acclorite.book_story
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.database.CursorWindow
|
|
||||||
import android.os.Bundle
|
|
||||||
import androidx.activity.compose.setContent
|
|
||||||
import androidx.activity.enableEdgeToEdge
|
|
||||||
import androidx.activity.viewModels
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
|
||||||
import androidx.compose.foundation.layout.WindowInsets
|
|
||||||
import androidx.compose.foundation.layout.ime
|
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
|
||||||
import androidx.compose.runtime.derivedStateOf
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.ui.platform.LocalDensity
|
|
||||||
import androidx.compose.ui.platform.LocalFocusManager
|
|
||||||
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
|
||||||
import androidx.core.view.WindowCompat
|
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
|
||||||
import ua.acclorite.book_story.presentation.core.components.navigation_bar.NavigationBar
|
|
||||||
import ua.acclorite.book_story.presentation.core.components.navigation_rail.NavigationRail
|
|
||||||
import ua.acclorite.book_story.presentation.core.navigation.NavigationHost
|
|
||||||
import ua.acclorite.book_story.presentation.core.navigation.Screen
|
|
||||||
import ua.acclorite.book_story.presentation.data.MainEvent
|
|
||||||
import ua.acclorite.book_story.presentation.data.MainViewModel
|
|
||||||
import ua.acclorite.book_story.presentation.screens.about.AboutScreenRoot
|
|
||||||
import ua.acclorite.book_story.presentation.screens.about.nested.credits.CreditsScreenRoot
|
|
||||||
import ua.acclorite.book_story.presentation.screens.about.nested.license_info.LicenseInfoScreenRoot
|
|
||||||
import ua.acclorite.book_story.presentation.screens.about.nested.licenses.LicensesScreenRoot
|
|
||||||
import ua.acclorite.book_story.presentation.screens.book_info.BookInfoScreenRoot
|
|
||||||
import ua.acclorite.book_story.presentation.screens.browse.BrowseScreenRoot
|
|
||||||
import ua.acclorite.book_story.presentation.screens.browse.data.BrowseViewModel
|
|
||||||
import ua.acclorite.book_story.presentation.screens.help.HelpScreenRoot
|
|
||||||
import ua.acclorite.book_story.presentation.screens.history.HistoryScreenRoot
|
|
||||||
import ua.acclorite.book_story.presentation.screens.history.data.HistoryViewModel
|
|
||||||
import ua.acclorite.book_story.presentation.screens.library.LibraryScreenRoot
|
|
||||||
import ua.acclorite.book_story.presentation.screens.library.data.LibraryViewModel
|
|
||||||
import ua.acclorite.book_story.presentation.screens.reader.ReaderScreenRoot
|
|
||||||
import ua.acclorite.book_story.presentation.screens.settings.SettingsScreenRoot
|
|
||||||
import ua.acclorite.book_story.presentation.screens.settings.data.SettingsViewModel
|
|
||||||
import ua.acclorite.book_story.presentation.screens.settings.nested.appearance.AppearanceSettingsRoot
|
|
||||||
import ua.acclorite.book_story.presentation.screens.settings.nested.browse.BrowseSettingsRoot
|
|
||||||
import ua.acclorite.book_story.presentation.screens.settings.nested.general.GeneralSettingsRoot
|
|
||||||
import ua.acclorite.book_story.presentation.screens.settings.nested.reader.ReaderSettingsRoot
|
|
||||||
import ua.acclorite.book_story.presentation.screens.start.StartScreenRoot
|
|
||||||
import ua.acclorite.book_story.presentation.ui.BookStoryTheme
|
|
||||||
import ua.acclorite.book_story.presentation.ui.Transitions
|
|
||||||
import ua.acclorite.book_story.presentation.ui.isDark
|
|
||||||
import ua.acclorite.book_story.presentation.ui.isPureDark
|
|
||||||
import java.lang.reflect.Field
|
|
||||||
|
|
||||||
|
|
||||||
@Suppress("unused")
|
|
||||||
@SuppressLint("DiscouragedPrivateApi")
|
|
||||||
@AndroidEntryPoint
|
|
||||||
class Activity : AppCompatActivity() {
|
|
||||||
// Initializing all required viewModels on app startup
|
|
||||||
private val mainViewModel: MainViewModel by viewModels()
|
|
||||||
private val libraryViewModel: LibraryViewModel by viewModels()
|
|
||||||
private val historyViewModel: HistoryViewModel by viewModels()
|
|
||||||
private val browseViewModel: BrowseViewModel by viewModels()
|
|
||||||
private val settingsViewModel: SettingsViewModel by viewModels()
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
|
||||||
super.onCreate(savedInstanceState)
|
|
||||||
|
|
||||||
// New Cursor size for Room
|
|
||||||
try {
|
|
||||||
val field: Field = CursorWindow::class.java.getDeclaredField("sCursorWindowSize")
|
|
||||||
field.isAccessible = true
|
|
||||||
field.set(null, 100 * 1024 * 1024)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initializing all variables
|
|
||||||
mainViewModel.onEvent(
|
|
||||||
MainEvent.OnInit(
|
|
||||||
libraryViewModelReady = libraryViewModel.isReady,
|
|
||||||
settingsViewModelReady = settingsViewModel.isReady
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
// Splash screen
|
|
||||||
installSplashScreen().apply {
|
|
||||||
setKeepOnScreenCondition {
|
|
||||||
!mainViewModel.isReady.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Edge to edge
|
|
||||||
enableEdgeToEdge()
|
|
||||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
|
||||||
|
|
||||||
setContent {
|
|
||||||
val state = MainViewModel.getState()
|
|
||||||
val isLoaded = mainViewModel.isReady.collectAsStateWithLifecycle()
|
|
||||||
|
|
||||||
val density = LocalDensity.current
|
|
||||||
val imeInsets = WindowInsets.ime
|
|
||||||
val focusManager = LocalFocusManager.current
|
|
||||||
val isKeyboardVisible by remember {
|
|
||||||
derivedStateOf {
|
|
||||||
imeInsets.getBottom(density) > 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LaunchedEffect(isKeyboardVisible) {
|
|
||||||
if (!isKeyboardVisible) {
|
|
||||||
focusManager.clearFocus()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isLoaded.value) {
|
|
||||||
BookStoryTheme(
|
|
||||||
theme = state.value.theme,
|
|
||||||
isDark = state.value.darkTheme.isDark(),
|
|
||||||
isPureDark = state.value.pureDark.isPureDark(this),
|
|
||||||
themeContrast = state.value.themeContrast
|
|
||||||
) {
|
|
||||||
NavigationHost(
|
|
||||||
startScreen = if (state.value.showStartScreen) Screen.Start
|
|
||||||
else Screen.Library
|
|
||||||
) {
|
|
||||||
navigation(
|
|
||||||
screens = arrayOf(
|
|
||||||
Screen.Library.getRoute(),
|
|
||||||
Screen.History.getRoute(),
|
|
||||||
Screen.Browse.getRoute()
|
|
||||||
),
|
|
||||||
bottomBar = {
|
|
||||||
NavigationBar()
|
|
||||||
},
|
|
||||||
navigationRail = {
|
|
||||||
NavigationRail()
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
// Library
|
|
||||||
composable<Screen.Library>(
|
|
||||||
enterAnim = Transitions.FadeTransitionIn,
|
|
||||||
exitAnim = Transitions.FadeTransitionOut
|
|
||||||
) {
|
|
||||||
LibraryScreenRoot()
|
|
||||||
}
|
|
||||||
|
|
||||||
// History
|
|
||||||
composable<Screen.History>(
|
|
||||||
enterAnim = Transitions.FadeTransitionIn,
|
|
||||||
exitAnim = Transitions.FadeTransitionOut
|
|
||||||
) {
|
|
||||||
HistoryScreenRoot()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Browse
|
|
||||||
composable<Screen.Browse>(
|
|
||||||
enterAnim = Transitions.FadeTransitionIn,
|
|
||||||
exitAnim = Transitions.FadeTransitionOut
|
|
||||||
) {
|
|
||||||
BrowseScreenRoot()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Book Info
|
|
||||||
composable<Screen.BookInfo> {
|
|
||||||
BookInfoScreenRoot(it)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reader
|
|
||||||
composable<Screen.Reader> {
|
|
||||||
ReaderScreenRoot(it)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Settings
|
|
||||||
composable<Screen.Settings> {
|
|
||||||
SettingsScreenRoot()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Nested settings categories
|
|
||||||
composable<Screen.Settings.General> {
|
|
||||||
GeneralSettingsRoot()
|
|
||||||
}
|
|
||||||
composable<Screen.Settings.Appearance> {
|
|
||||||
AppearanceSettingsRoot()
|
|
||||||
}
|
|
||||||
composable<Screen.Settings.ReaderSettings> {
|
|
||||||
ReaderSettingsRoot()
|
|
||||||
}
|
|
||||||
composable<Screen.Settings.BrowseSettings> {
|
|
||||||
BrowseSettingsRoot()
|
|
||||||
}
|
|
||||||
|
|
||||||
// About screen
|
|
||||||
composable<Screen.About> {
|
|
||||||
AboutScreenRoot()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Nested about categories
|
|
||||||
composable<Screen.About.Licenses> {
|
|
||||||
LicensesScreenRoot()
|
|
||||||
}
|
|
||||||
composable<Screen.About.LicenseInfo> {
|
|
||||||
LicenseInfoScreenRoot(it)
|
|
||||||
}
|
|
||||||
composable<Screen.About.Credits> {
|
|
||||||
CreditsScreenRoot()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Help screen
|
|
||||||
composable<Screen.Help> {
|
|
||||||
HelpScreenRoot(it)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start screen
|
|
||||||
composable<Screen.Start>(enterAnim = Transitions.FadeTransitionIn) {
|
|
||||||
StartScreenRoot()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -4,7 +4,7 @@ import androidx.room.TypeConverter
|
||||||
import com.google.common.reflect.TypeToken
|
import com.google.common.reflect.TypeToken
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import com.google.gson.JsonSyntaxException
|
import com.google.gson.JsonSyntaxException
|
||||||
import ua.acclorite.book_story.domain.model.Chapter
|
import ua.acclorite.book_story.domain.reader.Chapter
|
||||||
|
|
||||||
class ChapterConverter {
|
class ChapterConverter {
|
||||||
@TypeConverter
|
@TypeConverter
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ import androidx.room.Entity
|
||||||
import androidx.room.PrimaryKey
|
import androidx.room.PrimaryKey
|
||||||
import androidx.room.TypeConverters
|
import androidx.room.TypeConverters
|
||||||
import ua.acclorite.book_story.data.local.converter.ChapterConverter
|
import ua.acclorite.book_story.data.local.converter.ChapterConverter
|
||||||
import ua.acclorite.book_story.domain.model.Category
|
import ua.acclorite.book_story.domain.library.category.Category
|
||||||
import ua.acclorite.book_story.domain.model.Chapter
|
import ua.acclorite.book_story.domain.reader.Chapter
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@TypeConverters(ChapterConverter::class)
|
@TypeConverters(ChapterConverter::class)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package ua.acclorite.book_story.data.mapper.book
|
package ua.acclorite.book_story.data.mapper.book
|
||||||
|
|
||||||
import ua.acclorite.book_story.data.local.dto.BookEntity
|
import ua.acclorite.book_story.data.local.dto.BookEntity
|
||||||
import ua.acclorite.book_story.domain.model.Book
|
import ua.acclorite.book_story.domain.library.book.Book
|
||||||
|
|
||||||
interface BookMapper {
|
interface BookMapper {
|
||||||
suspend fun toBookEntity(book: Book): BookEntity
|
suspend fun toBookEntity(book: Book): BookEntity
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@ package ua.acclorite.book_story.data.mapper.book
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.data.local.dto.BookEntity
|
import ua.acclorite.book_story.data.local.dto.BookEntity
|
||||||
import ua.acclorite.book_story.domain.model.Book
|
import ua.acclorite.book_story.domain.library.book.Book
|
||||||
import ua.acclorite.book_story.domain.util.UIText
|
import ua.acclorite.book_story.domain.ui.UIText
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class BookMapperImpl @Inject constructor() : BookMapper {
|
class BookMapperImpl @Inject constructor() : BookMapper {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package ua.acclorite.book_story.data.mapper.color_preset
|
package ua.acclorite.book_story.data.mapper.color_preset
|
||||||
|
|
||||||
import ua.acclorite.book_story.data.local.dto.ColorPresetEntity
|
import ua.acclorite.book_story.data.local.dto.ColorPresetEntity
|
||||||
import ua.acclorite.book_story.domain.model.ColorPreset
|
import ua.acclorite.book_story.domain.reader.ColorPreset
|
||||||
|
|
||||||
interface ColorPresetMapper {
|
interface ColorPresetMapper {
|
||||||
suspend fun toColorPresetEntity(colorPreset: ColorPreset, order: Int): ColorPresetEntity
|
suspend fun toColorPresetEntity(colorPreset: ColorPreset, order: Int): ColorPresetEntity
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package ua.acclorite.book_story.data.mapper.color_preset
|
||||||
|
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import ua.acclorite.book_story.data.local.dto.ColorPresetEntity
|
import ua.acclorite.book_story.data.local.dto.ColorPresetEntity
|
||||||
import ua.acclorite.book_story.domain.model.ColorPreset
|
import ua.acclorite.book_story.domain.reader.ColorPreset
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class ColorPresetMapperImpl @Inject constructor() : ColorPresetMapper {
|
class ColorPresetMapperImpl @Inject constructor() : ColorPresetMapper {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package ua.acclorite.book_story.data.mapper.history
|
package ua.acclorite.book_story.data.mapper.history
|
||||||
|
|
||||||
import ua.acclorite.book_story.data.local.dto.HistoryEntity
|
import ua.acclorite.book_story.data.local.dto.HistoryEntity
|
||||||
import ua.acclorite.book_story.domain.model.History
|
import ua.acclorite.book_story.domain.history.History
|
||||||
|
|
||||||
interface HistoryMapper {
|
interface HistoryMapper {
|
||||||
suspend fun toHistoryEntity(history: History): HistoryEntity
|
suspend fun toHistoryEntity(history: History): HistoryEntity
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package ua.acclorite.book_story.data.mapper.history
|
package ua.acclorite.book_story.data.mapper.history
|
||||||
|
|
||||||
import ua.acclorite.book_story.data.local.dto.HistoryEntity
|
import ua.acclorite.book_story.data.local.dto.HistoryEntity
|
||||||
import ua.acclorite.book_story.domain.model.History
|
import ua.acclorite.book_story.domain.history.History
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class HistoryMapperImpl @Inject constructor() : HistoryMapper {
|
class HistoryMapperImpl @Inject constructor() : HistoryMapper {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package ua.acclorite.book_story.data.parser
|
package ua.acclorite.book_story.data.parser
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.model.BookWithCover
|
import ua.acclorite.book_story.domain.library.book.BookWithCover
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import ua.acclorite.book_story.data.parser.fb2.Fb2FileParser
|
||||||
import ua.acclorite.book_story.data.parser.html.HtmlFileParser
|
import ua.acclorite.book_story.data.parser.html.HtmlFileParser
|
||||||
import ua.acclorite.book_story.data.parser.pdf.PdfFileParser
|
import ua.acclorite.book_story.data.parser.pdf.PdfFileParser
|
||||||
import ua.acclorite.book_story.data.parser.txt.TxtFileParser
|
import ua.acclorite.book_story.data.parser.txt.TxtFileParser
|
||||||
import ua.acclorite.book_story.domain.model.BookWithCover
|
import ua.acclorite.book_story.domain.library.book.BookWithCover
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package ua.acclorite.book_story.data.parser
|
package ua.acclorite.book_story.data.parser
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.model.ChapterWithText
|
import ua.acclorite.book_story.domain.reader.ChapterWithText
|
||||||
import ua.acclorite.book_story.domain.util.Resource
|
import ua.acclorite.book_story.domain.util.Resource
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,9 @@ import ua.acclorite.book_story.data.parser.fb2.Fb2TextParser
|
||||||
import ua.acclorite.book_story.data.parser.html.HtmlTextParser
|
import ua.acclorite.book_story.data.parser.html.HtmlTextParser
|
||||||
import ua.acclorite.book_story.data.parser.pdf.PdfTextParser
|
import ua.acclorite.book_story.data.parser.pdf.PdfTextParser
|
||||||
import ua.acclorite.book_story.data.parser.txt.TxtTextParser
|
import ua.acclorite.book_story.data.parser.txt.TxtTextParser
|
||||||
import ua.acclorite.book_story.domain.model.ChapterWithText
|
import ua.acclorite.book_story.domain.reader.ChapterWithText
|
||||||
|
import ua.acclorite.book_story.domain.ui.UIText
|
||||||
import ua.acclorite.book_story.domain.util.Resource
|
import ua.acclorite.book_story.domain.util.Resource
|
||||||
import ua.acclorite.book_story.domain.util.UIText
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
@ -71,11 +71,3 @@ class TextParserImpl @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,10 @@ import kotlinx.coroutines.withContext
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.data.parser.FileParser
|
import ua.acclorite.book_story.data.parser.FileParser
|
||||||
import ua.acclorite.book_story.domain.model.Book
|
import ua.acclorite.book_story.domain.library.book.Book
|
||||||
import ua.acclorite.book_story.domain.model.BookWithCover
|
import ua.acclorite.book_story.domain.library.book.BookWithCover
|
||||||
import ua.acclorite.book_story.domain.model.Category
|
import ua.acclorite.book_story.domain.library.category.Category
|
||||||
import ua.acclorite.book_story.domain.util.UIText
|
import ua.acclorite.book_story.domain.ui.UIText
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.zip.ZipFile
|
import java.util.zip.ZipFile
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
|
||||||
|
|
@ -15,10 +15,10 @@ import org.jsoup.Jsoup
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.data.parser.DocumentParser
|
import ua.acclorite.book_story.data.parser.DocumentParser
|
||||||
import ua.acclorite.book_story.data.parser.TextParser
|
import ua.acclorite.book_story.data.parser.TextParser
|
||||||
import ua.acclorite.book_story.domain.model.Chapter
|
import ua.acclorite.book_story.domain.reader.Chapter
|
||||||
import ua.acclorite.book_story.domain.model.ChapterWithText
|
import ua.acclorite.book_story.domain.reader.ChapterWithText
|
||||||
|
import ua.acclorite.book_story.domain.ui.UIText
|
||||||
import ua.acclorite.book_story.domain.util.Resource
|
import ua.acclorite.book_story.domain.util.Resource
|
||||||
import ua.acclorite.book_story.domain.util.UIText
|
|
||||||
import ua.acclorite.book_story.presentation.core.util.addAll
|
import ua.acclorite.book_story.presentation.core.util.addAll
|
||||||
import ua.acclorite.book_story.presentation.core.util.clearMarkdown
|
import ua.acclorite.book_story.presentation.core.util.clearMarkdown
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,10 @@ import org.w3c.dom.Document
|
||||||
import org.w3c.dom.Element
|
import org.w3c.dom.Element
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.data.parser.FileParser
|
import ua.acclorite.book_story.data.parser.FileParser
|
||||||
import ua.acclorite.book_story.domain.model.Book
|
import ua.acclorite.book_story.domain.library.book.Book
|
||||||
import ua.acclorite.book_story.domain.model.BookWithCover
|
import ua.acclorite.book_story.domain.library.book.BookWithCover
|
||||||
import ua.acclorite.book_story.domain.model.Category
|
import ua.acclorite.book_story.domain.library.category.Category
|
||||||
import ua.acclorite.book_story.domain.util.UIText
|
import ua.acclorite.book_story.domain.ui.UIText
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.xml.parsers.DocumentBuilderFactory
|
import javax.xml.parsers.DocumentBuilderFactory
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,10 @@ import org.w3c.dom.Element
|
||||||
import org.w3c.dom.NodeList
|
import org.w3c.dom.NodeList
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.data.parser.TextParser
|
import ua.acclorite.book_story.data.parser.TextParser
|
||||||
import ua.acclorite.book_story.domain.model.Chapter
|
import ua.acclorite.book_story.domain.reader.Chapter
|
||||||
import ua.acclorite.book_story.domain.model.ChapterWithText
|
import ua.acclorite.book_story.domain.reader.ChapterWithText
|
||||||
|
import ua.acclorite.book_story.domain.ui.UIText
|
||||||
import ua.acclorite.book_story.domain.util.Resource
|
import ua.acclorite.book_story.domain.util.Resource
|
||||||
import ua.acclorite.book_story.domain.util.UIText
|
|
||||||
import ua.acclorite.book_story.presentation.core.util.clearAllMarkdown
|
import ua.acclorite.book_story.presentation.core.util.clearAllMarkdown
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,10 @@ package ua.acclorite.book_story.data.parser.html
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.data.parser.FileParser
|
import ua.acclorite.book_story.data.parser.FileParser
|
||||||
import ua.acclorite.book_story.domain.model.Book
|
import ua.acclorite.book_story.domain.library.book.Book
|
||||||
import ua.acclorite.book_story.domain.model.BookWithCover
|
import ua.acclorite.book_story.domain.library.book.BookWithCover
|
||||||
import ua.acclorite.book_story.domain.model.Category
|
import ua.acclorite.book_story.domain.library.category.Category
|
||||||
import ua.acclorite.book_story.domain.util.UIText
|
import ua.acclorite.book_story.domain.ui.UIText
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,10 @@ import org.jsoup.Jsoup
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.data.parser.DocumentParser
|
import ua.acclorite.book_story.data.parser.DocumentParser
|
||||||
import ua.acclorite.book_story.data.parser.TextParser
|
import ua.acclorite.book_story.data.parser.TextParser
|
||||||
import ua.acclorite.book_story.domain.model.Chapter
|
import ua.acclorite.book_story.domain.reader.Chapter
|
||||||
import ua.acclorite.book_story.domain.model.ChapterWithText
|
import ua.acclorite.book_story.domain.reader.ChapterWithText
|
||||||
|
import ua.acclorite.book_story.domain.ui.UIText
|
||||||
import ua.acclorite.book_story.domain.util.Resource
|
import ua.acclorite.book_story.domain.util.Resource
|
||||||
import ua.acclorite.book_story.domain.util.UIText
|
|
||||||
import ua.acclorite.book_story.presentation.core.util.clearAllMarkdown
|
import ua.acclorite.book_story.presentation.core.util.clearAllMarkdown
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,10 @@ import com.tom_roush.pdfbox.android.PDFBoxResourceLoader
|
||||||
import com.tom_roush.pdfbox.pdmodel.PDDocument
|
import com.tom_roush.pdfbox.pdmodel.PDDocument
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.data.parser.FileParser
|
import ua.acclorite.book_story.data.parser.FileParser
|
||||||
import ua.acclorite.book_story.domain.model.Book
|
import ua.acclorite.book_story.domain.library.book.Book
|
||||||
import ua.acclorite.book_story.domain.model.BookWithCover
|
import ua.acclorite.book_story.domain.library.book.BookWithCover
|
||||||
import ua.acclorite.book_story.domain.model.Category
|
import ua.acclorite.book_story.domain.library.category.Category
|
||||||
import ua.acclorite.book_story.domain.util.UIText
|
import ua.acclorite.book_story.domain.ui.UIText
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
@ -27,7 +27,7 @@ class PdfFileParser @Inject constructor(
|
||||||
if (isNullOrBlank()) UIText.StringResource(R.string.unknown_author)
|
if (isNullOrBlank()) UIText.StringResource(R.string.unknown_author)
|
||||||
else UIText.StringValue(this)
|
else UIText.StringValue(this)
|
||||||
}
|
}
|
||||||
val description = document.documentInformation.subject ?: null
|
val description = document.documentInformation.subject
|
||||||
|
|
||||||
document.close()
|
document.close()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,10 @@ import com.tom_roush.pdfbox.text.PDFTextStripper
|
||||||
import kotlinx.coroutines.yield
|
import kotlinx.coroutines.yield
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.data.parser.TextParser
|
import ua.acclorite.book_story.data.parser.TextParser
|
||||||
import ua.acclorite.book_story.domain.model.Chapter
|
import ua.acclorite.book_story.domain.reader.Chapter
|
||||||
import ua.acclorite.book_story.domain.model.ChapterWithText
|
import ua.acclorite.book_story.domain.reader.ChapterWithText
|
||||||
|
import ua.acclorite.book_story.domain.ui.UIText
|
||||||
import ua.acclorite.book_story.domain.util.Resource
|
import ua.acclorite.book_story.domain.util.Resource
|
||||||
import ua.acclorite.book_story.domain.util.UIText
|
|
||||||
import ua.acclorite.book_story.presentation.core.util.clearAllMarkdown
|
import ua.acclorite.book_story.presentation.core.util.clearAllMarkdown
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,10 @@ package ua.acclorite.book_story.data.parser.txt
|
||||||
|
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.data.parser.FileParser
|
import ua.acclorite.book_story.data.parser.FileParser
|
||||||
import ua.acclorite.book_story.domain.model.Book
|
import ua.acclorite.book_story.domain.library.book.Book
|
||||||
import ua.acclorite.book_story.domain.model.BookWithCover
|
import ua.acclorite.book_story.domain.library.book.BookWithCover
|
||||||
import ua.acclorite.book_story.domain.model.Category
|
import ua.acclorite.book_story.domain.library.category.Category
|
||||||
import ua.acclorite.book_story.domain.util.UIText
|
import ua.acclorite.book_story.domain.ui.UIText
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,10 @@ import kotlinx.coroutines.withContext
|
||||||
import kotlinx.coroutines.yield
|
import kotlinx.coroutines.yield
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.data.parser.TextParser
|
import ua.acclorite.book_story.data.parser.TextParser
|
||||||
import ua.acclorite.book_story.domain.model.Chapter
|
import ua.acclorite.book_story.domain.reader.Chapter
|
||||||
import ua.acclorite.book_story.domain.model.ChapterWithText
|
import ua.acclorite.book_story.domain.reader.ChapterWithText
|
||||||
|
import ua.acclorite.book_story.domain.ui.UIText
|
||||||
import ua.acclorite.book_story.domain.util.Resource
|
import ua.acclorite.book_story.domain.util.Resource
|
||||||
import ua.acclorite.book_story.domain.util.UIText
|
|
||||||
import ua.acclorite.book_story.presentation.core.util.clearAllMarkdown
|
import ua.acclorite.book_story.presentation.core.util.clearAllMarkdown
|
||||||
import java.io.BufferedReader
|
import java.io.BufferedReader
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
|
||||||
|
|
@ -16,14 +16,14 @@ import ua.acclorite.book_story.data.mapper.book.BookMapper
|
||||||
import ua.acclorite.book_story.data.parser.FileParser
|
import ua.acclorite.book_story.data.parser.FileParser
|
||||||
import ua.acclorite.book_story.data.parser.MarkdownParser
|
import ua.acclorite.book_story.data.parser.MarkdownParser
|
||||||
import ua.acclorite.book_story.data.parser.TextParser
|
import ua.acclorite.book_story.data.parser.TextParser
|
||||||
import ua.acclorite.book_story.domain.model.Book
|
import ua.acclorite.book_story.domain.library.book.Book
|
||||||
import ua.acclorite.book_story.domain.model.BookWithText
|
import ua.acclorite.book_story.domain.library.book.BookWithText
|
||||||
import ua.acclorite.book_story.domain.model.BookWithTextAndCover
|
import ua.acclorite.book_story.domain.library.book.BookWithTextAndCover
|
||||||
import ua.acclorite.book_story.domain.model.Chapter
|
import ua.acclorite.book_story.domain.reader.Chapter
|
||||||
import ua.acclorite.book_story.domain.repository.BookRepository
|
import ua.acclorite.book_story.domain.repository.BookRepository
|
||||||
|
import ua.acclorite.book_story.domain.ui.UIText
|
||||||
import ua.acclorite.book_story.domain.util.CoverImage
|
import ua.acclorite.book_story.domain.util.CoverImage
|
||||||
import ua.acclorite.book_story.domain.util.Resource
|
import ua.acclorite.book_story.domain.util.Resource
|
||||||
import ua.acclorite.book_story.domain.util.UIText
|
|
||||||
import java.io.BufferedReader
|
import java.io.BufferedReader
|
||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package ua.acclorite.book_story.data.repository
|
||||||
|
|
||||||
import ua.acclorite.book_story.data.local.room.BookDao
|
import ua.acclorite.book_story.data.local.room.BookDao
|
||||||
import ua.acclorite.book_story.data.mapper.color_preset.ColorPresetMapper
|
import ua.acclorite.book_story.data.mapper.color_preset.ColorPresetMapper
|
||||||
import ua.acclorite.book_story.domain.model.ColorPreset
|
import ua.acclorite.book_story.domain.reader.ColorPreset
|
||||||
import ua.acclorite.book_story.domain.repository.ColorPresetRepository
|
import ua.acclorite.book_story.domain.repository.ColorPresetRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import kotlinx.coroutines.awaitAll
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import ua.acclorite.book_story.data.local.data_store.DataStore
|
import ua.acclorite.book_story.data.local.data_store.DataStore
|
||||||
import ua.acclorite.book_story.domain.repository.DataStoreRepository
|
import ua.acclorite.book_story.domain.repository.DataStoreRepository
|
||||||
import ua.acclorite.book_story.presentation.data.MainState
|
import ua.acclorite.book_story.ui.main.MainState
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
|
||||||
|
|
@ -7,14 +7,14 @@ import ua.acclorite.book_story.data.local.room.BookDao
|
||||||
import ua.acclorite.book_story.data.mapper.book.BookMapper
|
import ua.acclorite.book_story.data.mapper.book.BookMapper
|
||||||
import ua.acclorite.book_story.data.parser.FileParser
|
import ua.acclorite.book_story.data.parser.FileParser
|
||||||
import ua.acclorite.book_story.data.parser.TextParser
|
import ua.acclorite.book_story.data.parser.TextParser
|
||||||
import ua.acclorite.book_story.domain.model.BookWithTextAndCover
|
import ua.acclorite.book_story.domain.browse.SelectableFile
|
||||||
import ua.acclorite.book_story.domain.model.NullableBook
|
import ua.acclorite.book_story.domain.library.book.BookWithTextAndCover
|
||||||
import ua.acclorite.book_story.domain.model.NullableBook.NotNull
|
import ua.acclorite.book_story.domain.library.book.NullableBook
|
||||||
import ua.acclorite.book_story.domain.model.NullableBook.Null
|
import ua.acclorite.book_story.domain.library.book.NullableBook.NotNull
|
||||||
import ua.acclorite.book_story.domain.model.SelectableFile
|
import ua.acclorite.book_story.domain.library.book.NullableBook.Null
|
||||||
import ua.acclorite.book_story.domain.repository.FileSystemRepository
|
import ua.acclorite.book_story.domain.repository.FileSystemRepository
|
||||||
|
import ua.acclorite.book_story.domain.ui.UIText
|
||||||
import ua.acclorite.book_story.domain.util.Resource
|
import ua.acclorite.book_story.domain.util.Resource
|
||||||
import ua.acclorite.book_story.domain.util.UIText
|
|
||||||
import ua.acclorite.book_story.presentation.core.constants.Constants
|
import ua.acclorite.book_story.presentation.core.constants.Constants
|
||||||
import ua.acclorite.book_story.presentation.core.constants.provideSupportedExtensions
|
import ua.acclorite.book_story.presentation.core.constants.provideSupportedExtensions
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package ua.acclorite.book_story.data.repository
|
||||||
|
|
||||||
import ua.acclorite.book_story.data.local.room.BookDao
|
import ua.acclorite.book_story.data.local.room.BookDao
|
||||||
import ua.acclorite.book_story.data.mapper.history.HistoryMapper
|
import ua.acclorite.book_story.data.mapper.history.HistoryMapper
|
||||||
import ua.acclorite.book_story.domain.model.History
|
import ua.acclorite.book_story.domain.history.History
|
||||||
import ua.acclorite.book_story.domain.repository.HistoryRepository
|
import ua.acclorite.book_story.domain.repository.HistoryRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.domain.model
|
package ua.acclorite.book_story.domain.about
|
||||||
|
|
||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package ua.acclorite.book_story.domain.model
|
package ua.acclorite.book_story.domain.about
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import ua.acclorite.book_story.domain.util.UIText
|
import ua.acclorite.book_story.domain.ui.UIText
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
data class Credit(
|
data class Credit(
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.presentation.screens.settings.nested.browse.data
|
package ua.acclorite.book_story.domain.browse
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.presentation.screens.settings.nested.browse.data
|
package ua.acclorite.book_story.domain.browse
|
||||||
|
|
||||||
enum class BrowseLayout {
|
enum class BrowseLayout {
|
||||||
LIST, GRID
|
LIST, GRID
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.presentation.screens.settings.nested.browse.data
|
package ua.acclorite.book_story.domain.browse
|
||||||
|
|
||||||
enum class BrowseSortOrder {
|
enum class BrowseSortOrder {
|
||||||
NAME,
|
NAME,
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
package ua.acclorite.book_story.domain.browse
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
|
import ua.acclorite.book_story.domain.ui.UIText
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
data class FileWithTitle(
|
||||||
|
val title: UIText,
|
||||||
|
val file: File
|
||||||
|
)
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.domain.model
|
package ua.acclorite.book_story.domain.browse
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import ua.acclorite.book_story.domain.util.Selected
|
import ua.acclorite.book_story.domain.util.Selected
|
||||||
|
|
@ -1,13 +1,12 @@
|
||||||
package ua.acclorite.book_story.domain.model
|
package ua.acclorite.book_story.domain.help
|
||||||
|
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import androidx.compose.ui.text.AnnotatedString
|
import androidx.compose.ui.text.AnnotatedString
|
||||||
import ua.acclorite.book_story.domain.util.OnNavigate
|
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
data class HelpTip(
|
data class HelpTip(
|
||||||
@StringRes val title: Int,
|
@StringRes val title: Int,
|
||||||
val description: @Composable AnnotatedString.Builder.(onNavigate: OnNavigate, fromStart: Boolean) -> Unit
|
val description: @Composable AnnotatedString.Builder.() -> Unit
|
||||||
)
|
)
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.domain.model
|
package ua.acclorite.book_story.domain.history
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package ua.acclorite.book_story.domain.model
|
package ua.acclorite.book_story.domain.history
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
|
import ua.acclorite.book_story.domain.library.book.Book
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
data class History(
|
data class History(
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
package ua.acclorite.book_story.domain.library.book
|
||||||
|
|
||||||
|
import android.net.Uri
|
||||||
|
import android.os.Parcelable
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
|
import kotlinx.parcelize.Parcelize
|
||||||
|
import ua.acclorite.book_story.domain.library.category.Category
|
||||||
|
import ua.acclorite.book_story.domain.reader.Chapter
|
||||||
|
import ua.acclorite.book_story.domain.ui.UIText
|
||||||
|
|
||||||
|
@Parcelize
|
||||||
|
@Immutable
|
||||||
|
data class Book(
|
||||||
|
val id: Int = 0,
|
||||||
|
|
||||||
|
val title: String,
|
||||||
|
val author: UIText,
|
||||||
|
val description: String?,
|
||||||
|
|
||||||
|
val textPath: String,
|
||||||
|
val filePath: String,
|
||||||
|
val coverImage: Uri?,
|
||||||
|
|
||||||
|
val scrollIndex: Int,
|
||||||
|
val scrollOffset: Int,
|
||||||
|
val progress: Float,
|
||||||
|
val chapters: List<Chapter> = emptyList(),
|
||||||
|
|
||||||
|
val lastOpened: Long?,
|
||||||
|
val category: Category,
|
||||||
|
) : Parcelable
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
package ua.acclorite.book_story.domain.library.book
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
|
import ua.acclorite.book_story.domain.util.CoverImage
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
data class BookWithCover(
|
||||||
|
val book: Book,
|
||||||
|
val coverImage: CoverImage?
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
package ua.acclorite.book_story.domain.library.book
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
data class BookWithText(
|
||||||
|
val book: Book,
|
||||||
|
val text: List<String>
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
package ua.acclorite.book_story.domain.library.book
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
|
import ua.acclorite.book_story.domain.util.CoverImage
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
data class BookWithTextAndCover(
|
||||||
|
val book: Book,
|
||||||
|
val coverImage: CoverImage?,
|
||||||
|
val text: List<String>
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
package ua.acclorite.book_story.domain.library.book
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
|
import ua.acclorite.book_story.domain.ui.UIText
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
sealed class NullableBook(
|
||||||
|
val bookWithTextAndCover: BookWithTextAndCover?,
|
||||||
|
val fileName: String?,
|
||||||
|
val message: UIText?
|
||||||
|
) {
|
||||||
|
class NotNull(
|
||||||
|
bookWithTextAndCover: BookWithTextAndCover
|
||||||
|
) : NullableBook(
|
||||||
|
bookWithTextAndCover = bookWithTextAndCover,
|
||||||
|
fileName = null,
|
||||||
|
message = null
|
||||||
|
)
|
||||||
|
|
||||||
|
class Null(
|
||||||
|
fileName: String,
|
||||||
|
message: UIText?
|
||||||
|
) : NullableBook(
|
||||||
|
bookWithTextAndCover = null,
|
||||||
|
fileName = fileName,
|
||||||
|
message = message
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
package ua.acclorite.book_story.domain.library.book
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
|
import ua.acclorite.book_story.domain.util.Selected
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
data class SelectableBook(
|
||||||
|
val data: Book,
|
||||||
|
val selected: Selected
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
package ua.acclorite.book_story.domain.library.book
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
|
import ua.acclorite.book_story.domain.util.Selected
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
data class SelectableNullableBook(
|
||||||
|
val data: NullableBook,
|
||||||
|
val selected: Selected
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
package ua.acclorite.book_story.domain.library.category
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
enum class Category {
|
||||||
|
READING,
|
||||||
|
ALREADY_READ,
|
||||||
|
PLANNING,
|
||||||
|
DROPPED
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
package ua.acclorite.book_story.domain.library.category
|
||||||
|
|
||||||
|
import ua.acclorite.book_story.domain.library.book.SelectableBook
|
||||||
|
import ua.acclorite.book_story.domain.ui.UIText
|
||||||
|
|
||||||
|
data class CategoryWithBooks(
|
||||||
|
val category: Category,
|
||||||
|
val title: UIText,
|
||||||
|
val books: List<SelectableBook>
|
||||||
|
)
|
||||||
|
|
@ -1,70 +0,0 @@
|
||||||
package ua.acclorite.book_story.domain.model
|
|
||||||
|
|
||||||
import android.net.Uri
|
|
||||||
import androidx.compose.runtime.Immutable
|
|
||||||
import ua.acclorite.book_story.domain.util.CoverImage
|
|
||||||
import ua.acclorite.book_story.domain.util.UIText
|
|
||||||
|
|
||||||
@Immutable
|
|
||||||
data class Book(
|
|
||||||
val id: Int = 0,
|
|
||||||
|
|
||||||
val title: String,
|
|
||||||
val author: UIText,
|
|
||||||
val description: String?,
|
|
||||||
|
|
||||||
val textPath: String,
|
|
||||||
val filePath: String,
|
|
||||||
val coverImage: Uri?,
|
|
||||||
|
|
||||||
val scrollIndex: Int,
|
|
||||||
val scrollOffset: Int,
|
|
||||||
val progress: Float,
|
|
||||||
val chapters: List<Chapter> = emptyList(),
|
|
||||||
|
|
||||||
val lastOpened: Long?,
|
|
||||||
val category: Category,
|
|
||||||
)
|
|
||||||
|
|
||||||
@Immutable
|
|
||||||
data class BookWithText(
|
|
||||||
val book: Book,
|
|
||||||
val text: List<String>
|
|
||||||
)
|
|
||||||
|
|
||||||
@Immutable
|
|
||||||
data class BookWithCover(
|
|
||||||
val book: Book,
|
|
||||||
val coverImage: CoverImage?
|
|
||||||
)
|
|
||||||
|
|
||||||
@Immutable
|
|
||||||
data class BookWithTextAndCover(
|
|
||||||
val book: Book,
|
|
||||||
val coverImage: CoverImage?,
|
|
||||||
val text: List<String>
|
|
||||||
)
|
|
||||||
|
|
||||||
@Immutable
|
|
||||||
sealed class NullableBook(
|
|
||||||
val bookWithTextAndCover: BookWithTextAndCover?,
|
|
||||||
val fileName: String?,
|
|
||||||
val message: UIText?
|
|
||||||
) {
|
|
||||||
class NotNull(
|
|
||||||
bookWithTextAndCover: BookWithTextAndCover
|
|
||||||
) : NullableBook(
|
|
||||||
bookWithTextAndCover = bookWithTextAndCover,
|
|
||||||
fileName = null,
|
|
||||||
message = null
|
|
||||||
)
|
|
||||||
|
|
||||||
class Null(
|
|
||||||
fileName: String,
|
|
||||||
message: UIText?
|
|
||||||
) : NullableBook(
|
|
||||||
bookWithTextAndCover = null,
|
|
||||||
fileName = fileName,
|
|
||||||
message = message
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
package ua.acclorite.book_story.domain.model
|
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
|
||||||
import ua.acclorite.book_story.domain.util.Selected
|
|
||||||
|
|
||||||
@Immutable
|
|
||||||
enum class Category {
|
|
||||||
READING, ALREADY_READ, PLANNING, DROPPED
|
|
||||||
}
|
|
||||||
|
|
||||||
@Immutable
|
|
||||||
data class CategorizedBooks(
|
|
||||||
val category: Category,
|
|
||||||
val books: List<Pair<Book, Selected>>
|
|
||||||
)
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
package ua.acclorite.book_story.domain.model
|
|
||||||
|
|
||||||
import android.os.Parcelable
|
|
||||||
import androidx.compose.runtime.Immutable
|
|
||||||
import kotlinx.parcelize.Parcelize
|
|
||||||
|
|
||||||
@Parcelize
|
|
||||||
@Immutable
|
|
||||||
data class ReaderLine(
|
|
||||||
val line: String
|
|
||||||
) : Parcelable
|
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
package ua.acclorite.book_story.domain.navigator
|
||||||
|
|
||||||
|
import androidx.lifecycle.SavedStateHandle
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import dagger.assisted.Assisted
|
||||||
|
import dagger.assisted.AssistedFactory
|
||||||
|
import dagger.assisted.AssistedInject
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
|
import kotlinx.coroutines.flow.stateIn
|
||||||
|
import kotlin.collections.plus
|
||||||
|
|
||||||
|
@HiltViewModel(assistedFactory = Navigator.Factory::class)
|
||||||
|
class Navigator @AssistedInject constructor(
|
||||||
|
private val savedStateHandle: SavedStateHandle,
|
||||||
|
@Assisted private val initialScreen: Screen
|
||||||
|
) : ViewModel() {
|
||||||
|
|
||||||
|
val items = savedStateHandle.getStateFlow("items", mutableListOf<Screen>(initialScreen))
|
||||||
|
private fun StateFlow<MutableList<Screen>>.removeLast() {
|
||||||
|
savedStateHandle["items"] = value.dropLast(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun StateFlow<MutableList<Screen>>.add(item: Screen) {
|
||||||
|
savedStateHandle["items"] = value + item
|
||||||
|
}
|
||||||
|
|
||||||
|
val lastItem = items.map {
|
||||||
|
it.lastOrNull() ?: initialScreen
|
||||||
|
}.stateIn(
|
||||||
|
scope = viewModelScope,
|
||||||
|
started = SharingStarted.Eagerly,
|
||||||
|
initialValue = initialScreen
|
||||||
|
)
|
||||||
|
|
||||||
|
val lastEvent = savedStateHandle.getStateFlow("stack_event", StackEvent.Default)
|
||||||
|
private fun StateFlow<StackEvent>.change(stackEvent: StackEvent) {
|
||||||
|
savedStateHandle["stack_event"] = stackEvent
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun push(
|
||||||
|
targetScreen: Screen,
|
||||||
|
popping: Boolean = false,
|
||||||
|
saveInBackStack: Boolean = true
|
||||||
|
) {
|
||||||
|
if (lastItem.value::class == targetScreen::class) return
|
||||||
|
if (!saveInBackStack) items.removeLast()
|
||||||
|
|
||||||
|
lastEvent.change(
|
||||||
|
if (popping) StackEvent.Pop
|
||||||
|
else StackEvent.Default
|
||||||
|
)
|
||||||
|
|
||||||
|
if (lastItem.value::class == targetScreen::class) items.removeLast()
|
||||||
|
items.add(targetScreen)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun pop(popping: Boolean = true) {
|
||||||
|
if (items.value.count() > 1) {
|
||||||
|
lastEvent.change(
|
||||||
|
if (popping) StackEvent.Pop
|
||||||
|
else StackEvent.Default
|
||||||
|
)
|
||||||
|
items.removeLast()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@AssistedFactory
|
||||||
|
interface Factory {
|
||||||
|
fun create(startScreen: Screen): Navigator
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,12 +1,13 @@
|
||||||
package ua.acclorite.book_story.domain.model
|
package ua.acclorite.book_story.domain.navigator
|
||||||
|
|
||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import ua.acclorite.book_story.presentation.core.navigation.Screen
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
@Immutable
|
@Immutable
|
||||||
data class NavigationItem(
|
data class NavigatorItem(
|
||||||
val screen: Screen,
|
val screen: Screen,
|
||||||
@StringRes val title: Int,
|
@StringRes val title: Int,
|
||||||
@StringRes val tooltip: Int,
|
@StringRes val tooltip: Int,
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
package ua.acclorite.book_story.domain.navigator
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
|
||||||
|
interface Screen {
|
||||||
|
@Composable
|
||||||
|
fun Content()
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
package ua.acclorite.book_story.domain.navigator
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
@Serializable
|
||||||
|
enum class StackEvent {
|
||||||
|
Default, Pop
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.domain.model
|
package ua.acclorite.book_story.domain.reader
|
||||||
|
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
|
|
@ -12,9 +12,3 @@ data class Chapter(
|
||||||
val startIndex: Int,
|
val startIndex: Int,
|
||||||
val endIndex: Int
|
val endIndex: Int
|
||||||
) : Parcelable
|
) : Parcelable
|
||||||
|
|
||||||
@Immutable
|
|
||||||
data class ChapterWithText(
|
|
||||||
val chapter: Chapter,
|
|
||||||
val text: List<String>
|
|
||||||
)
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
package ua.acclorite.book_story.domain.reader
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
data class ChapterWithText(
|
||||||
|
val chapter: Chapter,
|
||||||
|
val text: List<String>
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
package ua.acclorite.book_story.domain.reader
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
data class Checkpoint(
|
||||||
|
val index: Int,
|
||||||
|
val offset: Int
|
||||||
|
)
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.domain.model
|
package ua.acclorite.book_story.domain.reader
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
package ua.acclorite.book_story.domain.model
|
package ua.acclorite.book_story.domain.reader
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import androidx.compose.ui.text.font.FontFamily
|
import androidx.compose.ui.text.font.FontFamily
|
||||||
import ua.acclorite.book_story.domain.util.UIText
|
import ua.acclorite.book_story.domain.ui.UIText
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
data class FontWithName(
|
data class FontWithName(
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.presentation.screens.settings.nested.reader.data
|
package ua.acclorite.book_story.domain.reader
|
||||||
|
|
||||||
import android.content.pm.ActivityInfo
|
import android.content.pm.ActivityInfo
|
||||||
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.presentation.screens.settings.nested.reader.data
|
package ua.acclorite.book_story.domain.reader
|
||||||
|
|
||||||
enum class ReaderTextAlignment {
|
enum class ReaderTextAlignment {
|
||||||
START, JUSTIFY, CENTER, END
|
START, JUSTIFY, CENTER, END
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
package ua.acclorite.book_story.domain.repository
|
package ua.acclorite.book_story.domain.repository
|
||||||
|
|
||||||
import androidx.compose.ui.text.AnnotatedString
|
import androidx.compose.ui.text.AnnotatedString
|
||||||
import ua.acclorite.book_story.domain.model.Book
|
import ua.acclorite.book_story.domain.library.book.Book
|
||||||
import ua.acclorite.book_story.domain.model.BookWithText
|
import ua.acclorite.book_story.domain.library.book.BookWithText
|
||||||
import ua.acclorite.book_story.domain.model.BookWithTextAndCover
|
import ua.acclorite.book_story.domain.library.book.BookWithTextAndCover
|
||||||
import ua.acclorite.book_story.domain.model.Chapter
|
import ua.acclorite.book_story.domain.reader.Chapter
|
||||||
import ua.acclorite.book_story.domain.util.CoverImage
|
import ua.acclorite.book_story.domain.util.CoverImage
|
||||||
import ua.acclorite.book_story.domain.util.Resource
|
import ua.acclorite.book_story.domain.util.Resource
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package ua.acclorite.book_story.domain.repository
|
package ua.acclorite.book_story.domain.repository
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.model.ColorPreset
|
import ua.acclorite.book_story.domain.reader.ColorPreset
|
||||||
|
|
||||||
interface ColorPresetRepository {
|
interface ColorPresetRepository {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package ua.acclorite.book_story.domain.repository
|
package ua.acclorite.book_story.domain.repository
|
||||||
|
|
||||||
import androidx.datastore.preferences.core.Preferences
|
import androidx.datastore.preferences.core.Preferences
|
||||||
import ua.acclorite.book_story.presentation.data.MainState
|
import ua.acclorite.book_story.ui.main.MainState
|
||||||
|
|
||||||
interface DataStoreRepository {
|
interface DataStoreRepository {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package ua.acclorite.book_story.domain.repository
|
package ua.acclorite.book_story.domain.repository
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.model.NullableBook
|
import ua.acclorite.book_story.domain.browse.SelectableFile
|
||||||
import ua.acclorite.book_story.domain.model.SelectableFile
|
import ua.acclorite.book_story.domain.library.book.NullableBook
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
interface FileSystemRepository {
|
interface FileSystemRepository {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package ua.acclorite.book_story.domain.repository
|
package ua.acclorite.book_story.domain.repository
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.model.History
|
import ua.acclorite.book_story.domain.history.History
|
||||||
|
|
||||||
interface HistoryRepository {
|
interface HistoryRepository {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.domain.model
|
package ua.acclorite.book_story.domain.ui
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import androidx.compose.ui.text.TextStyle
|
import androidx.compose.ui.text.TextStyle
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.domain.util
|
package ua.acclorite.book_story.domain.ui
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package ua.acclorite.book_story.domain.use_case.book
|
package ua.acclorite.book_story.domain.use_case.book
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.model.Chapter
|
import ua.acclorite.book_story.domain.reader.Chapter
|
||||||
import ua.acclorite.book_story.domain.repository.BookRepository
|
import ua.acclorite.book_story.domain.repository.BookRepository
|
||||||
import ua.acclorite.book_story.domain.util.Resource
|
import ua.acclorite.book_story.domain.util.Resource
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package ua.acclorite.book_story.domain.use_case.book
|
package ua.acclorite.book_story.domain.use_case.book
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.model.Book
|
import ua.acclorite.book_story.domain.library.book.Book
|
||||||
import ua.acclorite.book_story.domain.repository.BookRepository
|
import ua.acclorite.book_story.domain.repository.BookRepository
|
||||||
import ua.acclorite.book_story.domain.repository.HistoryRepository
|
import ua.acclorite.book_story.domain.repository.HistoryRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package ua.acclorite.book_story.domain.use_case.book
|
package ua.acclorite.book_story.domain.use_case.book
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.model.Book
|
import ua.acclorite.book_story.domain.library.book.Book
|
||||||
import ua.acclorite.book_story.domain.repository.BookRepository
|
import ua.acclorite.book_story.domain.repository.BookRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package ua.acclorite.book_story.domain.use_case.book
|
package ua.acclorite.book_story.domain.use_case.book
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.model.Book
|
import ua.acclorite.book_story.domain.library.book.Book
|
||||||
import ua.acclorite.book_story.domain.repository.BookRepository
|
import ua.acclorite.book_story.domain.repository.BookRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package ua.acclorite.book_story.domain.use_case.book
|
package ua.acclorite.book_story.domain.use_case.book
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.model.Book
|
import ua.acclorite.book_story.domain.library.book.Book
|
||||||
import ua.acclorite.book_story.domain.repository.BookRepository
|
import ua.acclorite.book_story.domain.repository.BookRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package ua.acclorite.book_story.domain.use_case.book
|
package ua.acclorite.book_story.domain.use_case.book
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.model.BookWithTextAndCover
|
import ua.acclorite.book_story.domain.library.book.BookWithTextAndCover
|
||||||
import ua.acclorite.book_story.domain.repository.BookRepository
|
import ua.acclorite.book_story.domain.repository.BookRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package ua.acclorite.book_story.domain.use_case.book
|
package ua.acclorite.book_story.domain.use_case.book
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.model.Book
|
import ua.acclorite.book_story.domain.library.book.Book
|
||||||
import ua.acclorite.book_story.domain.repository.BookRepository
|
import ua.acclorite.book_story.domain.repository.BookRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package ua.acclorite.book_story.domain.use_case.book
|
package ua.acclorite.book_story.domain.use_case.book
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.model.BookWithText
|
import ua.acclorite.book_story.domain.library.book.BookWithText
|
||||||
import ua.acclorite.book_story.domain.repository.BookRepository
|
import ua.acclorite.book_story.domain.repository.BookRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package ua.acclorite.book_story.domain.use_case.book
|
package ua.acclorite.book_story.domain.use_case.book
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.model.Book
|
import ua.acclorite.book_story.domain.library.book.Book
|
||||||
import ua.acclorite.book_story.domain.repository.BookRepository
|
import ua.acclorite.book_story.domain.repository.BookRepository
|
||||||
import ua.acclorite.book_story.domain.util.CoverImage
|
import ua.acclorite.book_story.domain.util.CoverImage
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package ua.acclorite.book_story.domain.use_case.color_preset
|
package ua.acclorite.book_story.domain.use_case.color_preset
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.model.ColorPreset
|
import ua.acclorite.book_story.domain.reader.ColorPreset
|
||||||
import ua.acclorite.book_story.domain.repository.ColorPresetRepository
|
import ua.acclorite.book_story.domain.repository.ColorPresetRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package ua.acclorite.book_story.domain.use_case.color_preset
|
package ua.acclorite.book_story.domain.use_case.color_preset
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.model.ColorPreset
|
import ua.acclorite.book_story.domain.reader.ColorPreset
|
||||||
import ua.acclorite.book_story.domain.repository.ColorPresetRepository
|
import ua.acclorite.book_story.domain.repository.ColorPresetRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package ua.acclorite.book_story.domain.use_case.color_preset
|
package ua.acclorite.book_story.domain.use_case.color_preset
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.model.ColorPreset
|
import ua.acclorite.book_story.domain.reader.ColorPreset
|
||||||
import ua.acclorite.book_story.domain.repository.ColorPresetRepository
|
import ua.acclorite.book_story.domain.repository.ColorPresetRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package ua.acclorite.book_story.domain.use_case.color_preset
|
package ua.acclorite.book_story.domain.use_case.color_preset
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.model.ColorPreset
|
import ua.acclorite.book_story.domain.reader.ColorPreset
|
||||||
import ua.acclorite.book_story.domain.repository.ColorPresetRepository
|
import ua.acclorite.book_story.domain.repository.ColorPresetRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package ua.acclorite.book_story.domain.use_case.color_preset
|
package ua.acclorite.book_story.domain.use_case.color_preset
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.model.ColorPreset
|
import ua.acclorite.book_story.domain.reader.ColorPreset
|
||||||
import ua.acclorite.book_story.domain.repository.ColorPresetRepository
|
import ua.acclorite.book_story.domain.repository.ColorPresetRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package ua.acclorite.book_story.domain.use_case.data_store
|
package ua.acclorite.book_story.domain.use_case.data_store
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.repository.DataStoreRepository
|
import ua.acclorite.book_story.domain.repository.DataStoreRepository
|
||||||
import ua.acclorite.book_story.presentation.data.MainState
|
import ua.acclorite.book_story.ui.main.MainState
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class GetAllSettings @Inject constructor(
|
class GetAllSettings @Inject constructor(
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package ua.acclorite.book_story.domain.use_case.file_system
|
package ua.acclorite.book_story.domain.use_case.file_system
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.model.NullableBook
|
import ua.acclorite.book_story.domain.library.book.NullableBook
|
||||||
import ua.acclorite.book_story.domain.repository.FileSystemRepository
|
import ua.acclorite.book_story.domain.repository.FileSystemRepository
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package ua.acclorite.book_story.domain.use_case.file_system
|
package ua.acclorite.book_story.domain.use_case.file_system
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.model.SelectableFile
|
import ua.acclorite.book_story.domain.browse.SelectableFile
|
||||||
import ua.acclorite.book_story.domain.repository.FileSystemRepository
|
import ua.acclorite.book_story.domain.repository.FileSystemRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package ua.acclorite.book_story.domain.use_case.history
|
package ua.acclorite.book_story.domain.use_case.history
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.model.History
|
import ua.acclorite.book_story.domain.history.History
|
||||||
import ua.acclorite.book_story.domain.repository.HistoryRepository
|
import ua.acclorite.book_story.domain.repository.HistoryRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package ua.acclorite.book_story.domain.use_case.history
|
package ua.acclorite.book_story.domain.use_case.history
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.model.History
|
import ua.acclorite.book_story.domain.history.History
|
||||||
import ua.acclorite.book_story.domain.repository.HistoryRepository
|
import ua.acclorite.book_story.domain.repository.HistoryRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package ua.acclorite.book_story.domain.use_case.history
|
package ua.acclorite.book_story.domain.use_case.history
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.model.History
|
import ua.acclorite.book_story.domain.history.History
|
||||||
import ua.acclorite.book_story.domain.repository.HistoryRepository
|
import ua.acclorite.book_story.domain.repository.HistoryRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package ua.acclorite.book_story.domain.use_case.history
|
package ua.acclorite.book_story.domain.use_case.history
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.model.History
|
import ua.acclorite.book_story.domain.history.History
|
||||||
import ua.acclorite.book_story.domain.repository.HistoryRepository
|
import ua.acclorite.book_story.domain.repository.HistoryRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
package ua.acclorite.book_story.domain.util
|
package ua.acclorite.book_story.domain.util
|
||||||
|
|
||||||
|
import ua.acclorite.book_story.domain.ui.UIText
|
||||||
|
|
||||||
sealed class Resource<T>(val data: T? = null, val message: UIText? = null) {
|
sealed class Resource<T>(val data: T? = null, val message: UIText? = null) {
|
||||||
class Success<T>(data: T?) : Resource<T>(data)
|
class Success<T>(data: T?) : Resource<T>(data)
|
||||||
class Error<T>(message: UIText, data: T? = null) : Resource<T>(data, message)
|
class Error<T>(message: UIText, data: T? = null) : Resource<T>(data, message)
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
package ua.acclorite.book_story.domain.util
|
package ua.acclorite.book_story.domain.util
|
||||||
|
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import ua.acclorite.book_story.presentation.core.navigation.Navigator
|
|
||||||
|
|
||||||
typealias CoverImage = Bitmap
|
typealias CoverImage = Bitmap
|
||||||
typealias Selected = Boolean
|
typealias Selected = Boolean
|
||||||
typealias ID = Int
|
typealias ID = Int
|
||||||
typealias Route = String
|
typealias BottomSheet = String
|
||||||
typealias OnNavigate = (Navigator.() -> Unit) -> Unit
|
typealias Dialog = String
|
||||||
|
typealias Drawer = String
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
package ua.acclorite.book_story.domain.util
|
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.State
|
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
|
||||||
import androidx.lifecycle.ViewModel
|
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
|
||||||
|
|
||||||
|
|
||||||
abstract class UIViewModel<S, E> : ViewModel() {
|
|
||||||
abstract val state: StateFlow<S>
|
|
||||||
abstract fun onEvent(event: E)
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
@Composable
|
|
||||||
inline fun <reified V : UIViewModel<S, E>, S, E> getState(): State<S> {
|
|
||||||
return hiltViewModel<V>().state.collectAsStateWithLifecycle()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
inline fun <reified V : UIViewModel<S, E>, S, E> getEvent(): (E) -> Unit {
|
|
||||||
return hiltViewModel<V>()::onEvent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,19 +1,13 @@
|
||||||
package ua.acclorite.book_story.presentation.screens.about.components.badges
|
package ua.acclorite.book_story.presentation.about
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import ua.acclorite.book_story.domain.model.Badge
|
import ua.acclorite.book_story.domain.about.Badge
|
||||||
import ua.acclorite.book_story.presentation.core.components.common.IconButton
|
import ua.acclorite.book_story.presentation.core.components.common.IconButton
|
||||||
|
|
||||||
/**
|
|
||||||
* About Badge Item.
|
|
||||||
*
|
|
||||||
* @param badge [Badge].
|
|
||||||
* @param onClick OnClick callback.
|
|
||||||
*/
|
|
||||||
@Composable
|
@Composable
|
||||||
fun AboutBadgeItem(
|
fun AboutBadgeItem(
|
||||||
badge: Badge,
|
badge: Badge,
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.presentation.screens.about.components.badges
|
package ua.acclorite.book_story.presentation.about
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
|
|
@ -10,24 +10,17 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.unit.Dp
|
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.presentation.core.constants.Constants
|
import ua.acclorite.book_story.presentation.core.constants.Constants
|
||||||
import ua.acclorite.book_story.presentation.core.constants.provideAboutBadges
|
import ua.acclorite.book_story.presentation.core.constants.provideAboutBadges
|
||||||
import ua.acclorite.book_story.presentation.core.util.showToast
|
import ua.acclorite.book_story.presentation.core.util.showToast
|
||||||
import ua.acclorite.book_story.presentation.screens.about.data.AboutEvent
|
import ua.acclorite.book_story.ui.about.AboutEvent
|
||||||
import ua.acclorite.book_story.presentation.screens.about.data.AboutViewModel
|
|
||||||
|
|
||||||
/**
|
|
||||||
* About Badges.
|
|
||||||
* Links all ways to contact me.
|
|
||||||
*
|
|
||||||
* @param verticalPadding Vertical item padding.
|
|
||||||
*/
|
|
||||||
@Composable
|
@Composable
|
||||||
fun AboutBadges(verticalPadding: Dp = 18.dp) {
|
fun AboutBadges(
|
||||||
val onEvent = AboutViewModel.getEvent()
|
navigateToBrowserPage: (AboutEvent.OnNavigateToBrowserPage) -> Unit
|
||||||
|
) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
|
|
@ -36,11 +29,14 @@ fun AboutBadges(verticalPadding: Dp = 18.dp) {
|
||||||
) {
|
) {
|
||||||
LazyRow(
|
LazyRow(
|
||||||
Modifier
|
Modifier
|
||||||
.padding(horizontal = 18.dp, vertical = verticalPadding),
|
.padding(18.dp),
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
horizontalArrangement = Arrangement.spacedBy(13.dp)
|
horizontalArrangement = Arrangement.spacedBy(13.dp)
|
||||||
) {
|
) {
|
||||||
items(Constants.provideAboutBadges(), key = { it.id }) { badge ->
|
items(
|
||||||
|
Constants.provideAboutBadges(),
|
||||||
|
key = { it.id }
|
||||||
|
) { badge ->
|
||||||
AboutBadgeItem(badge = badge) {
|
AboutBadgeItem(badge = badge) {
|
||||||
when (badge.id) {
|
when (badge.id) {
|
||||||
"tryzub" -> {
|
"tryzub" -> {
|
||||||
|
|
@ -50,14 +46,10 @@ fun AboutBadges(verticalPadding: Dp = 18.dp) {
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
badge.url?.let {
|
badge.url?.let {
|
||||||
onEvent(
|
navigateToBrowserPage(
|
||||||
AboutEvent.OnNavigateToBrowserPage(
|
AboutEvent.OnNavigateToBrowserPage(
|
||||||
it,
|
page = it,
|
||||||
context,
|
context = context
|
||||||
noAppsFound = {
|
|
||||||
context.getString(R.string.error_no_browser)
|
|
||||||
.showToast(context = context, longToast = false)
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
package ua.acclorite.book_story.presentation.about
|
||||||
|
|
||||||
|
import androidx.compose.foundation.lazy.LazyListState
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.TopAppBarScrollBehavior
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import ua.acclorite.book_story.data.remote.dto.LatestReleaseInfo
|
||||||
|
import ua.acclorite.book_story.domain.util.Dialog
|
||||||
|
import ua.acclorite.book_story.ui.about.AboutEvent
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@Composable
|
||||||
|
fun AboutContent(
|
||||||
|
scrollBehavior: TopAppBarScrollBehavior,
|
||||||
|
dialog: Dialog? = null,
|
||||||
|
updateLoading: Boolean,
|
||||||
|
updateInfo: LatestReleaseInfo?,
|
||||||
|
listState: LazyListState,
|
||||||
|
checkForUpdate: (AboutEvent.OnCheckForUpdate) -> Unit,
|
||||||
|
navigateToBrowserPage: (AboutEvent.OnNavigateToBrowserPage) -> Unit,
|
||||||
|
dismissDialog: (AboutEvent.OnDismissDialog) -> Unit,
|
||||||
|
navigateToLicenses: () -> Unit,
|
||||||
|
navigateToCredits: () -> Unit,
|
||||||
|
navigateBack: () -> Unit
|
||||||
|
) {
|
||||||
|
AboutDialog(
|
||||||
|
dialog = dialog,
|
||||||
|
updateInfo = updateInfo,
|
||||||
|
navigateToBrowserPage = navigateToBrowserPage,
|
||||||
|
dismissDialog = dismissDialog
|
||||||
|
)
|
||||||
|
|
||||||
|
AboutScaffold(
|
||||||
|
scrollBehavior = scrollBehavior,
|
||||||
|
updateLoading = updateLoading,
|
||||||
|
listState = listState,
|
||||||
|
checkForUpdate = checkForUpdate,
|
||||||
|
navigateToBrowserPage = navigateToBrowserPage,
|
||||||
|
navigateToLicenses = navigateToLicenses,
|
||||||
|
navigateToCredits = navigateToCredits,
|
||||||
|
navigateBack = navigateBack
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
package ua.acclorite.book_story.presentation.about
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import ua.acclorite.book_story.data.remote.dto.LatestReleaseInfo
|
||||||
|
import ua.acclorite.book_story.domain.util.Dialog
|
||||||
|
import ua.acclorite.book_story.ui.about.AboutEvent
|
||||||
|
import ua.acclorite.book_story.ui.about.AboutScreen
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun AboutDialog(
|
||||||
|
dialog: Dialog? = null,
|
||||||
|
updateInfo: LatestReleaseInfo?,
|
||||||
|
navigateToBrowserPage: (AboutEvent.OnNavigateToBrowserPage) -> Unit,
|
||||||
|
dismissDialog: (AboutEvent.OnDismissDialog) -> Unit
|
||||||
|
) {
|
||||||
|
when (dialog) {
|
||||||
|
AboutScreen.UPDATE_DIALOG -> {
|
||||||
|
AboutUpdateDialog(
|
||||||
|
updateInfo = updateInfo,
|
||||||
|
navigateToBrowserPage = navigateToBrowserPage,
|
||||||
|
dismissDialog = dismissDialog
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.presentation.screens.about.components
|
package ua.acclorite.book_story.presentation.about
|
||||||
|
|
||||||
import androidx.compose.animation.core.EaseInOut
|
import androidx.compose.animation.core.EaseInOut
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
|
|
@ -21,20 +21,8 @@ import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import ua.acclorite.book_story.presentation.core.components.progress_indicator.CircularProgressIndicator
|
import ua.acclorite.book_story.presentation.core.components.progress_indicator.CircularProgressIndicator
|
||||||
import ua.acclorite.book_story.presentation.ui.FadeTransitionPreservingSpace
|
import ua.acclorite.book_story.ui.theme.FadeTransitionPreservingSpace
|
||||||
|
|
||||||
/**
|
|
||||||
* About Screen Item.
|
|
||||||
* Clickable item, that has title, description and loading state.
|
|
||||||
*
|
|
||||||
* @param modifier [Modifier].
|
|
||||||
* @param title Title of the item.
|
|
||||||
* @param description Description of the item.
|
|
||||||
* @param verticalPadding Vertical item padding.
|
|
||||||
* @param showLoading Whether loading indicator is shown.
|
|
||||||
* @param isOnClickEnabled Whether this item is clickable.
|
|
||||||
* @param onClick OnClick callback.
|
|
||||||
*/
|
|
||||||
@Composable
|
@Composable
|
||||||
fun AboutItem(
|
fun AboutItem(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
|
|
@ -0,0 +1,181 @@
|
||||||
|
package ua.acclorite.book_story.presentation.about
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.foundation.lazy.LazyListState
|
||||||
|
import androidx.compose.material3.HorizontalDivider
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.text.buildAnnotatedString
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import ua.acclorite.book_story.R
|
||||||
|
import ua.acclorite.book_story.presentation.core.components.common.LazyColumnWithScrollbar
|
||||||
|
import ua.acclorite.book_story.presentation.core.constants.Constants
|
||||||
|
import ua.acclorite.book_story.presentation.core.constants.provideContributorsPage
|
||||||
|
import ua.acclorite.book_story.presentation.core.constants.provideIssuesPage
|
||||||
|
import ua.acclorite.book_story.presentation.core.constants.provideReleasesPage
|
||||||
|
import ua.acclorite.book_story.presentation.core.constants.provideTranslationPage
|
||||||
|
import ua.acclorite.book_story.ui.about.AboutEvent
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun AboutLayout(
|
||||||
|
updateLoading: Boolean,
|
||||||
|
paddingValues: PaddingValues,
|
||||||
|
listState: LazyListState,
|
||||||
|
checkForUpdate: (AboutEvent.OnCheckForUpdate) -> Unit,
|
||||||
|
navigateToBrowserPage: (AboutEvent.OnNavigateToBrowserPage) -> Unit,
|
||||||
|
navigateToLicenses: () -> Unit,
|
||||||
|
navigateToCredits: () -> Unit
|
||||||
|
) {
|
||||||
|
val context = LocalContext.current
|
||||||
|
LazyColumnWithScrollbar(
|
||||||
|
Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(top = paddingValues.calculateTopPadding()),
|
||||||
|
state = listState
|
||||||
|
) {
|
||||||
|
item {
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
}
|
||||||
|
|
||||||
|
item {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
contentAlignment = Alignment.Center
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
painterResource(id = R.drawable.app_icon),
|
||||||
|
contentDescription = stringResource(id = R.string.app_icon_content_desc),
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(14.dp)
|
||||||
|
.size(120.dp),
|
||||||
|
tint = MaterialTheme.colorScheme.onSurfaceVariant
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
item {
|
||||||
|
Spacer(modifier = Modifier.height(36.dp))
|
||||||
|
HorizontalDivider(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
color = MaterialTheme.colorScheme.outlineVariant
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
item {
|
||||||
|
AboutItem(
|
||||||
|
title = stringResource(id = R.string.app_version_option),
|
||||||
|
description = buildAnnotatedString {
|
||||||
|
append(
|
||||||
|
stringResource(
|
||||||
|
id = R.string.app_version_option_desc_1,
|
||||||
|
context.getString(R.string.app_version)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
append("\n")
|
||||||
|
append(stringResource(id = R.string.app_version_option_desc_2))
|
||||||
|
},
|
||||||
|
showLoading = updateLoading
|
||||||
|
) {
|
||||||
|
checkForUpdate(
|
||||||
|
AboutEvent.OnCheckForUpdate(
|
||||||
|
context = context
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
item {
|
||||||
|
AboutItem(
|
||||||
|
title = stringResource(id = R.string.report_bug_option),
|
||||||
|
description = null
|
||||||
|
) {
|
||||||
|
navigateToBrowserPage(
|
||||||
|
AboutEvent.OnNavigateToBrowserPage(
|
||||||
|
page = Constants.provideIssuesPage(),
|
||||||
|
context = context
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
item {
|
||||||
|
AboutItem(
|
||||||
|
title = stringResource(id = R.string.contributors_option),
|
||||||
|
description = null
|
||||||
|
) {
|
||||||
|
navigateToBrowserPage(
|
||||||
|
AboutEvent.OnNavigateToBrowserPage(
|
||||||
|
page = Constants.provideContributorsPage(),
|
||||||
|
context = context
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
item {
|
||||||
|
AboutItem(
|
||||||
|
title = stringResource(id = R.string.whats_new_option),
|
||||||
|
description = null
|
||||||
|
) {
|
||||||
|
navigateToBrowserPage(
|
||||||
|
AboutEvent.OnNavigateToBrowserPage(
|
||||||
|
page = Constants.provideReleasesPage(),
|
||||||
|
context = context
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
item {
|
||||||
|
AboutItem(
|
||||||
|
title = stringResource(id = R.string.licenses_option),
|
||||||
|
description = null
|
||||||
|
) {
|
||||||
|
navigateToLicenses()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
item {
|
||||||
|
AboutItem(
|
||||||
|
title = stringResource(id = R.string.credits_option),
|
||||||
|
description = null
|
||||||
|
) {
|
||||||
|
navigateToCredits()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
item {
|
||||||
|
AboutItem(
|
||||||
|
title = stringResource(id = R.string.help_translate_option),
|
||||||
|
description = null
|
||||||
|
) {
|
||||||
|
navigateToBrowserPage(
|
||||||
|
AboutEvent.OnNavigateToBrowserPage(
|
||||||
|
page = Constants.provideTranslationPage(),
|
||||||
|
context = context
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
item {
|
||||||
|
AboutBadges(
|
||||||
|
navigateToBrowserPage = navigateToBrowserPage
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
package ua.acclorite.book_story.presentation.about
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.WindowInsets
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.navigationBars
|
||||||
|
import androidx.compose.foundation.layout.windowInsetsPadding
|
||||||
|
import androidx.compose.foundation.lazy.LazyListState
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.material3.TopAppBarScrollBehavior
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||||
|
import ua.acclorite.book_story.ui.about.AboutEvent
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@Composable
|
||||||
|
fun AboutScaffold(
|
||||||
|
scrollBehavior: TopAppBarScrollBehavior,
|
||||||
|
updateLoading: Boolean,
|
||||||
|
listState: LazyListState,
|
||||||
|
checkForUpdate: (AboutEvent.OnCheckForUpdate) -> Unit,
|
||||||
|
navigateToBrowserPage: (AboutEvent.OnNavigateToBrowserPage) -> Unit,
|
||||||
|
navigateToLicenses: () -> Unit,
|
||||||
|
navigateToCredits: () -> Unit,
|
||||||
|
navigateBack: () -> Unit
|
||||||
|
) {
|
||||||
|
Scaffold(
|
||||||
|
Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.nestedScroll(scrollBehavior.nestedScrollConnection)
|
||||||
|
.windowInsetsPadding(WindowInsets.navigationBars),
|
||||||
|
containerColor = MaterialTheme.colorScheme.surface,
|
||||||
|
topBar = {
|
||||||
|
AboutTopBar(
|
||||||
|
scrollBehavior = scrollBehavior,
|
||||||
|
navigateBack = navigateBack
|
||||||
|
)
|
||||||
|
}
|
||||||
|
) { paddingValues ->
|
||||||
|
AboutLayout(
|
||||||
|
updateLoading = updateLoading,
|
||||||
|
paddingValues = paddingValues,
|
||||||
|
listState = listState,
|
||||||
|
checkForUpdate = checkForUpdate,
|
||||||
|
navigateToBrowserPage = navigateToBrowserPage,
|
||||||
|
navigateToLicenses = navigateToLicenses,
|
||||||
|
navigateToCredits = navigateToCredits
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue