🚀 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:label="@string/app_name"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.Start.Splash"
|
||||
android:theme="@style/Splash"
|
||||
android:requestLegacyExternalStorage="true"
|
||||
android:enableOnBackInvokedCallback="true"
|
||||
android:usesCleartextTraffic="false"
|
||||
|
|
@ -33,11 +33,11 @@
|
|||
tools:ignore="DataExtractionRules">
|
||||
|
||||
<activity
|
||||
android:name=".Activity"
|
||||
android:name=".ui.main.MainActivity"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:configChanges="orientation|screenSize|screenLayout|smallestScreenSize|locale|density|uiMode"
|
||||
android:exported="true"
|
||||
android:theme="@style/Theme.Start.Splash">
|
||||
android:theme="@style/Splash">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<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.gson.Gson
|
||||
import com.google.gson.JsonSyntaxException
|
||||
import ua.acclorite.book_story.domain.model.Chapter
|
||||
import ua.acclorite.book_story.domain.reader.Chapter
|
||||
|
||||
class ChapterConverter {
|
||||
@TypeConverter
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ import androidx.room.Entity
|
|||
import androidx.room.PrimaryKey
|
||||
import androidx.room.TypeConverters
|
||||
import ua.acclorite.book_story.data.local.converter.ChapterConverter
|
||||
import ua.acclorite.book_story.domain.model.Category
|
||||
import ua.acclorite.book_story.domain.model.Chapter
|
||||
import ua.acclorite.book_story.domain.library.category.Category
|
||||
import ua.acclorite.book_story.domain.reader.Chapter
|
||||
|
||||
@Entity
|
||||
@TypeConverters(ChapterConverter::class)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package ua.acclorite.book_story.data.mapper.book
|
||||
|
||||
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 {
|
||||
suspend fun toBookEntity(book: Book): BookEntity
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ package ua.acclorite.book_story.data.mapper.book
|
|||
import android.net.Uri
|
||||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.data.local.dto.BookEntity
|
||||
import ua.acclorite.book_story.domain.model.Book
|
||||
import ua.acclorite.book_story.domain.util.UIText
|
||||
import ua.acclorite.book_story.domain.library.book.Book
|
||||
import ua.acclorite.book_story.domain.ui.UIText
|
||||
import javax.inject.Inject
|
||||
|
||||
class BookMapperImpl @Inject constructor() : BookMapper {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package ua.acclorite.book_story.data.mapper.color_preset
|
||||
|
||||
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 {
|
||||
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 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
|
||||
|
||||
class ColorPresetMapperImpl @Inject constructor() : ColorPresetMapper {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package ua.acclorite.book_story.data.mapper.history
|
||||
|
||||
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 {
|
||||
suspend fun toHistoryEntity(history: History): HistoryEntity
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package ua.acclorite.book_story.data.mapper.history
|
||||
|
||||
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
|
||||
|
||||
class HistoryMapperImpl @Inject constructor() : HistoryMapper {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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.pdf.PdfFileParser
|
||||
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 javax.inject.Inject
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
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 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.pdf.PdfTextParser
|
||||
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.UIText
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
@ -70,12 +70,4 @@ class TextParserImpl @Inject constructor(
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -7,10 +7,10 @@ import kotlinx.coroutines.withContext
|
|||
import org.jsoup.Jsoup
|
||||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.data.parser.FileParser
|
||||
import ua.acclorite.book_story.domain.model.Book
|
||||
import ua.acclorite.book_story.domain.model.BookWithCover
|
||||
import ua.acclorite.book_story.domain.model.Category
|
||||
import ua.acclorite.book_story.domain.util.UIText
|
||||
import ua.acclorite.book_story.domain.library.book.Book
|
||||
import ua.acclorite.book_story.domain.library.book.BookWithCover
|
||||
import ua.acclorite.book_story.domain.library.category.Category
|
||||
import ua.acclorite.book_story.domain.ui.UIText
|
||||
import java.io.File
|
||||
import java.util.zip.ZipFile
|
||||
import javax.inject.Inject
|
||||
|
|
|
|||
|
|
@ -15,10 +15,10 @@ import org.jsoup.Jsoup
|
|||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.data.parser.DocumentParser
|
||||
import ua.acclorite.book_story.data.parser.TextParser
|
||||
import ua.acclorite.book_story.domain.model.Chapter
|
||||
import ua.acclorite.book_story.domain.model.ChapterWithText
|
||||
import ua.acclorite.book_story.domain.reader.Chapter
|
||||
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.UIText
|
||||
import ua.acclorite.book_story.presentation.core.util.addAll
|
||||
import ua.acclorite.book_story.presentation.core.util.clearMarkdown
|
||||
import java.io.File
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@ import org.w3c.dom.Document
|
|||
import org.w3c.dom.Element
|
||||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.data.parser.FileParser
|
||||
import ua.acclorite.book_story.domain.model.Book
|
||||
import ua.acclorite.book_story.domain.model.BookWithCover
|
||||
import ua.acclorite.book_story.domain.model.Category
|
||||
import ua.acclorite.book_story.domain.util.UIText
|
||||
import ua.acclorite.book_story.domain.library.book.Book
|
||||
import ua.acclorite.book_story.domain.library.book.BookWithCover
|
||||
import ua.acclorite.book_story.domain.library.category.Category
|
||||
import ua.acclorite.book_story.domain.ui.UIText
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
import javax.xml.parsers.DocumentBuilderFactory
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@ import org.w3c.dom.Element
|
|||
import org.w3c.dom.NodeList
|
||||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.data.parser.TextParser
|
||||
import ua.acclorite.book_story.domain.model.Chapter
|
||||
import ua.acclorite.book_story.domain.model.ChapterWithText
|
||||
import ua.acclorite.book_story.domain.reader.Chapter
|
||||
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.UIText
|
||||
import ua.acclorite.book_story.presentation.core.util.clearAllMarkdown
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
|
|
|
|||
|
|
@ -3,10 +3,10 @@ package ua.acclorite.book_story.data.parser.html
|
|||
import org.jsoup.Jsoup
|
||||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.data.parser.FileParser
|
||||
import ua.acclorite.book_story.domain.model.Book
|
||||
import ua.acclorite.book_story.domain.model.BookWithCover
|
||||
import ua.acclorite.book_story.domain.model.Category
|
||||
import ua.acclorite.book_story.domain.util.UIText
|
||||
import ua.acclorite.book_story.domain.library.book.Book
|
||||
import ua.acclorite.book_story.domain.library.book.BookWithCover
|
||||
import ua.acclorite.book_story.domain.library.category.Category
|
||||
import ua.acclorite.book_story.domain.ui.UIText
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@ import org.jsoup.Jsoup
|
|||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.data.parser.DocumentParser
|
||||
import ua.acclorite.book_story.data.parser.TextParser
|
||||
import ua.acclorite.book_story.domain.model.Chapter
|
||||
import ua.acclorite.book_story.domain.model.ChapterWithText
|
||||
import ua.acclorite.book_story.domain.reader.Chapter
|
||||
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.UIText
|
||||
import ua.acclorite.book_story.presentation.core.util.clearAllMarkdown
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
|
|
|
|||
|
|
@ -5,10 +5,10 @@ import com.tom_roush.pdfbox.android.PDFBoxResourceLoader
|
|||
import com.tom_roush.pdfbox.pdmodel.PDDocument
|
||||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.data.parser.FileParser
|
||||
import ua.acclorite.book_story.domain.model.Book
|
||||
import ua.acclorite.book_story.domain.model.BookWithCover
|
||||
import ua.acclorite.book_story.domain.model.Category
|
||||
import ua.acclorite.book_story.domain.util.UIText
|
||||
import ua.acclorite.book_story.domain.library.book.Book
|
||||
import ua.acclorite.book_story.domain.library.book.BookWithCover
|
||||
import ua.acclorite.book_story.domain.library.category.Category
|
||||
import ua.acclorite.book_story.domain.ui.UIText
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
@ -27,7 +27,7 @@ class PdfFileParser @Inject constructor(
|
|||
if (isNullOrBlank()) UIText.StringResource(R.string.unknown_author)
|
||||
else UIText.StringValue(this)
|
||||
}
|
||||
val description = document.documentInformation.subject ?: null
|
||||
val description = document.documentInformation.subject
|
||||
|
||||
document.close()
|
||||
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@ import com.tom_roush.pdfbox.text.PDFTextStripper
|
|||
import kotlinx.coroutines.yield
|
||||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.data.parser.TextParser
|
||||
import ua.acclorite.book_story.domain.model.Chapter
|
||||
import ua.acclorite.book_story.domain.model.ChapterWithText
|
||||
import ua.acclorite.book_story.domain.reader.Chapter
|
||||
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.UIText
|
||||
import ua.acclorite.book_story.presentation.core.util.clearAllMarkdown
|
||||
import java.io.File
|
||||
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.data.parser.FileParser
|
||||
import ua.acclorite.book_story.domain.model.Book
|
||||
import ua.acclorite.book_story.domain.model.BookWithCover
|
||||
import ua.acclorite.book_story.domain.model.Category
|
||||
import ua.acclorite.book_story.domain.util.UIText
|
||||
import ua.acclorite.book_story.domain.library.book.Book
|
||||
import ua.acclorite.book_story.domain.library.book.BookWithCover
|
||||
import ua.acclorite.book_story.domain.library.category.Category
|
||||
import ua.acclorite.book_story.domain.ui.UIText
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@ import kotlinx.coroutines.withContext
|
|||
import kotlinx.coroutines.yield
|
||||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.data.parser.TextParser
|
||||
import ua.acclorite.book_story.domain.model.Chapter
|
||||
import ua.acclorite.book_story.domain.model.ChapterWithText
|
||||
import ua.acclorite.book_story.domain.reader.Chapter
|
||||
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.UIText
|
||||
import ua.acclorite.book_story.presentation.core.util.clearAllMarkdown
|
||||
import java.io.BufferedReader
|
||||
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.MarkdownParser
|
||||
import ua.acclorite.book_story.data.parser.TextParser
|
||||
import ua.acclorite.book_story.domain.model.Book
|
||||
import ua.acclorite.book_story.domain.model.BookWithText
|
||||
import ua.acclorite.book_story.domain.model.BookWithTextAndCover
|
||||
import ua.acclorite.book_story.domain.model.Chapter
|
||||
import ua.acclorite.book_story.domain.library.book.Book
|
||||
import ua.acclorite.book_story.domain.library.book.BookWithText
|
||||
import ua.acclorite.book_story.domain.library.book.BookWithTextAndCover
|
||||
import ua.acclorite.book_story.domain.reader.Chapter
|
||||
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.Resource
|
||||
import ua.acclorite.book_story.domain.util.UIText
|
||||
import java.io.BufferedReader
|
||||
import java.io.ByteArrayOutputStream
|
||||
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.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 javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import kotlinx.coroutines.awaitAll
|
|||
import kotlinx.coroutines.withContext
|
||||
import ua.acclorite.book_story.data.local.data_store.DataStore
|
||||
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 javax.inject.Inject
|
||||
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.parser.FileParser
|
||||
import ua.acclorite.book_story.data.parser.TextParser
|
||||
import ua.acclorite.book_story.domain.model.BookWithTextAndCover
|
||||
import ua.acclorite.book_story.domain.model.NullableBook
|
||||
import ua.acclorite.book_story.domain.model.NullableBook.NotNull
|
||||
import ua.acclorite.book_story.domain.model.NullableBook.Null
|
||||
import ua.acclorite.book_story.domain.model.SelectableFile
|
||||
import ua.acclorite.book_story.domain.browse.SelectableFile
|
||||
import ua.acclorite.book_story.domain.library.book.BookWithTextAndCover
|
||||
import ua.acclorite.book_story.domain.library.book.NullableBook
|
||||
import ua.acclorite.book_story.domain.library.book.NullableBook.NotNull
|
||||
import ua.acclorite.book_story.domain.library.book.NullableBook.Null
|
||||
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.UIText
|
||||
import ua.acclorite.book_story.presentation.core.constants.Constants
|
||||
import ua.acclorite.book_story.presentation.core.constants.provideSupportedExtensions
|
||||
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.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 javax.inject.Inject
|
||||
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.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 ua.acclorite.book_story.domain.util.UIText
|
||||
import ua.acclorite.book_story.domain.ui.UIText
|
||||
|
||||
@Immutable
|
||||
data class Credit(
|
||||
|
|
@ -9,4 +9,4 @@ data class Credit(
|
|||
val source: String?,
|
||||
val credits: List<UIText>,
|
||||
val website: String?
|
||||
)
|
||||
)
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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 {
|
||||
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 {
|
||||
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 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.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import ua.acclorite.book_story.domain.util.OnNavigate
|
||||
|
||||
@Immutable
|
||||
data class HelpTip(
|
||||
@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
|
||||
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
package ua.acclorite.book_story.domain.model
|
||||
package ua.acclorite.book_story.domain.history
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import ua.acclorite.book_story.domain.library.book.Book
|
||||
|
||||
@Immutable
|
||||
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.StringRes
|
||||
import androidx.compose.runtime.Immutable
|
||||
import ua.acclorite.book_story.presentation.core.navigation.Screen
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
@Immutable
|
||||
data class NavigationItem(
|
||||
data class NavigatorItem(
|
||||
val screen: Screen,
|
||||
@StringRes val title: 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 androidx.compose.runtime.Immutable
|
||||
|
|
@ -11,10 +11,4 @@ data class Chapter(
|
|||
val title: String,
|
||||
val startIndex: Int,
|
||||
val endIndex: Int
|
||||
) : Parcelable
|
||||
|
||||
@Immutable
|
||||
data class ChapterWithText(
|
||||
val chapter: Chapter,
|
||||
val text: List<String>
|
||||
)
|
||||
) : Parcelable
|
||||
|
|
@ -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.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.ui.text.font.FontFamily
|
||||
import ua.acclorite.book_story.domain.util.UIText
|
||||
import ua.acclorite.book_story.domain.ui.UIText
|
||||
|
||||
@Immutable
|
||||
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
|
||||
|
||||
|
|
@ -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 {
|
||||
START, JUSTIFY, CENTER, END
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
package ua.acclorite.book_story.domain.repository
|
||||
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import ua.acclorite.book_story.domain.model.Book
|
||||
import ua.acclorite.book_story.domain.model.BookWithText
|
||||
import ua.acclorite.book_story.domain.model.BookWithTextAndCover
|
||||
import ua.acclorite.book_story.domain.model.Chapter
|
||||
import ua.acclorite.book_story.domain.library.book.Book
|
||||
import ua.acclorite.book_story.domain.library.book.BookWithText
|
||||
import ua.acclorite.book_story.domain.library.book.BookWithTextAndCover
|
||||
import ua.acclorite.book_story.domain.reader.Chapter
|
||||
import ua.acclorite.book_story.domain.util.CoverImage
|
||||
import ua.acclorite.book_story.domain.util.Resource
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
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 {
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package ua.acclorite.book_story.domain.repository
|
||||
|
||||
import androidx.datastore.preferences.core.Preferences
|
||||
import ua.acclorite.book_story.presentation.data.MainState
|
||||
import ua.acclorite.book_story.ui.main.MainState
|
||||
|
||||
interface DataStoreRepository {
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package ua.acclorite.book_story.domain.repository
|
||||
|
||||
import ua.acclorite.book_story.domain.model.NullableBook
|
||||
import ua.acclorite.book_story.domain.model.SelectableFile
|
||||
import ua.acclorite.book_story.domain.browse.SelectableFile
|
||||
import ua.acclorite.book_story.domain.library.book.NullableBook
|
||||
import java.io.File
|
||||
|
||||
interface FileSystemRepository {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
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 {
|
||||
|
||||
|
|
|
|||
|
|
@ -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.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.os.Parcelable
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
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.util.Resource
|
||||
import javax.inject.Inject
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
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.HistoryRepository
|
||||
import javax.inject.Inject
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
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 javax.inject.Inject
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
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 javax.inject.Inject
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
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 javax.inject.Inject
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
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 javax.inject.Inject
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
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 javax.inject.Inject
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
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 javax.inject.Inject
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
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.util.CoverImage
|
||||
import javax.inject.Inject
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
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 javax.inject.Inject
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
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 javax.inject.Inject
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
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 javax.inject.Inject
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
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 javax.inject.Inject
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
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 javax.inject.Inject
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package ua.acclorite.book_story.domain.use_case.data_store
|
||||
|
||||
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
|
||||
|
||||
class GetAllSettings @Inject constructor(
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
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 java.io.File
|
||||
import javax.inject.Inject
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
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 javax.inject.Inject
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
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 javax.inject.Inject
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
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 javax.inject.Inject
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
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 javax.inject.Inject
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
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 javax.inject.Inject
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
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) {
|
||||
class Success<T>(data: T?) : Resource<T>(data)
|
||||
class Error<T>(message: UIText, data: T? = null) : Resource<T>(data, message)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
package ua.acclorite.book_story.domain.util
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import ua.acclorite.book_story.presentation.core.navigation.Navigator
|
||||
|
||||
typealias CoverImage = Bitmap
|
||||
typealias Selected = Boolean
|
||||
typealias ID = Int
|
||||
typealias Route = String
|
||||
typealias OnNavigate = (Navigator.() -> Unit) -> Unit
|
||||
typealias BottomSheet = String
|
||||
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.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
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
|
||||
|
||||
/**
|
||||
* About Badge Item.
|
||||
*
|
||||
* @param badge [Badge].
|
||||
* @param onClick OnClick callback.
|
||||
*/
|
||||
@Composable
|
||||
fun AboutBadgeItem(
|
||||
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.Box
|
||||
|
|
@ -10,24 +10,17 @@ 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.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import ua.acclorite.book_story.R
|
||||
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.util.showToast
|
||||
import ua.acclorite.book_story.presentation.screens.about.data.AboutEvent
|
||||
import ua.acclorite.book_story.presentation.screens.about.data.AboutViewModel
|
||||
import ua.acclorite.book_story.ui.about.AboutEvent
|
||||
|
||||
/**
|
||||
* About Badges.
|
||||
* Links all ways to contact me.
|
||||
*
|
||||
* @param verticalPadding Vertical item padding.
|
||||
*/
|
||||
@Composable
|
||||
fun AboutBadges(verticalPadding: Dp = 18.dp) {
|
||||
val onEvent = AboutViewModel.getEvent()
|
||||
fun AboutBadges(
|
||||
navigateToBrowserPage: (AboutEvent.OnNavigateToBrowserPage) -> Unit
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
|
||||
Box(
|
||||
|
|
@ -36,11 +29,14 @@ fun AboutBadges(verticalPadding: Dp = 18.dp) {
|
|||
) {
|
||||
LazyRow(
|
||||
Modifier
|
||||
.padding(horizontal = 18.dp, vertical = verticalPadding),
|
||||
.padding(18.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(13.dp)
|
||||
) {
|
||||
items(Constants.provideAboutBadges(), key = { it.id }) { badge ->
|
||||
items(
|
||||
Constants.provideAboutBadges(),
|
||||
key = { it.id }
|
||||
) { badge ->
|
||||
AboutBadgeItem(badge = badge) {
|
||||
when (badge.id) {
|
||||
"tryzub" -> {
|
||||
|
|
@ -50,14 +46,10 @@ fun AboutBadges(verticalPadding: Dp = 18.dp) {
|
|||
|
||||
else -> {
|
||||
badge.url?.let {
|
||||
onEvent(
|
||||
navigateToBrowserPage(
|
||||
AboutEvent.OnNavigateToBrowserPage(
|
||||
it,
|
||||
context,
|
||||
noAppsFound = {
|
||||
context.getString(R.string.error_no_browser)
|
||||
.showToast(context = context, longToast = false)
|
||||
}
|
||||
page = it,
|
||||
context = context
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
@ -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.tween
|
||||
|
|
@ -21,20 +21,8 @@ import androidx.compose.ui.unit.Dp
|
|||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
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
|
||||
fun AboutItem(
|
||||
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