diff --git a/.idea/misc.xml b/.idea/misc.xml index 8978d23d..ee7a3821 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,4 +1,13 @@ + + + + + + + + + diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 54050d3c..51cac9b0 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -16,7 +16,7 @@ android { minSdk = 26 targetSdk = 34 versionCode = 1 - versionName = "0.0.1" + versionName = "0.2.0" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { @@ -69,14 +69,29 @@ dependencies { implementation("androidx.compose.ui:ui-android:latest.release") implementation("androidx.compose.material3:material3") - // Debug - testImplementation("junit:junit:4.13.2") - androidTestImplementation("androidx.test.ext:junit:1.1.5") - androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") - androidTestImplementation(platform("androidx.compose:compose-bom:2023.08.00")) - androidTestImplementation("androidx.compose.ui:ui-test-junit4") - debugImplementation("androidx.compose.ui:ui-tooling") - debugImplementation("androidx.compose.ui:ui-test-manifest") + // Unit tests + testImplementation ("androidx.test:core:latest.release") + testImplementation ("junit:junit:latest.release") + testImplementation ("androidx.arch.core:core-testing:latest.release") + testImplementation ("org.jetbrains.kotlinx:kotlinx-coroutines-test:latest.release") + testImplementation ("com.google.truth:truth:1.2.0") + testImplementation ("androidx.test.ext:truth:1.5.0") + testImplementation ("com.squareup.okhttp3:mockwebserver:latest.release") + testImplementation ("io.mockk:mockk:latest.release") + debugImplementation ("androidx.compose.ui:ui-test-manifest:latest.release") + + // Instrumentation tests + androidTestImplementation ("com.google.dagger:hilt-android-testing:latest.release") + kaptAndroidTest ("com.google.dagger:hilt-android-compiler:latest.release") + androidTestImplementation ("junit:junit:latest.release") + androidTestImplementation ("org.jetbrains.kotlinx:kotlinx-coroutines-test:latest.release") + androidTestImplementation ("androidx.arch.core:core-testing:latest.release") + androidTestImplementation ("com.google.truth:truth:latest.release") + androidTestImplementation ("androidx.test.ext:junit:latest.release") + androidTestImplementation ("androidx.test:core-ktx:latest.release") + androidTestImplementation ("com.squareup.okhttp3:mockwebserver:latest.release") + androidTestImplementation ("io.mockk:mockk-android:latest.release") + androidTestImplementation ("androidx.test:runner:latest.release") // All dependencies implementation ("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.2") @@ -97,4 +112,7 @@ dependencies { // Datastore implementation ("androidx.datastore:datastore-preferences:latest.release") + + // Splash API + implementation ("androidx.core:core-splashscreen:latest.release") } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 8d22b2a4..0eae7a11 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,17 +7,17 @@ android:allowBackup="true" android:dataExtractionRules="@xml/data_extraction_rules" android:fullBackupContent="@xml/backup_rules" - android:icon="@mipmap/ic_launcher" + android:icon="@mipmap/app_icon" + android:roundIcon="@mipmap/app_icon_round" android:label="@string/app_name" - android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" - android:theme="@style/Theme.BooksHistoryResurrection" - tools:targetApi="31"> + android:theme="@style/Theme.Start.Splash" + android:enableOnBackInvokedCallback="true" + tools:targetApi="tiramisu"> + android:theme="@style/Theme.Start.Splash"> diff --git a/app/src/main/app_icon-playstore.png b/app/src/main/app_icon-playstore.png new file mode 100644 index 00000000..d8766d0a Binary files /dev/null and b/app/src/main/app_icon-playstore.png differ diff --git a/app/src/main/app_icon_mc-playstore.png b/app/src/main/app_icon_mc-playstore.png new file mode 100644 index 00000000..31e72bd8 Binary files /dev/null and b/app/src/main/app_icon_mc-playstore.png differ diff --git a/app/src/main/app_icon_monochromed-playstore.png b/app/src/main/app_icon_monochromed-playstore.png new file mode 100644 index 00000000..0448c62f Binary files /dev/null and b/app/src/main/app_icon_monochromed-playstore.png differ diff --git a/app/src/main/deleteme-playstore.png b/app/src/main/deleteme-playstore.png new file mode 100644 index 00000000..ee0066a6 Binary files /dev/null and b/app/src/main/deleteme-playstore.png differ diff --git a/app/src/main/java/com/acclorite/books_history/MainActivity.kt b/app/src/main/java/com/acclorite/books_history/MainActivity.kt index f9c3495e..17505eb0 100644 --- a/app/src/main/java/com/acclorite/books_history/MainActivity.kt +++ b/app/src/main/java/com/acclorite/books_history/MainActivity.kt @@ -4,20 +4,13 @@ import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.viewModels -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.material3.Text -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.stringResource -import androidx.datastore.core.DataStore -import androidx.lifecycle.viewmodel.compose.viewModel -import com.acclorite.books_history.data.use_case.ChangeLanguageImpl +import androidx.compose.runtime.collectAsState +import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import com.acclorite.books_history.presentation.MainViewModel import com.acclorite.books_history.presentation.NavigationHost import com.acclorite.books_history.presentation.Screen import com.acclorite.books_history.ui.theme.BooksHistoryResurrectionTheme +import com.acclorite.books_history.ui.theme.isDark import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint @@ -27,8 +20,21 @@ class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + mainViewModel.init(this) + installSplashScreen().apply { + setKeepOnScreenCondition { + !mainViewModel.isReady.value + } + } + setContent { - BooksHistoryResurrectionTheme { + val theme = mainViewModel.theme.collectAsState().value!! + val darkTheme = mainViewModel.darkTheme.collectAsState().value!! + + BooksHistoryResurrectionTheme( + theme = theme, + isDark = darkTheme.isDark() + ) { NavigationHost(startScreen = Screen.LIBRARY, this) { } diff --git a/app/src/main/java/com/acclorite/books_history/data/di/AppModule.kt b/app/src/main/java/com/acclorite/books_history/data/di/AppModule.kt index 83a83690..b96424d1 100644 --- a/app/src/main/java/com/acclorite/books_history/data/di/AppModule.kt +++ b/app/src/main/java/com/acclorite/books_history/data/di/AppModule.kt @@ -1,10 +1,6 @@ package com.acclorite.books_history.data.di import android.app.Application -import android.content.Context -import androidx.datastore.core.DataStore -import androidx.datastore.preferences.core.Preferences -import androidx.datastore.preferences.preferencesDataStore import androidx.room.Room import com.acclorite.books_history.data.local.room.BookDao import com.acclorite.books_history.data.local.room.BookDatabase diff --git a/app/src/main/java/com/acclorite/books_history/data/di/RepositoryModule.kt b/app/src/main/java/com/acclorite/books_history/data/di/RepositoryModule.kt index 282885ec..397e5bfe 100644 --- a/app/src/main/java/com/acclorite/books_history/data/di/RepositoryModule.kt +++ b/app/src/main/java/com/acclorite/books_history/data/di/RepositoryModule.kt @@ -2,6 +2,8 @@ package com.acclorite.books_history.data.di import com.acclorite.books_history.data.local.data_store.DataStore import com.acclorite.books_history.data.local.data_store.DataStoreImpl +import com.acclorite.books_history.data.mapper.BookMapper +import com.acclorite.books_history.data.mapper.BookMapperImpl import com.acclorite.books_history.data.repository.BookRepositoryImpl import com.acclorite.books_history.domain.repository.BookRepository import dagger.Binds @@ -24,4 +26,10 @@ abstract class RepositoryModule { abstract fun bindBookRepository( bookRepositoryImpl: BookRepositoryImpl ): BookRepository + + @Binds + @Singleton + abstract fun bindBookMapper( + bookMapperImpl: BookMapperImpl + ): BookMapper } \ No newline at end of file diff --git a/app/src/main/java/com/acclorite/books_history/data/di/UseCaseModule.kt b/app/src/main/java/com/acclorite/books_history/data/di/UseCaseModule.kt deleted file mode 100644 index 1554633b..00000000 --- a/app/src/main/java/com/acclorite/books_history/data/di/UseCaseModule.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.acclorite.books_history.data.di - -import com.acclorite.books_history.data.use_case.ChangeLanguageImpl -import com.acclorite.books_history.domain.use_case.ChangeLanguage -import dagger.Binds -import dagger.Module -import dagger.hilt.InstallIn -import dagger.hilt.components.SingletonComponent -import javax.inject.Singleton - -@Module -@InstallIn(SingletonComponent::class) -abstract class UseCaseModule { - - @Binds - abstract fun bindChangeLanguage( - changeLanguageImpl: ChangeLanguageImpl - ): ChangeLanguage -} \ No newline at end of file diff --git a/app/src/main/java/com/acclorite/books_history/data/mapper/BookMapper.kt b/app/src/main/java/com/acclorite/books_history/data/mapper/BookMapper.kt index e9a82de1..fef87947 100644 --- a/app/src/main/java/com/acclorite/books_history/data/mapper/BookMapper.kt +++ b/app/src/main/java/com/acclorite/books_history/data/mapper/BookMapper.kt @@ -4,7 +4,7 @@ import com.acclorite.books_history.data.local.dto.BookEntity import com.acclorite.books_history.domain.model.Book interface BookMapper { - fun Book.toBookEntity(): BookEntity + fun toBookEntity(book: Book): BookEntity - fun BookEntity.toBook(): Book + fun toBook(bookEntity: BookEntity): Book } \ No newline at end of file diff --git a/app/src/main/java/com/acclorite/books_history/data/mapper/BookMapperImpl.kt b/app/src/main/java/com/acclorite/books_history/data/mapper/BookMapperImpl.kt index e4982442..c62ef7b6 100644 --- a/app/src/main/java/com/acclorite/books_history/data/mapper/BookMapperImpl.kt +++ b/app/src/main/java/com/acclorite/books_history/data/mapper/BookMapperImpl.kt @@ -5,11 +5,11 @@ import com.acclorite.books_history.domain.model.Book import javax.inject.Inject class BookMapperImpl @Inject constructor(): BookMapper { - override fun Book.toBookEntity(): BookEntity { + override fun toBookEntity(book: Book): BookEntity { TODO("Not yet implemented") } - override fun BookEntity.toBook(): Book { + override fun toBook(bookEntity: BookEntity): Book { TODO("Not yet implemented") } } \ No newline at end of file diff --git a/app/src/main/java/com/acclorite/books_history/data/repository/BookRepositoryImpl.kt b/app/src/main/java/com/acclorite/books_history/data/repository/BookRepositoryImpl.kt index ff022f7f..f15ae168 100644 --- a/app/src/main/java/com/acclorite/books_history/data/repository/BookRepositoryImpl.kt +++ b/app/src/main/java/com/acclorite/books_history/data/repository/BookRepositoryImpl.kt @@ -3,7 +3,7 @@ package com.acclorite.books_history.data.repository import androidx.datastore.preferences.core.Preferences import com.acclorite.books_history.data.local.data_store.DataStore import com.acclorite.books_history.data.local.room.BookDao -import com.acclorite.books_history.data.mapper.toBookEntity +import com.acclorite.books_history.data.mapper.BookMapper import com.acclorite.books_history.domain.model.Book import com.acclorite.books_history.domain.repository.BookRepository import com.acclorite.books_history.util.Resource @@ -14,15 +14,17 @@ import javax.inject.Singleton @Singleton class BookRepositoryImpl @Inject constructor( private val database: BookDao, - private val dataStore: DataStore -): BookRepository { + private val dataStore: DataStore, + + private val bookMapper: BookMapper +) : BookRepository { override suspend fun getBooks(query: String): Flow>> { TODO("Not yet implemented") } override suspend fun insertBooks(books: List) { - database.insertBooks(books.map { it.toBookEntity() }) + database.insertBooks(books.map { bookMapper.toBookEntity(it) }) } override suspend fun updateBooks(books: List) { diff --git a/app/src/main/java/com/acclorite/books_history/data/use_case/ChangeLanguageImpl.kt b/app/src/main/java/com/acclorite/books_history/data/use_case/ChangeLanguageImpl.kt deleted file mode 100644 index b07f56e2..00000000 --- a/app/src/main/java/com/acclorite/books_history/data/use_case/ChangeLanguageImpl.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.acclorite.books_history.data.use_case - -import androidx.activity.ComponentActivity -import com.acclorite.books_history.domain.use_case.ChangeLanguage -import java.util.Locale -import javax.inject.Inject - -class ChangeLanguageImpl @Inject constructor() : ChangeLanguage { - override fun execute(language: String, activity: ComponentActivity) { - val config = activity.resources.configuration - val resources = activity.resources - val locale = Locale(language) - - Locale.setDefault(locale) - config.setLocale(locale) - - activity.createConfigurationContext(config) - resources.updateConfiguration( - config, - resources.displayMetrics - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/acclorite/books_history/domain/model/Book.kt b/app/src/main/java/com/acclorite/books_history/domain/model/Book.kt index 243945c8..d70360d3 100644 --- a/app/src/main/java/com/acclorite/books_history/domain/model/Book.kt +++ b/app/src/main/java/com/acclorite/books_history/domain/model/Book.kt @@ -1,8 +1,10 @@ package com.acclorite.books_history.domain.model import android.graphics.Bitmap +import androidx.compose.runtime.Immutable import java.io.File +@Immutable data class Book( val id: Int, val title: String, diff --git a/app/src/main/java/com/acclorite/books_history/domain/model/FontWithName.kt b/app/src/main/java/com/acclorite/books_history/domain/model/FontWithName.kt new file mode 100644 index 00000000..3c46dae5 --- /dev/null +++ b/app/src/main/java/com/acclorite/books_history/domain/model/FontWithName.kt @@ -0,0 +1,10 @@ +package com.acclorite.books_history.domain.model + +import androidx.compose.runtime.Immutable +import androidx.compose.ui.text.font.FontFamily + +@Immutable +data class FontWithName( + val fontName: String, + val font: FontFamily +) \ No newline at end of file diff --git a/app/src/main/java/com/acclorite/books_history/domain/use_case/ChangeLanguage.kt b/app/src/main/java/com/acclorite/books_history/domain/use_case/ChangeLanguage.kt index 957cee71..dc4ffe75 100644 --- a/app/src/main/java/com/acclorite/books_history/domain/use_case/ChangeLanguage.kt +++ b/app/src/main/java/com/acclorite/books_history/domain/use_case/ChangeLanguage.kt @@ -1,11 +1,29 @@ package com.acclorite.books_history.domain.use_case import androidx.activity.ComponentActivity -import androidx.annotation.Size +import com.acclorite.books_history.domain.repository.BookRepository +import com.acclorite.books_history.util.DataStoreConstants +import java.util.Locale +import javax.inject.Inject -interface ChangeLanguage { - fun execute( - @Size(max = 2) language: String, - activity: ComponentActivity - ) +class ChangeLanguage @Inject constructor(private val repository: BookRepository) { + suspend fun execute(language: String, activity: ComponentActivity) { + val config = activity.resources.configuration + val resources = activity.resources + val locale = Locale(language) + + Locale.setDefault(locale) + config.setLocale(locale) + + activity.createConfigurationContext(config) + resources.updateConfiguration( + config, + resources.displayMetrics + ) + + repository.putDataToDataStore( + DataStoreConstants.LANGUAGE, + language + ) + } } \ No newline at end of file diff --git a/app/src/main/java/com/acclorite/books_history/domain/use_case/GetDatastore.kt b/app/src/main/java/com/acclorite/books_history/domain/use_case/GetDatastore.kt new file mode 100644 index 00000000..c3cec0c8 --- /dev/null +++ b/app/src/main/java/com/acclorite/books_history/domain/use_case/GetDatastore.kt @@ -0,0 +1,13 @@ +package com.acclorite.books_history.domain.use_case + +import androidx.datastore.preferences.core.Preferences +import com.acclorite.books_history.domain.repository.BookRepository +import kotlinx.coroutines.flow.Flow +import javax.inject.Inject + +class GetDatastore @Inject constructor(private val repository: BookRepository) { + + suspend fun execute (key: Preferences.Key, defaultValue: T): Flow { + return repository.retrieveDataFromDataStore(key, defaultValue) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/acclorite/books_history/domain/use_case/InsertBooks.kt b/app/src/main/java/com/acclorite/books_history/domain/use_case/InsertBooks.kt new file mode 100644 index 00000000..8fde956b --- /dev/null +++ b/app/src/main/java/com/acclorite/books_history/domain/use_case/InsertBooks.kt @@ -0,0 +1,11 @@ +package com.acclorite.books_history.domain.use_case + +import com.acclorite.books_history.domain.model.Book +import com.acclorite.books_history.domain.repository.BookRepository +import javax.inject.Inject + +class InsertBooks @Inject constructor(private val repository: BookRepository) { + suspend fun execute(books: List) { + repository.insertBooks(books) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/acclorite/books_history/domain/use_case/SetDatastore.kt b/app/src/main/java/com/acclorite/books_history/domain/use_case/SetDatastore.kt new file mode 100644 index 00000000..a5f738b4 --- /dev/null +++ b/app/src/main/java/com/acclorite/books_history/domain/use_case/SetDatastore.kt @@ -0,0 +1,12 @@ +package com.acclorite.books_history.domain.use_case + +import androidx.datastore.preferences.core.Preferences +import com.acclorite.books_history.domain.repository.BookRepository +import javax.inject.Inject + +class SetDatastore @Inject constructor(private val repository: BookRepository) { + + suspend fun execute (key: Preferences.Key, value: T) { + repository.putDataToDataStore(key, value) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/acclorite/books_history/presentation/MainViewModel.kt b/app/src/main/java/com/acclorite/books_history/presentation/MainViewModel.kt index 0e042594..f36e5def 100644 --- a/app/src/main/java/com/acclorite/books_history/presentation/MainViewModel.kt +++ b/app/src/main/java/com/acclorite/books_history/presentation/MainViewModel.kt @@ -1,10 +1,28 @@ package com.acclorite.books_history.presentation +import android.os.Build +import androidx.activity.ComponentActivity +import androidx.compose.ui.graphics.Color import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel -import com.acclorite.books_history.domain.repository.BookRepository +import androidx.lifecycle.viewModelScope import com.acclorite.books_history.domain.use_case.ChangeLanguage +import com.acclorite.books_history.domain.use_case.GetDatastore +import com.acclorite.books_history.domain.use_case.SetDatastore +import com.acclorite.books_history.ui.theme.DarkTheme +import com.acclorite.books_history.ui.theme.Theme +import com.acclorite.books_history.ui.theme.toDarkTheme +import com.acclorite.books_history.ui.theme.toTheme +import com.acclorite.books_history.util.Constants +import com.acclorite.books_history.util.DataStoreConstants import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.launch +import java.util.Locale import javax.inject.Inject /** @@ -13,10 +31,276 @@ import javax.inject.Inject @HiltViewModel class MainViewModel @Inject constructor( private val stateHandle: SavedStateHandle, - private val repository: BookRepository, - private val changeLanguage: ChangeLanguage + private val getDatastore: GetDatastore, + private val setDatastore: SetDatastore, + private val changeLanguage: ChangeLanguage, ) : ViewModel() { + private val _isReady = MutableStateFlow(false) + val isReady = _isReady.asStateFlow() + + /* -- Language ----------------------------------------------------- */ + private var _language: String = + stateHandle[Constants.LANGUAGE] ?: Locale.getDefault().language + set(value) { + field = value + stateHandle[Constants.LANGUAGE] = value + } + val language: StateFlow + get() = stateHandle.getStateFlow(Constants.LANGUAGE, null) + + /* -- Theme -------------------------------------------------------- */ + private var _theme: Theme = + stateHandle[Constants.THEME] ?: + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) Theme.DYNAMIC else Theme.BLUE + set(value) { + field = value + stateHandle[Constants.THEME] = value + } + val theme: StateFlow + get() = stateHandle.getStateFlow(Constants.THEME, null) + + /* -- Dark Theme --------------------------------------------------- */ + private var _darkTheme: DarkTheme = + stateHandle[Constants.DARK_THEME] ?: DarkTheme.FOLLOW_SYSTEM + set(value) { + field = value + stateHandle[Constants.DARK_THEME] = value + } + val darkTheme: StateFlow + get() = stateHandle.getStateFlow(Constants.DARK_THEME, null) + + /* -- Show Start Screen -------------------------------------------- */ + private var _showStartScreen: Boolean = + stateHandle[Constants.SHOW_START_SCREEN] ?: true + set(value) { + field = value + stateHandle[Constants.SHOW_START_SCREEN] = value + } + val showStartScreen: StateFlow + get() = stateHandle.getStateFlow(Constants.SHOW_START_SCREEN, null) + + /* -- Background Color --------------------------------------------- */ + private var _backgroundColor: Long = + stateHandle[Constants.BACKGROUND_COLOR] ?: Color.DarkGray.value.toLong() + set(value) { + field = value + stateHandle[Constants.BACKGROUND_COLOR] = value + } + val backgroundColor: StateFlow + get() = stateHandle.getStateFlow(Constants.BACKGROUND_COLOR, null) + + /* -- Font Color --------------------------------------------------- */ + private var _fontColor: Long = + stateHandle[Constants.FONT_COLOR] ?: Color.LightGray.value.toLong() + set(value) { + field = value + stateHandle[Constants.FONT_COLOR] = value + } + val fontColor: StateFlow + get() = stateHandle.getStateFlow(Constants.FONT_COLOR, null) + + /* -- Font Family -------------------------------------------------- */ + private var _fontFamily: String = + stateHandle[Constants.FONT] ?: Constants.FONTS[0].fontName + set(value) { + field = value + stateHandle[Constants.FONT] = value + } + val fontFamily: StateFlow + get() = stateHandle.getStateFlow(Constants.FONT, null) + + /* -- Is Italic ---------------------------------------------------- */ + private var _isItalic: Boolean = + stateHandle[Constants.IS_ITALIC] ?: false + set(value) { + field = value + stateHandle[Constants.IS_ITALIC] = value + } + val isItalic: StateFlow + get() = stateHandle.getStateFlow(Constants.IS_ITALIC, null) + + /* -- Font Size ---------------------------------------------------- */ + private var _fontSize: Int = + stateHandle[Constants.FONT_SIZE] ?: 16 + set(value) { + field = value + stateHandle[Constants.FONT_SIZE] = value + } + val fontSize: StateFlow + get() = stateHandle.getStateFlow(Constants.FONT_SIZE, null) + + /* -- Line Height -------------------------------------------------- */ + private var _lineHeight: Int = + stateHandle[Constants.LINE_HEIGHT] ?: 4 + set(value) { + field = value + stateHandle[Constants.LINE_HEIGHT] = value + } + val lineHeight: StateFlow + get() = stateHandle.getStateFlow(Constants.LINE_HEIGHT, null) + + /* -- Paragraph Height --------------------------------------------- */ + private var _paragraphHeight: Int = + stateHandle[Constants.PARAGRAPH_HEIGHT] ?: 8 + set(value) { + field = value + stateHandle[Constants.PARAGRAPH_HEIGHT] = value + } + val paragraphHeight: StateFlow + get() = stateHandle.getStateFlow(Constants.PARAGRAPH_HEIGHT, null) + + /* -- Paragraph Indentation ---------------------------------------- */ + private var _paragraphIndentation: Boolean = + stateHandle[Constants.PARAGRAPH_INDENTATION] ?: false + set(value) { + field = value + stateHandle[Constants.PARAGRAPH_INDENTATION] = value + } + val paragraphIndentation: StateFlow + get() = stateHandle.getStateFlow(Constants.PARAGRAPH_INDENTATION, null) + /* --------------------------------------------------------------- */ + + + fun init(activity: ComponentActivity) { + val isDataReady = combine( + language, theme, darkTheme, showStartScreen, backgroundColor, + fontColor, fontFamily, isItalic, fontSize, lineHeight, + paragraphHeight, paragraphIndentation + ) { values -> + values.all { it != null } + } + + viewModelScope.launch { + isDataReady.collect { bool -> + if (bool) { + _isReady.value = true + } + } + } + + // Language + viewModelScope.launch(Dispatchers.IO) { + getDatastore + .execute(DataStoreConstants.LANGUAGE, _language) + .collect { + changeLanguage.execute(it, activity) + _language = it + } + } + + // Theme + viewModelScope.launch(Dispatchers.IO) { + getDatastore + .execute(DataStoreConstants.THEME, _theme.toString()) + .collect { + setDatastore.execute(DataStoreConstants.THEME, it) + _theme = it.toTheme() + } + } + + // Dark Theme + viewModelScope.launch(Dispatchers.IO) { + getDatastore + .execute(DataStoreConstants.DARK_THEME, _darkTheme.toString()) + .collect { + setDatastore.execute(DataStoreConstants.DARK_THEME, it) + _darkTheme = it.toDarkTheme() + } + } + + // Show Start Screen + viewModelScope.launch(Dispatchers.IO) { + getDatastore + .execute(DataStoreConstants.SHOW_START_SCREEN, _showStartScreen) + .collect { + setDatastore.execute(DataStoreConstants.SHOW_START_SCREEN, it) + _showStartScreen = it + } + } + + // Background Color + viewModelScope.launch(Dispatchers.IO) { + getDatastore + .execute(DataStoreConstants.BACKGROUND_COLOR, _backgroundColor) + .collect { + setDatastore.execute(DataStoreConstants.BACKGROUND_COLOR, it) + _backgroundColor = it + } + } + + // Font Color + viewModelScope.launch(Dispatchers.IO) { + getDatastore + .execute(DataStoreConstants.FONT_COLOR, _fontColor) + .collect { + setDatastore.execute(DataStoreConstants.FONT_COLOR, it) + _fontColor = it + } + } + + // Font Family + viewModelScope.launch(Dispatchers.IO) { + getDatastore + .execute(DataStoreConstants.FONT, _fontFamily) + .collect { + setDatastore.execute(DataStoreConstants.FONT, it) + _fontFamily = Constants.FONTS.find { font -> font.fontName == it }?.fontName + ?: Constants.FONTS[0].fontName + } + } + + // Font Style + viewModelScope.launch(Dispatchers.IO) { + getDatastore + .execute(DataStoreConstants.IS_ITALIC, _isItalic) + .collect { + setDatastore.execute(DataStoreConstants.IS_ITALIC, it) + _isItalic = it + } + } + + // Font Size + viewModelScope.launch(Dispatchers.IO) { + getDatastore + .execute(DataStoreConstants.FONT_SIZE, _fontSize) + .collect { + setDatastore.execute(DataStoreConstants.FONT_SIZE, it) + _fontSize = it + } + } + + // Line Height + viewModelScope.launch(Dispatchers.IO) { + getDatastore + .execute(DataStoreConstants.LINE_HEIGHT, _lineHeight) + .collect { + setDatastore.execute(DataStoreConstants.LINE_HEIGHT, it) + _lineHeight = it + } + } + + // Paragraph Height + viewModelScope.launch(Dispatchers.IO) { + getDatastore + .execute(DataStoreConstants.PARAGRAPH_HEIGHT, _paragraphHeight) + .collect { + setDatastore.execute(DataStoreConstants.PARAGRAPH_HEIGHT, it) + _paragraphHeight = it + } + } + + // Paragraph Indentation + viewModelScope.launch(Dispatchers.IO) { + getDatastore + .execute(DataStoreConstants.PARAGRAPH_INDENTATION, _paragraphIndentation) + .collect { + setDatastore.execute(DataStoreConstants.PARAGRAPH_INDENTATION, it) + _paragraphIndentation = it + } + } + + } } \ No newline at end of file diff --git a/app/src/main/java/com/acclorite/books_history/presentation/Navigation.kt b/app/src/main/java/com/acclorite/books_history/presentation/Navigation.kt index 96f0f110..914e8425 100644 --- a/app/src/main/java/com/acclorite/books_history/presentation/Navigation.kt +++ b/app/src/main/java/com/acclorite/books_history/presentation/Navigation.kt @@ -1,7 +1,6 @@ package com.acclorite.books_history.presentation import android.annotation.SuppressLint -import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.BackHandler import androidx.activity.viewModels @@ -20,12 +19,9 @@ import androidx.compose.runtime.collectAsState import androidx.compose.runtime.mutableStateListOf import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.lifecycle.AbstractSavedStateViewModelFactory import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel -import androidx.lifecycle.createSavedStateHandle import androidx.lifecycle.viewModelScope -import androidx.savedstate.SavedStateRegistryOwner import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject @@ -34,7 +30,6 @@ import dagger.hilt.android.lifecycle.withCreationCallback import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch -import javax.inject.Inject private const val CURRENT_SCREEN = "current_screen" diff --git a/app/src/main/java/com/acclorite/books_history/ui/theme/BlueTheme.kt b/app/src/main/java/com/acclorite/books_history/ui/theme/BlueTheme.kt new file mode 100644 index 00000000..7d45c48f --- /dev/null +++ b/app/src/main/java/com/acclorite/books_history/ui/theme/BlueTheme.kt @@ -0,0 +1,137 @@ +package com.acclorite.books_history.ui.theme + +import androidx.compose.material3.ColorScheme +import androidx.compose.material3.darkColorScheme +import androidx.compose.material3.lightColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.Color + +private val md_theme_light_primary = Color(0xFF005DB8) +private val md_theme_light_onPrimary = Color(0xFFFFFFFF) +private val md_theme_light_primaryContainer = Color(0xFFD6E3FF) +private val md_theme_light_onPrimaryContainer = Color(0xFF001B3E) +private val md_theme_light_secondary = Color(0xFF565F71) +private val md_theme_light_onSecondary = Color(0xFFFFFFFF) +private val md_theme_light_secondaryContainer = Color(0xFFDAE2F9) +private val md_theme_light_onSecondaryContainer = Color(0xFF131C2B) +private val md_theme_light_tertiary = Color(0xFF6F5575) +private val md_theme_light_onTertiary = Color(0xFFFFFFFF) +private val md_theme_light_tertiaryContainer = Color(0xFFF9D8FD) +private val md_theme_light_onTertiaryContainer = Color(0xFF28132E) +private val md_theme_light_error = Color(0xFFBA1A1A) +private val md_theme_light_errorContainer = Color(0xFFFFDAD6) +private val md_theme_light_onError = Color(0xFFFFFFFF) +private val md_theme_light_onErrorContainer = Color(0xFF410002) +private val md_theme_light_background = Color(0xFFFDFBFF) +private val md_theme_light_onBackground = Color(0xFF1A1B1E) +private val md_theme_light_surface = Color(0xFFFDFBFF) +private val md_theme_light_onSurface = Color(0xFF1A1B1E) +private val md_theme_light_surfaceVariant = Color(0xFFE0E2EC) +private val md_theme_light_onSurfaceVariant = Color(0xFF44474E) +private val md_theme_light_outline = Color(0xFF74777F) +private val md_theme_light_inverseOnSurface = Color(0xFFF1F0F4) +private val md_theme_light_inverseSurface = Color(0xFF2F3033) +private val md_theme_light_inversePrimary = Color(0xFFAAC7FF) +private val md_theme_light_surfaceTint = Color(0xFF005DB8) +private val md_theme_light_outlineVariant = Color(0xFFC4C6D0) +private val md_theme_light_scrim = Color(0xFF000000) + +private val md_theme_dark_primary = Color(0xFFAAC7FF) +private val md_theme_dark_onPrimary = Color(0xFF002F64) +private val md_theme_dark_primaryContainer = Color(0xFF00458D) +private val md_theme_dark_onPrimaryContainer = Color(0xFFD6E3FF) +private val md_theme_dark_secondary = Color(0xFFBEC6DC) +private val md_theme_dark_onSecondary = Color(0xFF283141) +private val md_theme_dark_secondaryContainer = Color(0xFF3E4759) +private val md_theme_dark_onSecondaryContainer = Color(0xFFDAE2F9) +private val md_theme_dark_tertiary = Color(0xFFDCBCE0) +private val md_theme_dark_onTertiary = Color(0xFF3F2844) +private val md_theme_dark_tertiaryContainer = Color(0xFF573E5C) +private val md_theme_dark_onTertiaryContainer = Color(0xFFF9D8FD) +private val md_theme_dark_error = Color(0xFFFFB4AB) +private val md_theme_dark_errorContainer = Color(0xFF93000A) +private val md_theme_dark_onError = Color(0xFF690005) +private val md_theme_dark_onErrorContainer = Color(0xFFFFDAD6) +private val md_theme_dark_background = Color(0xFF1A1B1E) +private val md_theme_dark_onBackground = Color(0xFFE3E2E6) +private val md_theme_dark_surface = Color(0xFF1A1B1E) +private val md_theme_dark_onSurface = Color(0xFFE3E2E6) +private val md_theme_dark_surfaceVariant = Color(0xFF44474E) +private val md_theme_dark_onSurfaceVariant = Color(0xFFC4C6D0) +private val md_theme_dark_outline = Color(0xFF8E9099) +private val md_theme_dark_inverseOnSurface = Color(0xFF1A1B1E) +private val md_theme_dark_inverseSurface = Color(0xFFE3E2E6) +private val md_theme_dark_inversePrimary = Color(0xFF005DB8) +private val md_theme_dark_surfaceTint = Color(0xFFAAC7FF) +private val md_theme_dark_outlineVariant = Color(0xFF44474E) +private val md_theme_dark_scrim = Color(0xFF000000) + + +@Composable +fun blueTheme(isDark: Boolean): ColorScheme { + return if (isDark) { + darkColorScheme( + primary = md_theme_dark_primary, + onPrimary = md_theme_dark_onPrimary, + primaryContainer = md_theme_dark_primaryContainer, + onPrimaryContainer = md_theme_dark_onPrimaryContainer, + secondary = md_theme_dark_secondary, + onSecondary = md_theme_dark_onSecondary, + secondaryContainer = md_theme_dark_secondaryContainer, + onSecondaryContainer = md_theme_dark_onSecondaryContainer, + tertiary = md_theme_dark_tertiary, + onTertiary = md_theme_dark_onTertiary, + tertiaryContainer = md_theme_dark_tertiaryContainer, + onTertiaryContainer = md_theme_dark_onTertiaryContainer, + error = md_theme_dark_error, + errorContainer = md_theme_dark_errorContainer, + onError = md_theme_dark_onError, + onErrorContainer = md_theme_dark_onErrorContainer, + background = md_theme_dark_background, + onBackground = md_theme_dark_onBackground, + surface = md_theme_dark_surface, + onSurface = md_theme_dark_onSurface, + surfaceVariant = md_theme_dark_surfaceVariant, + onSurfaceVariant = md_theme_dark_onSurfaceVariant, + outline = md_theme_dark_outline, + inverseOnSurface = md_theme_dark_inverseOnSurface, + inverseSurface = md_theme_dark_inverseSurface, + inversePrimary = md_theme_dark_inversePrimary, + surfaceTint = md_theme_dark_surfaceTint, + outlineVariant = md_theme_dark_outlineVariant, + scrim = md_theme_dark_scrim + ) + } else { + lightColorScheme( + primary = md_theme_light_primary, + onPrimary = md_theme_light_onPrimary, + primaryContainer = md_theme_light_primaryContainer, + onPrimaryContainer = md_theme_light_onPrimaryContainer, + secondary = md_theme_light_secondary, + onSecondary = md_theme_light_onSecondary, + secondaryContainer = md_theme_light_secondaryContainer, + onSecondaryContainer = md_theme_light_onSecondaryContainer, + tertiary = md_theme_light_tertiary, + onTertiary = md_theme_light_onTertiary, + tertiaryContainer = md_theme_light_tertiaryContainer, + onTertiaryContainer = md_theme_light_onTertiaryContainer, + error = md_theme_light_error, + errorContainer = md_theme_light_errorContainer, + onError = md_theme_light_onError, + onErrorContainer = md_theme_light_onErrorContainer, + background = md_theme_light_background, + onBackground = md_theme_light_onBackground, + surface = md_theme_light_surface, + onSurface = md_theme_light_onSurface, + surfaceVariant = md_theme_light_surfaceVariant, + onSurfaceVariant = md_theme_light_onSurfaceVariant, + outline = md_theme_light_outline, + inverseOnSurface = md_theme_light_inverseOnSurface, + inverseSurface = md_theme_light_inverseSurface, + inversePrimary = md_theme_light_inversePrimary, + surfaceTint = md_theme_light_surfaceTint, + outlineVariant = md_theme_light_outlineVariant, + scrim = md_theme_light_scrim + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/acclorite/books_history/ui/theme/Color.kt b/app/src/main/java/com/acclorite/books_history/ui/theme/Color.kt index 7e2537eb..6fd8bacc 100644 --- a/app/src/main/java/com/acclorite/books_history/ui/theme/Color.kt +++ b/app/src/main/java/com/acclorite/books_history/ui/theme/Color.kt @@ -1,11 +1,70 @@ package com.acclorite.books_history.ui.theme -import androidx.compose.ui.graphics.Color +import android.annotation.SuppressLint +import androidx.compose.material3.ColorScheme +import androidx.compose.material3.dynamicDarkColorScheme +import androidx.compose.material3.dynamicLightColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.platform.LocalContext -val Purple80 = Color(0xFFD0BCFF) -val PurpleGrey80 = Color(0xFFCCC2DC) -val Pink80 = Color(0xFFEFB8C8) +enum class Theme { + DYNAMIC, + BLUE, + PURPLE, + GREEN, + PINK +} -val Purple40 = Color(0xFF6650a4) -val PurpleGrey40 = Color(0xFF625b71) -val Pink40 = Color(0xFF7D5260) \ No newline at end of file +/** + * Converting [String] into [Theme]. + */ +fun String.toTheme(): Theme { + return when (this) { + "DYNAMIC" -> Theme.DYNAMIC + "PURPLE" -> Theme.PURPLE + "GREEN" -> Theme.GREEN + "PINK" -> Theme.PINK + else -> Theme.BLUE + } +} + +/** + * Creates a colorscheme based on [Theme]. + * + * @param theme a [Theme]. + * + * @return a [ColorScheme]. + */ +@SuppressLint("NewApi") +@Composable +fun colorScheme(theme: Theme, darkTheme: Boolean): ColorScheme { + when (theme) { + Theme.DYNAMIC -> { + /* Dynamic Theme */ + return if (darkTheme) + dynamicDarkColorScheme(LocalContext.current) + else + dynamicLightColorScheme(LocalContext.current) + } + + Theme.BLUE -> { + /* Blue Theme */ + return blueTheme(isDark = darkTheme) + } + + Theme.PURPLE -> { + /* Purple Theme */ + return purpleTheme(isDark = darkTheme) + } + + Theme.GREEN -> { + /* Green Theme */ + return greenTheme(isDark = darkTheme) + } + + else -> { + /* Pink Theme */ + return pinkTheme(isDark = darkTheme) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/acclorite/books_history/ui/theme/GreenTheme.kt b/app/src/main/java/com/acclorite/books_history/ui/theme/GreenTheme.kt new file mode 100644 index 00000000..024c1042 --- /dev/null +++ b/app/src/main/java/com/acclorite/books_history/ui/theme/GreenTheme.kt @@ -0,0 +1,136 @@ +package com.acclorite.books_history.ui.theme + +import androidx.compose.material3.ColorScheme +import androidx.compose.material3.darkColorScheme +import androidx.compose.material3.lightColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.Color + +private val md_theme_light_primary = Color(0xFF006C50) +private val md_theme_light_onPrimary = Color(0xFFFFFFFF) +private val md_theme_light_primaryContainer = Color(0xFF85F8CC) +private val md_theme_light_onPrimaryContainer = Color(0xFF002116) +private val md_theme_light_secondary = Color(0xFF4C6359) +private val md_theme_light_onSecondary = Color(0xFFFFFFFF) +private val md_theme_light_secondaryContainer = Color(0xFFCEE9DB) +private val md_theme_light_onSecondaryContainer = Color(0xFF092017) +private val md_theme_light_tertiary = Color(0xFF3F6374) +private val md_theme_light_onTertiary = Color(0xFFFFFFFF) +private val md_theme_light_tertiaryContainer = Color(0xFFC2E8FD) +private val md_theme_light_onTertiaryContainer = Color(0xFF001F2A) +private val md_theme_light_error = Color(0xFFBA1A1A) +private val md_theme_light_errorContainer = Color(0xFFFFDAD6) +private val md_theme_light_onError = Color(0xFFFFFFFF) +private val md_theme_light_onErrorContainer = Color(0xFF410002) +private val md_theme_light_background = Color(0xFFFBFDF9) +private val md_theme_light_onBackground = Color(0xFF191C1A) +private val md_theme_light_surface = Color(0xFFFBFDF9) +private val md_theme_light_onSurface = Color(0xFF191C1A) +private val md_theme_light_surfaceVariant = Color(0xFFDBE5DE) +private val md_theme_light_onSurfaceVariant = Color(0xFF404944) +private val md_theme_light_outline = Color(0xFF707974) +private val md_theme_light_inverseOnSurface = Color(0xFFEFF1EE) +private val md_theme_light_inverseSurface = Color(0xFF2E312F) +private val md_theme_light_inversePrimary = Color(0xFF67DBB1) +private val md_theme_light_surfaceTint = Color(0xFF006C50) +private val md_theme_light_outlineVariant = Color(0xFFBFC9C2) +private val md_theme_light_scrim = Color(0xFF000000) + +private val md_theme_dark_primary = Color(0xFF67DBB1) +private val md_theme_dark_onPrimary = Color(0xFF003828) +private val md_theme_dark_primaryContainer = Color(0xFF00513B) +private val md_theme_dark_onPrimaryContainer = Color(0xFF85F8CC) +private val md_theme_dark_secondary = Color(0xFFB3CCBF) +private val md_theme_dark_onSecondary = Color(0xFF1E352C) +private val md_theme_dark_secondaryContainer = Color(0xFF354B41) +private val md_theme_dark_onSecondaryContainer = Color(0xFFCEE9DB) +private val md_theme_dark_tertiary = Color(0xFFA6CCE0) +private val md_theme_dark_onTertiary = Color(0xFF093544) +private val md_theme_dark_tertiaryContainer = Color(0xFF264B5C) +private val md_theme_dark_onTertiaryContainer = Color(0xFFC2E8FD) +private val md_theme_dark_error = Color(0xFFFFB4AB) +private val md_theme_dark_errorContainer = Color(0xFF93000A) +private val md_theme_dark_onError = Color(0xFF690005) +private val md_theme_dark_onErrorContainer = Color(0xFFFFDAD6) +private val md_theme_dark_background = Color(0xFF191C1A) +private val md_theme_dark_onBackground = Color(0xFFE1E3DF) +private val md_theme_dark_surface = Color(0xFF191C1A) +private val md_theme_dark_onSurface = Color(0xFFE1E3DF) +private val md_theme_dark_surfaceVariant = Color(0xFF404944) +private val md_theme_dark_onSurfaceVariant = Color(0xFFBFC9C2) +private val md_theme_dark_outline = Color(0xFF89938D) +private val md_theme_dark_inverseOnSurface = Color(0xFF191C1A) +private val md_theme_dark_inverseSurface = Color(0xFFE1E3DF) +private val md_theme_dark_inversePrimary = Color(0xFF006C50) +private val md_theme_dark_surfaceTint = Color(0xFF67DBB1) +private val md_theme_dark_outlineVariant = Color(0xFF404944) +private val md_theme_dark_scrim = Color(0xFF000000) + +@Composable +fun greenTheme(isDark: Boolean): ColorScheme { + return if (isDark) { + darkColorScheme( + primary = md_theme_dark_primary, + onPrimary = md_theme_dark_onPrimary, + primaryContainer = md_theme_dark_primaryContainer, + onPrimaryContainer = md_theme_dark_onPrimaryContainer, + secondary = md_theme_dark_secondary, + onSecondary = md_theme_dark_onSecondary, + secondaryContainer = md_theme_dark_secondaryContainer, + onSecondaryContainer = md_theme_dark_onSecondaryContainer, + tertiary = md_theme_dark_tertiary, + onTertiary = md_theme_dark_onTertiary, + tertiaryContainer = md_theme_dark_tertiaryContainer, + onTertiaryContainer = md_theme_dark_onTertiaryContainer, + error = md_theme_dark_error, + errorContainer = md_theme_dark_errorContainer, + onError = md_theme_dark_onError, + onErrorContainer = md_theme_dark_onErrorContainer, + background = md_theme_dark_background, + onBackground = md_theme_dark_onBackground, + surface = md_theme_dark_surface, + onSurface = md_theme_dark_onSurface, + surfaceVariant = md_theme_dark_surfaceVariant, + onSurfaceVariant = md_theme_dark_onSurfaceVariant, + outline = md_theme_dark_outline, + inverseOnSurface = md_theme_dark_inverseOnSurface, + inverseSurface = md_theme_dark_inverseSurface, + inversePrimary = md_theme_dark_inversePrimary, + surfaceTint = md_theme_dark_surfaceTint, + outlineVariant = md_theme_dark_outlineVariant, + scrim = md_theme_dark_scrim + ) + } else { + lightColorScheme( + primary = md_theme_light_primary, + onPrimary = md_theme_light_onPrimary, + primaryContainer = md_theme_light_primaryContainer, + onPrimaryContainer = md_theme_light_onPrimaryContainer, + secondary = md_theme_light_secondary, + onSecondary = md_theme_light_onSecondary, + secondaryContainer = md_theme_light_secondaryContainer, + onSecondaryContainer = md_theme_light_onSecondaryContainer, + tertiary = md_theme_light_tertiary, + onTertiary = md_theme_light_onTertiary, + tertiaryContainer = md_theme_light_tertiaryContainer, + onTertiaryContainer = md_theme_light_onTertiaryContainer, + error = md_theme_light_error, + errorContainer = md_theme_light_errorContainer, + onError = md_theme_light_onError, + onErrorContainer = md_theme_light_onErrorContainer, + background = md_theme_light_background, + onBackground = md_theme_light_onBackground, + surface = md_theme_light_surface, + onSurface = md_theme_light_onSurface, + surfaceVariant = md_theme_light_surfaceVariant, + onSurfaceVariant = md_theme_light_onSurfaceVariant, + outline = md_theme_light_outline, + inverseOnSurface = md_theme_light_inverseOnSurface, + inverseSurface = md_theme_light_inverseSurface, + inversePrimary = md_theme_light_inversePrimary, + surfaceTint = md_theme_light_surfaceTint, + outlineVariant = md_theme_light_outlineVariant, + scrim = md_theme_light_scrim + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/acclorite/books_history/ui/theme/PinkTheme.kt b/app/src/main/java/com/acclorite/books_history/ui/theme/PinkTheme.kt new file mode 100644 index 00000000..d7637112 --- /dev/null +++ b/app/src/main/java/com/acclorite/books_history/ui/theme/PinkTheme.kt @@ -0,0 +1,136 @@ +package com.acclorite.books_history.ui.theme + +import androidx.compose.material3.ColorScheme +import androidx.compose.material3.darkColorScheme +import androidx.compose.material3.lightColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.Color + +private val md_theme_light_primary = Color(0xFF914084) +private val md_theme_light_onPrimary = Color(0xFFFFFFFF) +private val md_theme_light_primaryContainer = Color(0xFFFFD7F2) +private val md_theme_light_onPrimaryContainer = Color(0xFF390034) +private val md_theme_light_secondary = Color(0xFF6F5868) +private val md_theme_light_onSecondary = Color(0xFFFFFFFF) +private val md_theme_light_secondaryContainer = Color(0xFFF8DAED) +private val md_theme_light_onSecondaryContainer = Color(0xFF271623) +private val md_theme_light_tertiary = Color(0xFF815342) +private val md_theme_light_onTertiary = Color(0xFFFFFFFF) +private val md_theme_light_tertiaryContainer = Color(0xFFFFDBCF) +private val md_theme_light_onTertiaryContainer = Color(0xFF321206) +private val md_theme_light_error = Color(0xFFBA1A1A) +private val md_theme_light_errorContainer = Color(0xFFFFDAD6) +private val md_theme_light_onError = Color(0xFFFFFFFF) +private val md_theme_light_onErrorContainer = Color(0xFF410002) +private val md_theme_light_background = Color(0xFFFFFBFF) +private val md_theme_light_onBackground = Color(0xFF1F1A1D) +private val md_theme_light_surface = Color(0xFFFFFBFF) +private val md_theme_light_onSurface = Color(0xFF1F1A1D) +private val md_theme_light_surfaceVariant = Color(0xFFEEDEE7) +private val md_theme_light_onSurfaceVariant = Color(0xFF4E444A) +private val md_theme_light_outline = Color(0xFF80747B) +private val md_theme_light_inverseOnSurface = Color(0xFFF8EEF2) +private val md_theme_light_inverseSurface = Color(0xFF342F32) +private val md_theme_light_inversePrimary = Color(0xFFFFACEB) +private val md_theme_light_surfaceTint = Color(0xFF914084) +private val md_theme_light_outlineVariant = Color(0xFFD2C2CB) +private val md_theme_light_scrim = Color(0xFF000000) + +private val md_theme_dark_primary = Color(0xFFFFACEB) +private val md_theme_dark_onPrimary = Color(0xFF590B52) +private val md_theme_dark_primaryContainer = Color(0xFF75276A) +private val md_theme_dark_onPrimaryContainer = Color(0xFFFFD7F2) +private val md_theme_dark_secondary = Color(0xFFDBBED1) +private val md_theme_dark_onSecondary = Color(0xFF3E2A39) +private val md_theme_dark_secondaryContainer = Color(0xFF564050) +private val md_theme_dark_onSecondaryContainer = Color(0xFFF8DAED) +private val md_theme_dark_tertiary = Color(0xFFF5B9A4) +private val md_theme_dark_onTertiary = Color(0xFF4C2618) +private val md_theme_dark_tertiaryContainer = Color(0xFF663C2D) +private val md_theme_dark_onTertiaryContainer = Color(0xFFFFDBCF) +private val md_theme_dark_error = Color(0xFFFFB4AB) +private val md_theme_dark_errorContainer = Color(0xFF93000A) +private val md_theme_dark_onError = Color(0xFF690005) +private val md_theme_dark_onErrorContainer = Color(0xFFFFDAD6) +private val md_theme_dark_background = Color(0xFF1F1A1D) +private val md_theme_dark_onBackground = Color(0xFFEAE0E3) +private val md_theme_dark_surface = Color(0xFF1F1A1D) +private val md_theme_dark_onSurface = Color(0xFFEAE0E3) +private val md_theme_dark_surfaceVariant = Color(0xFF4E444A) +private val md_theme_dark_onSurfaceVariant = Color(0xFFD2C2CB) +private val md_theme_dark_outline = Color(0xFF9B8D95) +private val md_theme_dark_inverseOnSurface = Color(0xFF1F1A1D) +private val md_theme_dark_inverseSurface = Color(0xFFEAE0E3) +private val md_theme_dark_inversePrimary = Color(0xFF914084) +private val md_theme_dark_surfaceTint = Color(0xFFFFACEB) +private val md_theme_dark_outlineVariant = Color(0xFF4E444A) +private val md_theme_dark_scrim = Color(0xFF000000) + +@Composable +fun pinkTheme(isDark: Boolean): ColorScheme { + return if (isDark) { + darkColorScheme( + primary = md_theme_dark_primary, + onPrimary = md_theme_dark_onPrimary, + primaryContainer = md_theme_dark_primaryContainer, + onPrimaryContainer = md_theme_dark_onPrimaryContainer, + secondary = md_theme_dark_secondary, + onSecondary = md_theme_dark_onSecondary, + secondaryContainer = md_theme_dark_secondaryContainer, + onSecondaryContainer = md_theme_dark_onSecondaryContainer, + tertiary = md_theme_dark_tertiary, + onTertiary = md_theme_dark_onTertiary, + tertiaryContainer = md_theme_dark_tertiaryContainer, + onTertiaryContainer = md_theme_dark_onTertiaryContainer, + error = md_theme_dark_error, + errorContainer = md_theme_dark_errorContainer, + onError = md_theme_dark_onError, + onErrorContainer = md_theme_dark_onErrorContainer, + background = md_theme_dark_background, + onBackground = md_theme_dark_onBackground, + surface = md_theme_dark_surface, + onSurface = md_theme_dark_onSurface, + surfaceVariant = md_theme_dark_surfaceVariant, + onSurfaceVariant = md_theme_dark_onSurfaceVariant, + outline = md_theme_dark_outline, + inverseOnSurface = md_theme_dark_inverseOnSurface, + inverseSurface = md_theme_dark_inverseSurface, + inversePrimary = md_theme_dark_inversePrimary, + surfaceTint = md_theme_dark_surfaceTint, + outlineVariant = md_theme_dark_outlineVariant, + scrim = md_theme_dark_scrim + ) + } else { + lightColorScheme( + primary = md_theme_light_primary, + onPrimary = md_theme_light_onPrimary, + primaryContainer = md_theme_light_primaryContainer, + onPrimaryContainer = md_theme_light_onPrimaryContainer, + secondary = md_theme_light_secondary, + onSecondary = md_theme_light_onSecondary, + secondaryContainer = md_theme_light_secondaryContainer, + onSecondaryContainer = md_theme_light_onSecondaryContainer, + tertiary = md_theme_light_tertiary, + onTertiary = md_theme_light_onTertiary, + tertiaryContainer = md_theme_light_tertiaryContainer, + onTertiaryContainer = md_theme_light_onTertiaryContainer, + error = md_theme_light_error, + errorContainer = md_theme_light_errorContainer, + onError = md_theme_light_onError, + onErrorContainer = md_theme_light_onErrorContainer, + background = md_theme_light_background, + onBackground = md_theme_light_onBackground, + surface = md_theme_light_surface, + onSurface = md_theme_light_onSurface, + surfaceVariant = md_theme_light_surfaceVariant, + onSurfaceVariant = md_theme_light_onSurfaceVariant, + outline = md_theme_light_outline, + inverseOnSurface = md_theme_light_inverseOnSurface, + inverseSurface = md_theme_light_inverseSurface, + inversePrimary = md_theme_light_inversePrimary, + surfaceTint = md_theme_light_surfaceTint, + outlineVariant = md_theme_light_outlineVariant, + scrim = md_theme_light_scrim + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/acclorite/books_history/ui/theme/PurpleTheme.kt b/app/src/main/java/com/acclorite/books_history/ui/theme/PurpleTheme.kt new file mode 100644 index 00000000..8db93d43 --- /dev/null +++ b/app/src/main/java/com/acclorite/books_history/ui/theme/PurpleTheme.kt @@ -0,0 +1,137 @@ +package com.acclorite.books_history.ui.theme + +import androidx.compose.material3.ColorScheme +import androidx.compose.material3.darkColorScheme +import androidx.compose.material3.lightColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.Color + + +private val md_theme_light_primary = Color(0xFF7A4A98) +private val md_theme_light_onPrimary = Color(0xFFFFFFFF) +private val md_theme_light_primaryContainer = Color(0xFFF4D9FF) +private val md_theme_light_onPrimaryContainer = Color(0xFF2F004B) +private val md_theme_light_secondary = Color(0xFF68596E) +private val md_theme_light_onSecondary = Color(0xFFFFFFFF) +private val md_theme_light_secondaryContainer = Color(0xFFEFDCF5) +private val md_theme_light_onSecondaryContainer = Color(0xFF221729) +private val md_theme_light_tertiary = Color(0xFF815153) +private val md_theme_light_onTertiary = Color(0xFFFFFFFF) +private val md_theme_light_tertiaryContainer = Color(0xFFFFDADA) +private val md_theme_light_onTertiaryContainer = Color(0xFF331113) +private val md_theme_light_error = Color(0xFFBA1A1A) +private val md_theme_light_errorContainer = Color(0xFFFFDAD6) +private val md_theme_light_onError = Color(0xFFFFFFFF) +private val md_theme_light_onErrorContainer = Color(0xFF410002) +private val md_theme_light_background = Color(0xFFFFFBFF) +private val md_theme_light_onBackground = Color(0xFF1D1B1E) +private val md_theme_light_surface = Color(0xFFFFFBFF) +private val md_theme_light_onSurface = Color(0xFF1D1B1E) +private val md_theme_light_surfaceVariant = Color(0xFFEADFEA) +private val md_theme_light_onSurfaceVariant = Color(0xFF4B454D) +private val md_theme_light_outline = Color(0xFF7D747E) +private val md_theme_light_inverseOnSurface = Color(0xFFF6EFF3) +private val md_theme_light_inverseSurface = Color(0xFF332F33) +private val md_theme_light_inversePrimary = Color(0xFFE4B5FF) +private val md_theme_light_surfaceTint = Color(0xFF7A4A98) +private val md_theme_light_outlineVariant = Color(0xFFCDC3CE) +private val md_theme_light_scrim = Color(0xFF000000) + +private val md_theme_dark_primary = Color(0xFFE4B5FF) +private val md_theme_dark_onPrimary = Color(0xFF481866) +private val md_theme_dark_primaryContainer = Color(0xFF61317F) +private val md_theme_dark_onPrimaryContainer = Color(0xFFF4D9FF) +private val md_theme_dark_secondary = Color(0xFFD3C1D8) +private val md_theme_dark_onSecondary = Color(0xFF382C3E) +private val md_theme_dark_secondaryContainer = Color(0xFF4F4255) +private val md_theme_dark_onSecondaryContainer = Color(0xFFEFDCF5) +private val md_theme_dark_tertiary = Color(0xFFF4B7B9) +private val md_theme_dark_onTertiary = Color(0xFF4C2527) +private val md_theme_dark_tertiaryContainer = Color(0xFF663B3C) +private val md_theme_dark_onTertiaryContainer = Color(0xFFFFDADA) +private val md_theme_dark_error = Color(0xFFFFB4AB) +private val md_theme_dark_errorContainer = Color(0xFF93000A) +private val md_theme_dark_onError = Color(0xFF690005) +private val md_theme_dark_onErrorContainer = Color(0xFFFFDAD6) +private val md_theme_dark_background = Color(0xFF1D1B1E) +private val md_theme_dark_onBackground = Color(0xFFE8E0E5) +private val md_theme_dark_surface = Color(0xFF1D1B1E) +private val md_theme_dark_onSurface = Color(0xFFE8E0E5) +private val md_theme_dark_surfaceVariant = Color(0xFF4B454D) +private val md_theme_dark_onSurfaceVariant = Color(0xFFCDC3CE) +private val md_theme_dark_outline = Color(0xFF978E98) +private val md_theme_dark_inverseOnSurface = Color(0xFF1D1B1E) +private val md_theme_dark_inverseSurface = Color(0xFFE8E0E5) +private val md_theme_dark_inversePrimary = Color(0xFF7A4A98) +private val md_theme_dark_surfaceTint = Color(0xFFE4B5FF) +private val md_theme_dark_outlineVariant = Color(0xFF4B454D) +private val md_theme_dark_scrim = Color(0xFF000000) + +@Composable +fun purpleTheme(isDark: Boolean): ColorScheme { + return if (isDark) { + darkColorScheme( + primary = md_theme_dark_primary, + onPrimary = md_theme_dark_onPrimary, + primaryContainer = md_theme_dark_primaryContainer, + onPrimaryContainer = md_theme_dark_onPrimaryContainer, + secondary = md_theme_dark_secondary, + onSecondary = md_theme_dark_onSecondary, + secondaryContainer = md_theme_dark_secondaryContainer, + onSecondaryContainer = md_theme_dark_onSecondaryContainer, + tertiary = md_theme_dark_tertiary, + onTertiary = md_theme_dark_onTertiary, + tertiaryContainer = md_theme_dark_tertiaryContainer, + onTertiaryContainer = md_theme_dark_onTertiaryContainer, + error = md_theme_dark_error, + errorContainer = md_theme_dark_errorContainer, + onError = md_theme_dark_onError, + onErrorContainer = md_theme_dark_onErrorContainer, + background = md_theme_dark_background, + onBackground = md_theme_dark_onBackground, + surface = md_theme_dark_surface, + onSurface = md_theme_dark_onSurface, + surfaceVariant = md_theme_dark_surfaceVariant, + onSurfaceVariant = md_theme_dark_onSurfaceVariant, + outline = md_theme_dark_outline, + inverseOnSurface = md_theme_dark_inverseOnSurface, + inverseSurface = md_theme_dark_inverseSurface, + inversePrimary = md_theme_dark_inversePrimary, + surfaceTint = md_theme_dark_surfaceTint, + outlineVariant = md_theme_dark_outlineVariant, + scrim = md_theme_dark_scrim + ) + } else { + lightColorScheme( + primary = md_theme_light_primary, + onPrimary = md_theme_light_onPrimary, + primaryContainer = md_theme_light_primaryContainer, + onPrimaryContainer = md_theme_light_onPrimaryContainer, + secondary = md_theme_light_secondary, + onSecondary = md_theme_light_onSecondary, + secondaryContainer = md_theme_light_secondaryContainer, + onSecondaryContainer = md_theme_light_onSecondaryContainer, + tertiary = md_theme_light_tertiary, + onTertiary = md_theme_light_onTertiary, + tertiaryContainer = md_theme_light_tertiaryContainer, + onTertiaryContainer = md_theme_light_onTertiaryContainer, + error = md_theme_light_error, + errorContainer = md_theme_light_errorContainer, + onError = md_theme_light_onError, + onErrorContainer = md_theme_light_onErrorContainer, + background = md_theme_light_background, + onBackground = md_theme_light_onBackground, + surface = md_theme_light_surface, + onSurface = md_theme_light_onSurface, + surfaceVariant = md_theme_light_surfaceVariant, + onSurfaceVariant = md_theme_light_onSurfaceVariant, + outline = md_theme_light_outline, + inverseOnSurface = md_theme_light_inverseOnSurface, + inverseSurface = md_theme_light_inverseSurface, + inversePrimary = md_theme_light_inversePrimary, + surfaceTint = md_theme_light_surfaceTint, + outlineVariant = md_theme_light_outlineVariant, + scrim = md_theme_light_scrim + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/acclorite/books_history/ui/theme/Theme.kt b/app/src/main/java/com/acclorite/books_history/ui/theme/Theme.kt index 30e54c90..dd5094f7 100644 --- a/app/src/main/java/com/acclorite/books_history/ui/theme/Theme.kt +++ b/app/src/main/java/com/acclorite/books_history/ui/theme/Theme.kt @@ -4,67 +4,70 @@ import android.app.Activity import android.os.Build import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.darkColorScheme -import androidx.compose.material3.dynamicDarkColorScheme -import androidx.compose.material3.dynamicLightColorScheme -import androidx.compose.material3.lightColorScheme +import androidx.compose.material3.NavigationBarDefaults +import androidx.compose.material3.surfaceColorAtElevation import androidx.compose.runtime.Composable import androidx.compose.runtime.SideEffect +import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.toArgb -import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalView +import androidx.compose.ui.unit.Dp import androidx.core.view.WindowCompat -private val DarkColorScheme = darkColorScheme( - primary = Purple80, - secondary = PurpleGrey80, - tertiary = Pink80 -) +enum class DarkTheme { + FOLLOW_SYSTEM, + OFF, + ON +} -private val LightColorScheme = lightColorScheme( - primary = Purple40, - secondary = PurpleGrey40, - tertiary = Pink40 +fun String.toDarkTheme(): DarkTheme { + return when (this) { + "OFF" -> DarkTheme.OFF + "ON" -> DarkTheme.ON + else -> DarkTheme.FOLLOW_SYSTEM + } +} - /* Other default colors to override - background = Color(0xFFFFFBFE), - surface = Color(0xFFFFFBFE), - onPrimary = Color.White, - onSecondary = Color.White, - onTertiary = Color.White, - onBackground = Color(0xFF1C1B1F), - onSurface = Color(0xFF1C1B1F), - */ -) +@Composable +fun DarkTheme.isDark(): Boolean { + return when (this) { + DarkTheme.FOLLOW_SYSTEM -> isSystemInDarkTheme() + DarkTheme.ON -> true + DarkTheme.OFF -> false + } +} @Composable fun BooksHistoryResurrectionTheme( - darkTheme: Boolean = isSystemInDarkTheme(), - // Dynamic color is available on Android 12+ - dynamicColor: Boolean = true, + theme: Theme, + isDark: Boolean, content: @Composable () -> Unit ) { - val colorScheme = when { - dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { - val context = LocalContext.current - if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) - } - - darkTheme -> DarkColorScheme - else -> LightColorScheme - } val view = LocalView.current if (!view.isInEditMode) { SideEffect { val window = (view.context as Activity).window - window.statusBarColor = colorScheme.primary.toArgb() - WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = darkTheme + WindowCompat.setDecorFitsSystemWindows(window, false) + + window.statusBarColor = Color.Transparent.toArgb() + window.navigationBarColor = Color.Transparent.toArgb() + + WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = !isDark + WindowCompat.getInsetsController(window, view).isAppearanceLightNavigationBars = !isDark } } MaterialTheme( - colorScheme = colorScheme, + colorScheme = colorScheme( + theme = if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) theme + else if(theme != Theme.DYNAMIC) theme else Theme.BLUE, + darkTheme = isDark + ), typography = Typography, content = content ) -} \ No newline at end of file +} + +@Composable +fun MaterialTheme.getElevatedColor(elevation: Dp = NavigationBarDefaults.Elevation): Color = + colorScheme.surfaceColorAtElevation(elevation) \ No newline at end of file diff --git a/app/src/main/java/com/acclorite/books_history/util/Constants.kt b/app/src/main/java/com/acclorite/books_history/util/Constants.kt index 3d612eeb..f0ee06cb 100644 --- a/app/src/main/java/com/acclorite/books_history/util/Constants.kt +++ b/app/src/main/java/com/acclorite/books_history/util/Constants.kt @@ -1,5 +1,137 @@ package com.acclorite.books_history.util +import androidx.compose.ui.text.font.Font +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontStyle +import androidx.compose.ui.text.font.FontWeight +import com.acclorite.books_history.R +import com.acclorite.books_history.domain.model.FontWithName + object Constants { + const val LANGUAGE = "language" + const val THEME = "theme" + const val DARK_THEME = "dark_theme" + const val SHOW_START_SCREEN = "guide" + const val BACKGROUND_COLOR = "background_color" + const val FONT_COLOR = "font_color" + const val FONT = "font" + const val IS_ITALIC = "font_style" + const val FONT_SIZE = "font_size" + const val LINE_HEIGHT = "line_height" + const val PARAGRAPH_HEIGHT = "paragraph_height" + const val PARAGRAPH_INDENTATION = "paragraph_indentation" + + val FONTS = listOf( + FontWithName( + "Raleway", + FontFamily( + Font(R.font.raleway_regular), + Font(R.font.raleway_regular_italic, style = FontStyle.Italic), + Font(R.font.raleway_medium, FontWeight.Medium), + Font(R.font.raleway_medium_italic, FontWeight.Medium, style = FontStyle.Italic), + Font(R.font.raleway_bold, FontWeight.Bold), + Font(R.font.raleway_bold_italic, FontWeight.Bold, style = FontStyle.Italic) + ) + ), + FontWithName( + "Open Sans", + FontFamily( + Font(R.font.opensans_regular), + Font(R.font.opensans_regular_italic, style = FontStyle.Italic), + Font(R.font.opensans_medium, FontWeight.Medium), + Font(R.font.opensans_medium_italic, FontWeight.Medium, style = FontStyle.Italic), + Font(R.font.opensans_bold, FontWeight.Bold), + Font(R.font.opensans_bold_italic, FontWeight.Bold, style = FontStyle.Italic) + ) + ), + FontWithName( + "Mulish", + FontFamily( + Font(R.font.mulish_regular), + Font(R.font.mulish_regular_italic, style = FontStyle.Italic), + Font(R.font.mulish_medium, FontWeight.Medium), + Font(R.font.mulish_medium_italic, FontWeight.Medium, style = FontStyle.Italic), + Font(R.font.mulish_bold, FontWeight.Bold), + Font(R.font.mulish_bold_italic, FontWeight.Bold, style = FontStyle.Italic) + ) + ), + FontWithName( + "Arimo", + FontFamily( + Font(R.font.arimo_regular), + Font(R.font.arimo_regular_italic, style = FontStyle.Italic), + Font(R.font.arimo_medium, FontWeight.Medium), + Font(R.font.arimo_medium_italic, FontWeight.Medium, style = FontStyle.Italic), + Font(R.font.arimo_bold, FontWeight.Bold), + Font(R.font.arimo_bold_italic, FontWeight.Bold, style = FontStyle.Italic) + ) + ), + FontWithName( + "Garamond", + FontFamily( + Font(R.font.garamond_regular), + Font(R.font.garamond_regular_italic, style = FontStyle.Italic), + Font(R.font.garamond_medium, FontWeight.Medium), + Font(R.font.garamond_medium_italic, FontWeight.Medium, style = FontStyle.Italic), + Font(R.font.garamond_bold, FontWeight.Bold), + Font(R.font.garamond_bold_italic, FontWeight.Bold, style = FontStyle.Italic) + ) + ), + FontWithName( + "Roboto Serif", + FontFamily( + Font(R.font.robotoserif_regular), + Font(R.font.robotoserif_regular_italic, style = FontStyle.Italic), + Font(R.font.robotoserif_medium, FontWeight.Medium), + Font(R.font.robotoserif_medium_italic, FontWeight.Medium, style = FontStyle.Italic), + Font(R.font.robotoserif_bold, FontWeight.Bold), + Font(R.font.robotoserif_bold_italic, FontWeight.Bold, style = FontStyle.Italic) + ) + ), + FontWithName( + "Noto Serif", + FontFamily( + Font(R.font.notoserif_regular), + Font(R.font.notoserif_regular_italic, style = FontStyle.Italic), + Font(R.font.notoserif_medium, FontWeight.Medium), + Font(R.font.notoserif_medium_italic, FontWeight.Medium, style = FontStyle.Italic), + Font(R.font.notoserif_bold, FontWeight.Bold), + Font(R.font.notoserif_bold_italic, FontWeight.Bold, style = FontStyle.Italic) + ) + ), + FontWithName( + "Noto Sans", + FontFamily( + Font(R.font.notosans_regular), + Font(R.font.notosans_regular_italic, style = FontStyle.Italic), + Font(R.font.notosans_medium, FontWeight.Medium), + Font(R.font.notosans_medium_italic, FontWeight.Medium, style = FontStyle.Italic), + Font(R.font.notosans_bold, FontWeight.Bold), + Font(R.font.notosans_bold_italic, FontWeight.Bold, style = FontStyle.Italic) + ) + ), + FontWithName( + "Roboto", + FontFamily( + Font(R.font.roboto_regular), + Font(R.font.roboto_regular_italic, style = FontStyle.Italic), + Font(R.font.roboto_medium, FontWeight.Medium), + Font(R.font.roboto_medium_italic, FontWeight.Medium, style = FontStyle.Italic), + Font(R.font.roboto_bold, FontWeight.Bold), + Font(R.font.roboto_bold_italic, FontWeight.Bold, style = FontStyle.Italic) + ) + ), + FontWithName( + "Jost", + FontFamily( + Font(R.font.jost_regular), + Font(R.font.jost_regular_italic, style = FontStyle.Italic), + Font(R.font.jost_medium, FontWeight.Medium), + Font(R.font.jost_medium_italic, FontWeight.Medium, style = FontStyle.Italic), + Font(R.font.jost_bold, FontWeight.Bold), + Font(R.font.jost_bold_italic, FontWeight.Bold, style = FontStyle.Italic) + ) + ) + ) } \ No newline at end of file diff --git a/app/src/main/java/com/acclorite/books_history/util/DataStoreConstants.kt b/app/src/main/java/com/acclorite/books_history/util/DataStoreConstants.kt index 6174c0b0..f5dd2f5c 100644 --- a/app/src/main/java/com/acclorite/books_history/util/DataStoreConstants.kt +++ b/app/src/main/java/com/acclorite/books_history/util/DataStoreConstants.kt @@ -1,19 +1,22 @@ package com.acclorite.books_history.util +import androidx.datastore.preferences.core.booleanPreferencesKey +import androidx.datastore.preferences.core.intPreferencesKey +import androidx.datastore.preferences.core.longPreferencesKey import androidx.datastore.preferences.core.stringPreferencesKey object DataStoreConstants { val LANGUAGE = stringPreferencesKey("language") val THEME = stringPreferencesKey("theme") val DARK_THEME = stringPreferencesKey("dark_theme") - val GUIDE = stringPreferencesKey("guide") + val SHOW_START_SCREEN = booleanPreferencesKey("guide") - val BACKGROUND_COLOR = stringPreferencesKey("background_color") - val FONT_COLOR = stringPreferencesKey("font_color") + val BACKGROUND_COLOR = longPreferencesKey("background_color") + val FONT_COLOR = longPreferencesKey("font_color") val FONT = stringPreferencesKey("font") - val FONT_STYLE = stringPreferencesKey("font_style") - val FONT_SIZE = stringPreferencesKey("font_size") - val LINE_HEIGHT = stringPreferencesKey("line_height") - val PARAGRAPH_HEIGHT = stringPreferencesKey("paragraph_height") - val PARAGRAPH_INDENTATION = stringPreferencesKey("paragraph_indentation") + val IS_ITALIC = booleanPreferencesKey("font_style") + val FONT_SIZE = intPreferencesKey("font_size") + val LINE_HEIGHT = intPreferencesKey("line_height") + val PARAGRAPH_HEIGHT = intPreferencesKey("paragraph_height") + val PARAGRAPH_INDENTATION = booleanPreferencesKey("paragraph_indentation") } \ No newline at end of file diff --git a/app/src/main/res/drawable/app_icon_colored.png b/app/src/main/res/drawable/app_icon_colored.png new file mode 100644 index 00000000..e76100d1 Binary files /dev/null and b/app/src/main/res/drawable/app_icon_colored.png differ diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml deleted file mode 100644 index 07d5da9c..00000000 --- a/app/src/main/res/drawable/ic_launcher_background.xml +++ /dev/null @@ -1,170 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml deleted file mode 100644 index 2b068d11..00000000 --- a/app/src/main/res/drawable/ic_launcher_foreground.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/splash_icon.xml b/app/src/main/res/drawable/splash_icon.xml new file mode 100644 index 00000000..8400ffaa --- /dev/null +++ b/app/src/main/res/drawable/splash_icon.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/font/arimo_bold.ttf b/app/src/main/res/font/arimo_bold.ttf new file mode 100644 index 00000000..c26951c1 Binary files /dev/null and b/app/src/main/res/font/arimo_bold.ttf differ diff --git a/app/src/main/res/font/arimo_bold_italic.ttf b/app/src/main/res/font/arimo_bold_italic.ttf new file mode 100644 index 00000000..e085b9a5 Binary files /dev/null and b/app/src/main/res/font/arimo_bold_italic.ttf differ diff --git a/app/src/main/res/font/arimo_medium.ttf b/app/src/main/res/font/arimo_medium.ttf new file mode 100644 index 00000000..f2223e20 Binary files /dev/null and b/app/src/main/res/font/arimo_medium.ttf differ diff --git a/app/src/main/res/font/arimo_medium_italic.ttf b/app/src/main/res/font/arimo_medium_italic.ttf new file mode 100644 index 00000000..7572c83a Binary files /dev/null and b/app/src/main/res/font/arimo_medium_italic.ttf differ diff --git a/app/src/main/res/font/arimo_regular.ttf b/app/src/main/res/font/arimo_regular.ttf new file mode 100644 index 00000000..7872b35a Binary files /dev/null and b/app/src/main/res/font/arimo_regular.ttf differ diff --git a/app/src/main/res/font/arimo_regular_italic.ttf b/app/src/main/res/font/arimo_regular_italic.ttf new file mode 100644 index 00000000..49a03256 Binary files /dev/null and b/app/src/main/res/font/arimo_regular_italic.ttf differ diff --git a/app/src/main/res/font/bold.ttf b/app/src/main/res/font/bold.ttf new file mode 100644 index 00000000..886134dc Binary files /dev/null and b/app/src/main/res/font/bold.ttf differ diff --git a/app/src/main/res/font/bold_italic.ttf b/app/src/main/res/font/bold_italic.ttf new file mode 100644 index 00000000..0cb4efae Binary files /dev/null and b/app/src/main/res/font/bold_italic.ttf differ diff --git a/app/src/main/res/font/garamond_bold.ttf b/app/src/main/res/font/garamond_bold.ttf new file mode 100644 index 00000000..b73dee02 Binary files /dev/null and b/app/src/main/res/font/garamond_bold.ttf differ diff --git a/app/src/main/res/font/garamond_bold_italic.ttf b/app/src/main/res/font/garamond_bold_italic.ttf new file mode 100644 index 00000000..852be7c6 Binary files /dev/null and b/app/src/main/res/font/garamond_bold_italic.ttf differ diff --git a/app/src/main/res/font/garamond_medium.ttf b/app/src/main/res/font/garamond_medium.ttf new file mode 100644 index 00000000..fd40af32 Binary files /dev/null and b/app/src/main/res/font/garamond_medium.ttf differ diff --git a/app/src/main/res/font/garamond_medium_italic.ttf b/app/src/main/res/font/garamond_medium_italic.ttf new file mode 100644 index 00000000..8e580f5e Binary files /dev/null and b/app/src/main/res/font/garamond_medium_italic.ttf differ diff --git a/app/src/main/res/font/garamond_regular.ttf b/app/src/main/res/font/garamond_regular.ttf new file mode 100644 index 00000000..d3d6f3fb Binary files /dev/null and b/app/src/main/res/font/garamond_regular.ttf differ diff --git a/app/src/main/res/font/garamond_regular_italic.ttf b/app/src/main/res/font/garamond_regular_italic.ttf new file mode 100644 index 00000000..0f76a8ec Binary files /dev/null and b/app/src/main/res/font/garamond_regular_italic.ttf differ diff --git a/app/src/main/res/font/jost_bold.ttf b/app/src/main/res/font/jost_bold.ttf new file mode 100644 index 00000000..75590c30 Binary files /dev/null and b/app/src/main/res/font/jost_bold.ttf differ diff --git a/app/src/main/res/font/jost_bold_italic.ttf b/app/src/main/res/font/jost_bold_italic.ttf new file mode 100644 index 00000000..e939edff Binary files /dev/null and b/app/src/main/res/font/jost_bold_italic.ttf differ diff --git a/app/src/main/res/font/jost_medium.ttf b/app/src/main/res/font/jost_medium.ttf new file mode 100644 index 00000000..e557ed4b Binary files /dev/null and b/app/src/main/res/font/jost_medium.ttf differ diff --git a/app/src/main/res/font/jost_medium_italic.ttf b/app/src/main/res/font/jost_medium_italic.ttf new file mode 100644 index 00000000..7fcd6eb6 Binary files /dev/null and b/app/src/main/res/font/jost_medium_italic.ttf differ diff --git a/app/src/main/res/font/jost_regular.ttf b/app/src/main/res/font/jost_regular.ttf new file mode 100644 index 00000000..32695631 Binary files /dev/null and b/app/src/main/res/font/jost_regular.ttf differ diff --git a/app/src/main/res/font/jost_regular_italic.ttf b/app/src/main/res/font/jost_regular_italic.ttf new file mode 100644 index 00000000..01090bb7 Binary files /dev/null and b/app/src/main/res/font/jost_regular_italic.ttf differ diff --git a/app/src/main/res/font/light.ttf b/app/src/main/res/font/light.ttf new file mode 100644 index 00000000..e64c0fef Binary files /dev/null and b/app/src/main/res/font/light.ttf differ diff --git a/app/src/main/res/font/light_italic.ttf b/app/src/main/res/font/light_italic.ttf new file mode 100644 index 00000000..b465e5a2 Binary files /dev/null and b/app/src/main/res/font/light_italic.ttf differ diff --git a/app/src/main/res/font/medium.ttf b/app/src/main/res/font/medium.ttf new file mode 100644 index 00000000..e24c1d61 Binary files /dev/null and b/app/src/main/res/font/medium.ttf differ diff --git a/app/src/main/res/font/medium_italic.ttf b/app/src/main/res/font/medium_italic.ttf new file mode 100644 index 00000000..6fec0957 Binary files /dev/null and b/app/src/main/res/font/medium_italic.ttf differ diff --git a/app/src/main/res/font/mulish_bold.ttf b/app/src/main/res/font/mulish_bold.ttf new file mode 100644 index 00000000..0c1eed73 Binary files /dev/null and b/app/src/main/res/font/mulish_bold.ttf differ diff --git a/app/src/main/res/font/mulish_bold_italic.ttf b/app/src/main/res/font/mulish_bold_italic.ttf new file mode 100644 index 00000000..6f08e151 Binary files /dev/null and b/app/src/main/res/font/mulish_bold_italic.ttf differ diff --git a/app/src/main/res/font/mulish_medium.ttf b/app/src/main/res/font/mulish_medium.ttf new file mode 100644 index 00000000..be50c597 Binary files /dev/null and b/app/src/main/res/font/mulish_medium.ttf differ diff --git a/app/src/main/res/font/mulish_medium_italic.ttf b/app/src/main/res/font/mulish_medium_italic.ttf new file mode 100644 index 00000000..01cf746f Binary files /dev/null and b/app/src/main/res/font/mulish_medium_italic.ttf differ diff --git a/app/src/main/res/font/mulish_regular.ttf b/app/src/main/res/font/mulish_regular.ttf new file mode 100644 index 00000000..0971518b Binary files /dev/null and b/app/src/main/res/font/mulish_regular.ttf differ diff --git a/app/src/main/res/font/mulish_regular_italic.ttf b/app/src/main/res/font/mulish_regular_italic.ttf new file mode 100644 index 00000000..a42d8759 Binary files /dev/null and b/app/src/main/res/font/mulish_regular_italic.ttf differ diff --git a/app/src/main/res/font/notosans_bold.ttf b/app/src/main/res/font/notosans_bold.ttf new file mode 100644 index 00000000..d84248ed Binary files /dev/null and b/app/src/main/res/font/notosans_bold.ttf differ diff --git a/app/src/main/res/font/notosans_bold_italic.ttf b/app/src/main/res/font/notosans_bold_italic.ttf new file mode 100644 index 00000000..3a34c4c3 Binary files /dev/null and b/app/src/main/res/font/notosans_bold_italic.ttf differ diff --git a/app/src/main/res/font/notosans_medium.ttf b/app/src/main/res/font/notosans_medium.ttf new file mode 100644 index 00000000..a799b74d Binary files /dev/null and b/app/src/main/res/font/notosans_medium.ttf differ diff --git a/app/src/main/res/font/notosans_medium_italic.ttf b/app/src/main/res/font/notosans_medium_italic.ttf new file mode 100644 index 00000000..2ccbc5b0 Binary files /dev/null and b/app/src/main/res/font/notosans_medium_italic.ttf differ diff --git a/app/src/main/res/font/notosans_regular.ttf b/app/src/main/res/font/notosans_regular.ttf new file mode 100644 index 00000000..fa4cff50 Binary files /dev/null and b/app/src/main/res/font/notosans_regular.ttf differ diff --git a/app/src/main/res/font/notosans_regular_italic.ttf b/app/src/main/res/font/notosans_regular_italic.ttf new file mode 100644 index 00000000..c40c3562 Binary files /dev/null and b/app/src/main/res/font/notosans_regular_italic.ttf differ diff --git a/app/src/main/res/font/notoserif_bold.ttf b/app/src/main/res/font/notoserif_bold.ttf new file mode 100644 index 00000000..aa21d44e Binary files /dev/null and b/app/src/main/res/font/notoserif_bold.ttf differ diff --git a/app/src/main/res/font/notoserif_bold_italic.ttf b/app/src/main/res/font/notoserif_bold_italic.ttf new file mode 100644 index 00000000..5a38d83d Binary files /dev/null and b/app/src/main/res/font/notoserif_bold_italic.ttf differ diff --git a/app/src/main/res/font/notoserif_medium.ttf b/app/src/main/res/font/notoserif_medium.ttf new file mode 100644 index 00000000..7a177074 Binary files /dev/null and b/app/src/main/res/font/notoserif_medium.ttf differ diff --git a/app/src/main/res/font/notoserif_medium_italic.ttf b/app/src/main/res/font/notoserif_medium_italic.ttf new file mode 100644 index 00000000..3aa6bf49 Binary files /dev/null and b/app/src/main/res/font/notoserif_medium_italic.ttf differ diff --git a/app/src/main/res/font/notoserif_regular.ttf b/app/src/main/res/font/notoserif_regular.ttf new file mode 100644 index 00000000..dc30297e Binary files /dev/null and b/app/src/main/res/font/notoserif_regular.ttf differ diff --git a/app/src/main/res/font/notoserif_regular_italic.ttf b/app/src/main/res/font/notoserif_regular_italic.ttf new file mode 100644 index 00000000..786ecc73 Binary files /dev/null and b/app/src/main/res/font/notoserif_regular_italic.ttf differ diff --git a/app/src/main/res/font/opensans_bold.ttf b/app/src/main/res/font/opensans_bold.ttf new file mode 100644 index 00000000..98c74e0a Binary files /dev/null and b/app/src/main/res/font/opensans_bold.ttf differ diff --git a/app/src/main/res/font/opensans_bold_italic.ttf b/app/src/main/res/font/opensans_bold_italic.ttf new file mode 100644 index 00000000..85589283 Binary files /dev/null and b/app/src/main/res/font/opensans_bold_italic.ttf differ diff --git a/app/src/main/res/font/opensans_medium.ttf b/app/src/main/res/font/opensans_medium.ttf new file mode 100644 index 00000000..ae716936 Binary files /dev/null and b/app/src/main/res/font/opensans_medium.ttf differ diff --git a/app/src/main/res/font/opensans_medium_italic.ttf b/app/src/main/res/font/opensans_medium_italic.ttf new file mode 100644 index 00000000..6d1e09b2 Binary files /dev/null and b/app/src/main/res/font/opensans_medium_italic.ttf differ diff --git a/app/src/main/res/font/opensans_regular.ttf b/app/src/main/res/font/opensans_regular.ttf new file mode 100644 index 00000000..67803bb6 Binary files /dev/null and b/app/src/main/res/font/opensans_regular.ttf differ diff --git a/app/src/main/res/font/opensans_regular_italic.ttf b/app/src/main/res/font/opensans_regular_italic.ttf new file mode 100644 index 00000000..29ff6938 Binary files /dev/null and b/app/src/main/res/font/opensans_regular_italic.ttf differ diff --git a/app/src/main/res/font/raleway_bold.ttf b/app/src/main/res/font/raleway_bold.ttf new file mode 100644 index 00000000..16db3eba Binary files /dev/null and b/app/src/main/res/font/raleway_bold.ttf differ diff --git a/app/src/main/res/font/raleway_bold_italic.ttf b/app/src/main/res/font/raleway_bold_italic.ttf new file mode 100644 index 00000000..5a429a42 Binary files /dev/null and b/app/src/main/res/font/raleway_bold_italic.ttf differ diff --git a/app/src/main/res/font/raleway_medium.ttf b/app/src/main/res/font/raleway_medium.ttf new file mode 100644 index 00000000..015d8108 Binary files /dev/null and b/app/src/main/res/font/raleway_medium.ttf differ diff --git a/app/src/main/res/font/raleway_medium_italic.ttf b/app/src/main/res/font/raleway_medium_italic.ttf new file mode 100644 index 00000000..2b8b88c3 Binary files /dev/null and b/app/src/main/res/font/raleway_medium_italic.ttf differ diff --git a/app/src/main/res/font/raleway_regular.ttf b/app/src/main/res/font/raleway_regular.ttf new file mode 100644 index 00000000..9a70667f Binary files /dev/null and b/app/src/main/res/font/raleway_regular.ttf differ diff --git a/app/src/main/res/font/raleway_regular_italic.ttf b/app/src/main/res/font/raleway_regular_italic.ttf new file mode 100644 index 00000000..fa7ca30c Binary files /dev/null and b/app/src/main/res/font/raleway_regular_italic.ttf differ diff --git a/app/src/main/res/font/regular.ttf b/app/src/main/res/font/regular.ttf new file mode 100644 index 00000000..9411bfbe Binary files /dev/null and b/app/src/main/res/font/regular.ttf differ diff --git a/app/src/main/res/font/regular_italic.ttf b/app/src/main/res/font/regular_italic.ttf new file mode 100644 index 00000000..f4ab1149 Binary files /dev/null and b/app/src/main/res/font/regular_italic.ttf differ diff --git a/app/src/main/res/font/roboto_bold.ttf b/app/src/main/res/font/roboto_bold.ttf new file mode 100644 index 00000000..43da14d8 Binary files /dev/null and b/app/src/main/res/font/roboto_bold.ttf differ diff --git a/app/src/main/res/font/roboto_bold_italic.ttf b/app/src/main/res/font/roboto_bold_italic.ttf new file mode 100644 index 00000000..bcfdab43 Binary files /dev/null and b/app/src/main/res/font/roboto_bold_italic.ttf differ diff --git a/app/src/main/res/font/roboto_medium.ttf b/app/src/main/res/font/roboto_medium.ttf new file mode 100644 index 00000000..ac0f908b Binary files /dev/null and b/app/src/main/res/font/roboto_medium.ttf differ diff --git a/app/src/main/res/font/roboto_medium_italic.ttf b/app/src/main/res/font/roboto_medium_italic.ttf new file mode 100644 index 00000000..fc36a478 Binary files /dev/null and b/app/src/main/res/font/roboto_medium_italic.ttf differ diff --git a/app/src/main/res/font/roboto_regular.ttf b/app/src/main/res/font/roboto_regular.ttf new file mode 100644 index 00000000..ddf4bfac Binary files /dev/null and b/app/src/main/res/font/roboto_regular.ttf differ diff --git a/app/src/main/res/font/roboto_regular_italic.ttf b/app/src/main/res/font/roboto_regular_italic.ttf new file mode 100644 index 00000000..1b5eaa36 Binary files /dev/null and b/app/src/main/res/font/roboto_regular_italic.ttf differ diff --git a/app/src/main/res/font/robotoserif_bold.ttf b/app/src/main/res/font/robotoserif_bold.ttf new file mode 100644 index 00000000..3122ab80 Binary files /dev/null and b/app/src/main/res/font/robotoserif_bold.ttf differ diff --git a/app/src/main/res/font/robotoserif_bold_italic.ttf b/app/src/main/res/font/robotoserif_bold_italic.ttf new file mode 100644 index 00000000..6d9e50ba Binary files /dev/null and b/app/src/main/res/font/robotoserif_bold_italic.ttf differ diff --git a/app/src/main/res/font/robotoserif_medium.ttf b/app/src/main/res/font/robotoserif_medium.ttf new file mode 100644 index 00000000..bf083f21 Binary files /dev/null and b/app/src/main/res/font/robotoserif_medium.ttf differ diff --git a/app/src/main/res/font/robotoserif_medium_italic.ttf b/app/src/main/res/font/robotoserif_medium_italic.ttf new file mode 100644 index 00000000..0854155f Binary files /dev/null and b/app/src/main/res/font/robotoserif_medium_italic.ttf differ diff --git a/app/src/main/res/font/robotoserif_regular.ttf b/app/src/main/res/font/robotoserif_regular.ttf new file mode 100644 index 00000000..48773aec Binary files /dev/null and b/app/src/main/res/font/robotoserif_regular.ttf differ diff --git a/app/src/main/res/font/robotoserif_regular_italic.ttf b/app/src/main/res/font/robotoserif_regular_italic.ttf new file mode 100644 index 00000000..fcc48dfd Binary files /dev/null and b/app/src/main/res/font/robotoserif_regular_italic.ttf differ diff --git a/app/src/main/res/font/semi_bold.ttf b/app/src/main/res/font/semi_bold.ttf new file mode 100644 index 00000000..1326a7dc Binary files /dev/null and b/app/src/main/res/font/semi_bold.ttf differ diff --git a/app/src/main/res/font/semi_bold_italic.ttf b/app/src/main/res/font/semi_bold_italic.ttf new file mode 100644 index 00000000..d20e95f7 Binary files /dev/null and b/app/src/main/res/font/semi_bold_italic.ttf differ diff --git a/app/src/main/res/font/thin.ttf b/app/src/main/res/font/thin.ttf new file mode 100644 index 00000000..d9eabf95 Binary files /dev/null and b/app/src/main/res/font/thin.ttf differ diff --git a/app/src/main/res/font/thin_italic.ttf b/app/src/main/res/font/thin_italic.ttf new file mode 100644 index 00000000..2037f4a7 Binary files /dev/null and b/app/src/main/res/font/thin_italic.ttf differ diff --git a/app/src/main/res/mipmap-anydpi-v26/app_icon.xml b/app/src/main/res/mipmap-anydpi-v26/app_icon.xml new file mode 100644 index 00000000..69b65dc0 --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/app_icon.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/app_icon_round.xml b/app/src/main/res/mipmap-anydpi-v26/app_icon_round.xml new file mode 100644 index 00000000..69b65dc0 --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/app_icon_round.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi/ic_launcher.xml b/app/src/main/res/mipmap-anydpi/ic_launcher.xml deleted file mode 100644 index 6f3b755b..00000000 --- a/app/src/main/res/mipmap-anydpi/ic_launcher.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml deleted file mode 100644 index 6f3b755b..00000000 --- a/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/app_icon.webp b/app/src/main/res/mipmap-hdpi/app_icon.webp new file mode 100644 index 00000000..62ba9e1c Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/app_icon.webp differ diff --git a/app/src/main/res/mipmap-hdpi/app_icon_foreground.webp b/app/src/main/res/mipmap-hdpi/app_icon_foreground.webp new file mode 100644 index 00000000..06f5c8f4 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/app_icon_foreground.webp differ diff --git a/app/src/main/res/mipmap-hdpi/app_icon_monochrome.webp b/app/src/main/res/mipmap-hdpi/app_icon_monochrome.webp new file mode 100644 index 00000000..2078e7fb Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/app_icon_monochrome.webp differ diff --git a/app/src/main/res/mipmap-hdpi/app_icon_round.webp b/app/src/main/res/mipmap-hdpi/app_icon_round.webp new file mode 100644 index 00000000..5a201221 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/app_icon_round.webp differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/app/src/main/res/mipmap-hdpi/ic_launcher.webp deleted file mode 100644 index c209e78e..00000000 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher.webp and /dev/null differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp deleted file mode 100644 index b2dfe3d1..00000000 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp and /dev/null differ diff --git a/app/src/main/res/mipmap-mdpi/app_icon.webp b/app/src/main/res/mipmap-mdpi/app_icon.webp new file mode 100644 index 00000000..17f3912c Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/app_icon.webp differ diff --git a/app/src/main/res/mipmap-mdpi/app_icon_foreground.webp b/app/src/main/res/mipmap-mdpi/app_icon_foreground.webp new file mode 100644 index 00000000..eeb288e4 Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/app_icon_foreground.webp differ diff --git a/app/src/main/res/mipmap-mdpi/app_icon_monochrome.webp b/app/src/main/res/mipmap-mdpi/app_icon_monochrome.webp new file mode 100644 index 00000000..3e46530f Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/app_icon_monochrome.webp differ diff --git a/app/src/main/res/mipmap-mdpi/app_icon_round.webp b/app/src/main/res/mipmap-mdpi/app_icon_round.webp new file mode 100644 index 00000000..b0889cab Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/app_icon_round.webp differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/app/src/main/res/mipmap-mdpi/ic_launcher.webp deleted file mode 100644 index 4f0f1d64..00000000 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher.webp and /dev/null differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp deleted file mode 100644 index 62b611da..00000000 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp and /dev/null differ diff --git a/app/src/main/res/mipmap-xhdpi/app_icon.webp b/app/src/main/res/mipmap-xhdpi/app_icon.webp new file mode 100644 index 00000000..73172c04 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/app_icon.webp differ diff --git a/app/src/main/res/mipmap-xhdpi/app_icon_foreground.webp b/app/src/main/res/mipmap-xhdpi/app_icon_foreground.webp new file mode 100644 index 00000000..67bc1941 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/app_icon_foreground.webp differ diff --git a/app/src/main/res/mipmap-xhdpi/app_icon_monochrome.webp b/app/src/main/res/mipmap-xhdpi/app_icon_monochrome.webp new file mode 100644 index 00000000..ee458a14 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/app_icon_monochrome.webp differ diff --git a/app/src/main/res/mipmap-xhdpi/app_icon_round.webp b/app/src/main/res/mipmap-xhdpi/app_icon_round.webp new file mode 100644 index 00000000..24508b61 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/app_icon_round.webp differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp deleted file mode 100644 index 948a3070..00000000 Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp and /dev/null differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp deleted file mode 100644 index 1b9a6956..00000000 Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp and /dev/null differ diff --git a/app/src/main/res/mipmap-xxhdpi/app_icon.webp b/app/src/main/res/mipmap-xxhdpi/app_icon.webp new file mode 100644 index 00000000..c04de250 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/app_icon.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/app_icon_foreground.webp b/app/src/main/res/mipmap-xxhdpi/app_icon_foreground.webp new file mode 100644 index 00000000..b14b0285 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/app_icon_foreground.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/app_icon_monochrome.webp b/app/src/main/res/mipmap-xxhdpi/app_icon_monochrome.webp new file mode 100644 index 00000000..2e0651e1 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/app_icon_monochrome.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/app_icon_round.webp b/app/src/main/res/mipmap-xxhdpi/app_icon_round.webp new file mode 100644 index 00000000..9f81e3a6 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/app_icon_round.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp deleted file mode 100644 index 28d4b77f..00000000 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp and /dev/null differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp deleted file mode 100644 index 9287f508..00000000 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp and /dev/null differ diff --git a/app/src/main/res/mipmap-xxxhdpi/app_icon.webp b/app/src/main/res/mipmap-xxxhdpi/app_icon.webp new file mode 100644 index 00000000..a56c37e3 Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/app_icon.webp differ diff --git a/app/src/main/res/mipmap-xxxhdpi/app_icon_foreground.webp b/app/src/main/res/mipmap-xxxhdpi/app_icon_foreground.webp new file mode 100644 index 00000000..511230fb Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/app_icon_foreground.webp differ diff --git a/app/src/main/res/mipmap-xxxhdpi/app_icon_monochrome.webp b/app/src/main/res/mipmap-xxxhdpi/app_icon_monochrome.webp new file mode 100644 index 00000000..2614838c Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/app_icon_monochrome.webp differ diff --git a/app/src/main/res/mipmap-xxxhdpi/app_icon_round.webp b/app/src/main/res/mipmap-xxxhdpi/app_icon_round.webp new file mode 100644 index 00000000..7654f8b6 Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/app_icon_round.webp differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp deleted file mode 100644 index aa7d6427..00000000 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp and /dev/null differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp deleted file mode 100644 index 9126ae37..00000000 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp and /dev/null differ diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml new file mode 100644 index 00000000..73065e41 --- /dev/null +++ b/app/src/main/res/values-night/themes.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 9f7f942a..b4adf9da 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -1,5 +1,5 @@ - Історія Книги: Воскресіння + Історія Книги \ No newline at end of file diff --git a/app/src/main/res/values/app_icon_background.xml b/app/src/main/res/values/app_icon_background.xml new file mode 100644 index 00000000..c49d7488 --- /dev/null +++ b/app/src/main/res/values/app_icon_background.xml @@ -0,0 +1,4 @@ + + + #FFFFFF + \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index f8c6127d..e204b630 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -1,10 +1,5 @@ - #FFBB86FC - #FF6200EE - #FF3700B3 - #FF03DAC5 - #FF018786 - #FF000000 - #FFFFFFFF + #FAFAFA + #101010 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a9cfeb1d..97b4f384 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,7 +1,12 @@ - 0.0.1 - Book\'s History: Resurrection + 0.2.0 + + en + uk + + + Book\'s History \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 9501296a..cea0e99c 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -1,5 +1,15 @@ - + - + + \ No newline at end of file diff --git a/app/src/test/java/com/acclorite/books_history/data/repository/FakeBookRepository.kt b/app/src/test/java/com/acclorite/books_history/data/repository/FakeBookRepository.kt new file mode 100644 index 00000000..f8809e58 --- /dev/null +++ b/app/src/test/java/com/acclorite/books_history/data/repository/FakeBookRepository.kt @@ -0,0 +1,45 @@ +package com.acclorite.books_history.data.repository + +import androidx.datastore.preferences.core.Preferences +import com.acclorite.books_history.domain.model.Book +import com.acclorite.books_history.domain.repository.BookRepository +import com.acclorite.books_history.util.Resource +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flow + +class FakeBookRepository: BookRepository { + + private val booksList = mutableListOf() + + override suspend fun getBooks(query: String): Flow>> { + return flow { emit(Resource.Success(booksList.filter { it.title.lowercase().contains(query) })) } + } + + override suspend fun insertBooks(books: List) { + booksList.addAll(books) + } + + override suspend fun updateBooks(books: List) { + booksList.forEachIndexed { index, book -> + books.forEach { + if(it.id == book.id) + booksList[index] = it + } + } + } + + override suspend fun deleteBooks(books: List) { + booksList.removeAll(books) + } + + override suspend fun retrieveDataFromDataStore( + key: Preferences.Key, + defaultValue: T + ): Flow { + return flow { emit(defaultValue) } + } + + override suspend fun putDataToDataStore(key: Preferences.Key, value: T) { + TODO("Not yet implemented") + } +} \ No newline at end of file diff --git a/app/src/test/java/com/acclorite/books_history/domain/use_case/InsertBooksTest.kt b/app/src/test/java/com/acclorite/books_history/domain/use_case/InsertBooksTest.kt new file mode 100644 index 00000000..5389450f --- /dev/null +++ b/app/src/test/java/com/acclorite/books_history/domain/use_case/InsertBooksTest.kt @@ -0,0 +1,50 @@ +package com.acclorite.books_history.domain.use_case + +import com.acclorite.books_history.data.repository.FakeBookRepository +import com.acclorite.books_history.domain.model.Book +import com.acclorite.books_history.domain.model.Category +import com.google.common.truth.Truth.* +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.runBlocking +import org.junit.Before +import org.junit.Test + +class InsertBooksTest { + + private lateinit var insertBooks: InsertBooks + private lateinit var fakeRepository: FakeBookRepository + + @Before + fun setUp() { + fakeRepository = FakeBookRepository() + insertBooks = InsertBooks(fakeRepository) + } + + @Test + fun `Insert all books, inserted book`() = runBlocking { + val booksToInsert = mutableListOf() + ('a'..'z').forEachIndexed { index, c -> + booksToInsert.add( + Book( + index, + c.toString(), + c.toString(), + c.toString(), + emptyList(), + (index / 100f), + null, + null, + Category.READING, + coverImage = null + ) + ) + } + booksToInsert.shuffle() + + val oldRepoSize = fakeRepository.getBooks("").first().data?.size ?: return@runBlocking + insertBooks.execute(booksToInsert) + val repoSize = fakeRepository.getBooks("").first().data?.size ?: return@runBlocking + + assertThat(oldRepoSize).isLessThan(repoSize) + } +} \ No newline at end of file