🚀 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:
Acclorite 2024-12-22 11:21:26 +02:00
parent 85712cf566
commit 8ddb378f47
464 changed files with 12824 additions and 11768 deletions

View file

@ -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" />

View file

@ -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()
}
}
}
}
}
}
}

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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 {

View file

@ -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

View file

@ -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 {

View file

@ -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

View file

@ -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 {

View file

@ -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

View 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

View file

@ -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

View 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
@ -70,12 +70,4 @@ class TextParserImpl @Inject constructor(
} }
} }
} }
} }

View file

@ -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

View file

@ -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

View 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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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()

View file

@ -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

View file

@ -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

View file

@ -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

View 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

View 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

View file

@ -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

View file

@ -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

View 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

View file

@ -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

View file

@ -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(
@ -9,4 +9,4 @@ data class Credit(
val source: String?, val source: String?,
val credits: List<UIText>, val credits: List<UIText>,
val website: String? val website: String?
) )

View file

@ -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

View file

@ -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

View file

@ -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,

View file

@ -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
)

View 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

View file

@ -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
) )

View file

@ -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

View file

@ -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(

View file

@ -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

View file

@ -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?
)

View file

@ -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>
)

View file

@ -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>
)

View file

@ -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
)
}

View file

@ -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
)

View file

@ -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
)

View file

@ -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
}

View file

@ -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>
)

View file

@ -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
)
}

View file

@ -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>>
)

View file

@ -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

View file

@ -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
}
}

View file

@ -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,

View file

@ -0,0 +1,8 @@
package ua.acclorite.book_story.domain.navigator
import androidx.compose.runtime.Composable
interface Screen {
@Composable
fun Content()
}

View file

@ -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
}

View file

@ -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
@ -11,10 +11,4 @@ data class Chapter(
val title: String, val title: String,
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>
)

View file

@ -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>
)

View file

@ -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
)

View file

@ -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

View file

@ -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(

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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 {

View file

@ -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 {

View file

@ -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 {

View file

@ -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 {

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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(

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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
}
}
}

View file

@ -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,

View file

@ -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)
}
) )
) )
} }

View file

@ -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
)
}

View file

@ -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
)
}
}
}

View file

@ -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,

View file

@ -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
)
}
}
}

View file

@ -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