0.2.0 - MainViewModel and DataStore Handling implementation

This commit is contained in:
Acclorite 2023-12-31 17:57:49 +02:00
parent 29a75aa18a
commit 17fa0973b8
149 changed files with 1385 additions and 373 deletions

9
.idea/misc.xml generated
View file

@ -1,4 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="EntryPointsManager">
<list size="4">
<item index="0" class="java.lang.String" itemvalue="dagger.Binds" />
<item index="1" class="java.lang.String" itemvalue="dagger.Binds" />
<item index="2" class="java.lang.String" itemvalue="dagger.Binds" />
<item index="3" class="java.lang.String" itemvalue="dagger.Module" />
</list>
</component>
<component name="ExternalStorageConfigurationManager" enabled="true" /> <component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" /> <output url="file://$PROJECT_DIR$/build/classes" />

View file

@ -16,7 +16,7 @@ android {
minSdk = 26 minSdk = 26
targetSdk = 34 targetSdk = 34
versionCode = 1 versionCode = 1
versionName = "0.0.1" versionName = "0.2.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables { vectorDrawables {
@ -69,14 +69,29 @@ dependencies {
implementation("androidx.compose.ui:ui-android:latest.release") implementation("androidx.compose.ui:ui-android:latest.release")
implementation("androidx.compose.material3:material3") implementation("androidx.compose.material3:material3")
// Debug // Unit tests
testImplementation("junit:junit:4.13.2") testImplementation ("androidx.test:core:latest.release")
androidTestImplementation("androidx.test.ext:junit:1.1.5") testImplementation ("junit:junit:latest.release")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") testImplementation ("androidx.arch.core:core-testing:latest.release")
androidTestImplementation(platform("androidx.compose:compose-bom:2023.08.00")) testImplementation ("org.jetbrains.kotlinx:kotlinx-coroutines-test:latest.release")
androidTestImplementation("androidx.compose.ui:ui-test-junit4") testImplementation ("com.google.truth:truth:1.2.0")
debugImplementation("androidx.compose.ui:ui-tooling") testImplementation ("androidx.test.ext:truth:1.5.0")
debugImplementation("androidx.compose.ui:ui-test-manifest") 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 // All dependencies
implementation ("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.2") implementation ("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.2")
@ -97,4 +112,7 @@ dependencies {
// Datastore // Datastore
implementation ("androidx.datastore:datastore-preferences:latest.release") implementation ("androidx.datastore:datastore-preferences:latest.release")
// Splash API
implementation ("androidx.core:core-splashscreen:latest.release")
} }

View file

@ -7,17 +7,17 @@
android:allowBackup="true" android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules" android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_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:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.BooksHistoryResurrection" android:theme="@style/Theme.Start.Splash"
tools:targetApi="31"> android:enableOnBackInvokedCallback="true"
tools:targetApi="tiramisu">
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:exported="true" android:exported="true"
android:label="@string/app_name" android:theme="@style/Theme.Start.Splash">
android:theme="@style/Theme.BooksHistoryResurrection">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

View file

@ -4,20 +4,13 @@ import android.os.Bundle
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.compose.foundation.background import androidx.compose.runtime.collectAsState
import androidx.compose.foundation.layout.Box import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
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 com.acclorite.books_history.presentation.MainViewModel import com.acclorite.books_history.presentation.MainViewModel
import com.acclorite.books_history.presentation.NavigationHost import com.acclorite.books_history.presentation.NavigationHost
import com.acclorite.books_history.presentation.Screen import com.acclorite.books_history.presentation.Screen
import com.acclorite.books_history.ui.theme.BooksHistoryResurrectionTheme import com.acclorite.books_history.ui.theme.BooksHistoryResurrectionTheme
import com.acclorite.books_history.ui.theme.isDark
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint @AndroidEntryPoint
@ -27,8 +20,21 @@ class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
mainViewModel.init(this)
installSplashScreen().apply {
setKeepOnScreenCondition {
!mainViewModel.isReady.value
}
}
setContent { 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) { NavigationHost(startScreen = Screen.LIBRARY, this) {
} }

View file

@ -1,10 +1,6 @@
package com.acclorite.books_history.data.di package com.acclorite.books_history.data.di
import android.app.Application 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 androidx.room.Room
import com.acclorite.books_history.data.local.room.BookDao import com.acclorite.books_history.data.local.room.BookDao
import com.acclorite.books_history.data.local.room.BookDatabase import com.acclorite.books_history.data.local.room.BookDatabase

View file

@ -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.DataStore
import com.acclorite.books_history.data.local.data_store.DataStoreImpl 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.data.repository.BookRepositoryImpl
import com.acclorite.books_history.domain.repository.BookRepository import com.acclorite.books_history.domain.repository.BookRepository
import dagger.Binds import dagger.Binds
@ -24,4 +26,10 @@ abstract class RepositoryModule {
abstract fun bindBookRepository( abstract fun bindBookRepository(
bookRepositoryImpl: BookRepositoryImpl bookRepositoryImpl: BookRepositoryImpl
): BookRepository ): BookRepository
@Binds
@Singleton
abstract fun bindBookMapper(
bookMapperImpl: BookMapperImpl
): BookMapper
} }

View file

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

View file

@ -4,7 +4,7 @@ import com.acclorite.books_history.data.local.dto.BookEntity
import com.acclorite.books_history.domain.model.Book import com.acclorite.books_history.domain.model.Book
interface BookMapper { interface BookMapper {
fun Book.toBookEntity(): BookEntity fun toBookEntity(book: Book): BookEntity
fun BookEntity.toBook(): Book fun toBook(bookEntity: BookEntity): Book
} }

View file

@ -5,11 +5,11 @@ import com.acclorite.books_history.domain.model.Book
import javax.inject.Inject import javax.inject.Inject
class BookMapperImpl @Inject constructor(): BookMapper { class BookMapperImpl @Inject constructor(): BookMapper {
override fun Book.toBookEntity(): BookEntity { override fun toBookEntity(book: Book): BookEntity {
TODO("Not yet implemented") TODO("Not yet implemented")
} }
override fun BookEntity.toBook(): Book { override fun toBook(bookEntity: BookEntity): Book {
TODO("Not yet implemented") TODO("Not yet implemented")
} }
} }

View file

@ -3,7 +3,7 @@ package com.acclorite.books_history.data.repository
import androidx.datastore.preferences.core.Preferences import androidx.datastore.preferences.core.Preferences
import com.acclorite.books_history.data.local.data_store.DataStore 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.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.model.Book
import com.acclorite.books_history.domain.repository.BookRepository import com.acclorite.books_history.domain.repository.BookRepository
import com.acclorite.books_history.util.Resource import com.acclorite.books_history.util.Resource
@ -14,7 +14,9 @@ import javax.inject.Singleton
@Singleton @Singleton
class BookRepositoryImpl @Inject constructor( class BookRepositoryImpl @Inject constructor(
private val database: BookDao, private val database: BookDao,
private val dataStore: DataStore private val dataStore: DataStore,
private val bookMapper: BookMapper
) : BookRepository { ) : BookRepository {
override suspend fun getBooks(query: String): Flow<Resource<List<Book>>> { override suspend fun getBooks(query: String): Flow<Resource<List<Book>>> {
@ -22,7 +24,7 @@ class BookRepositoryImpl @Inject constructor(
} }
override suspend fun insertBooks(books: List<Book>) { override suspend fun insertBooks(books: List<Book>) {
database.insertBooks(books.map { it.toBookEntity() }) database.insertBooks(books.map { bookMapper.toBookEntity(it) })
} }
override suspend fun updateBooks(books: List<Book>) { override suspend fun updateBooks(books: List<Book>) {

View file

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

View file

@ -1,8 +1,10 @@
package com.acclorite.books_history.domain.model package com.acclorite.books_history.domain.model
import android.graphics.Bitmap import android.graphics.Bitmap
import androidx.compose.runtime.Immutable
import java.io.File import java.io.File
@Immutable
data class Book( data class Book(
val id: Int, val id: Int,
val title: String, val title: String,

View file

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

View file

@ -1,11 +1,29 @@
package com.acclorite.books_history.domain.use_case package com.acclorite.books_history.domain.use_case
import androidx.activity.ComponentActivity 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 { class ChangeLanguage @Inject constructor(private val repository: BookRepository) {
fun execute( suspend fun execute(language: String, activity: ComponentActivity) {
@Size(max = 2) language: String, val config = activity.resources.configuration
activity: ComponentActivity 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
) )
} }
}

View file

@ -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 <T> execute (key: Preferences.Key<T>, defaultValue: T): Flow<T> {
return repository.retrieveDataFromDataStore(key, defaultValue)
}
}

View file

@ -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<Book>) {
repository.insertBooks(books)
}
}

View file

@ -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 <T> execute (key: Preferences.Key<T>, value: T) {
repository.putDataToDataStore(key, value)
}
}

View file

@ -1,10 +1,28 @@
package com.acclorite.books_history.presentation 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.SavedStateHandle
import androidx.lifecycle.ViewModel 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.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 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 import javax.inject.Inject
/** /**
@ -13,10 +31,276 @@ import javax.inject.Inject
@HiltViewModel @HiltViewModel
class MainViewModel @Inject constructor( class MainViewModel @Inject constructor(
private val stateHandle: SavedStateHandle, 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() { ) : 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<String?>
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<Theme?>
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<DarkTheme?>
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<Boolean?>
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<Long?>
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<Long?>
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<String?>
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<Boolean?>
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<Int?>
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<Int?>
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<Int?>
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<Boolean?>
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
}
}
}
} }

View file

@ -1,7 +1,6 @@
package com.acclorite.books_history.presentation package com.acclorite.books_history.presentation
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.os.Bundle
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.activity.compose.BackHandler import androidx.activity.compose.BackHandler
import androidx.activity.viewModels import androidx.activity.viewModels
@ -20,12 +19,9 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.mutableStateListOf
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.lifecycle.AbstractSavedStateViewModelFactory
import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.createSavedStateHandle
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import androidx.savedstate.SavedStateRegistryOwner
import dagger.assisted.Assisted import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject import dagger.assisted.AssistedInject
@ -34,7 +30,6 @@ import dagger.hilt.android.lifecycle.withCreationCallback
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import javax.inject.Inject
private const val CURRENT_SCREEN = "current_screen" private const val CURRENT_SCREEN = "current_screen"

View file

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

View file

@ -1,11 +1,70 @@
package com.acclorite.books_history.ui.theme 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) enum class Theme {
val PurpleGrey80 = Color(0xFFCCC2DC) DYNAMIC,
val Pink80 = Color(0xFFEFB8C8) BLUE,
PURPLE,
GREEN,
PINK
}
val Purple40 = Color(0xFF6650a4) /**
val PurpleGrey40 = Color(0xFF625b71) * Converting [String] into [Theme].
val Pink40 = Color(0xFF7D5260) */
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)
}
}
}

View file

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

View file

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

View file

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

View file

@ -4,67 +4,70 @@ import android.app.Activity
import android.os.Build import android.os.Build
import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.darkColorScheme import androidx.compose.material3.NavigationBarDefaults
import androidx.compose.material3.dynamicDarkColorScheme import androidx.compose.material3.surfaceColorAtElevation
import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.SideEffect import androidx.compose.runtime.SideEffect
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalView import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.unit.Dp
import androidx.core.view.WindowCompat import androidx.core.view.WindowCompat
private val DarkColorScheme = darkColorScheme( enum class DarkTheme {
primary = Purple80, FOLLOW_SYSTEM,
secondary = PurpleGrey80, OFF,
tertiary = Pink80 ON
) }
private val LightColorScheme = lightColorScheme( fun String.toDarkTheme(): DarkTheme {
primary = Purple40, return when (this) {
secondary = PurpleGrey40, "OFF" -> DarkTheme.OFF
tertiary = Pink40 "ON" -> DarkTheme.ON
else -> DarkTheme.FOLLOW_SYSTEM
}
}
/* Other default colors to override @Composable
background = Color(0xFFFFFBFE), fun DarkTheme.isDark(): Boolean {
surface = Color(0xFFFFFBFE), return when (this) {
onPrimary = Color.White, DarkTheme.FOLLOW_SYSTEM -> isSystemInDarkTheme()
onSecondary = Color.White, DarkTheme.ON -> true
onTertiary = Color.White, DarkTheme.OFF -> false
onBackground = Color(0xFF1C1B1F), }
onSurface = Color(0xFF1C1B1F), }
*/
)
@Composable @Composable
fun BooksHistoryResurrectionTheme( fun BooksHistoryResurrectionTheme(
darkTheme: Boolean = isSystemInDarkTheme(), theme: Theme,
// Dynamic color is available on Android 12+ isDark: Boolean,
dynamicColor: Boolean = true,
content: @Composable () -> Unit 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 val view = LocalView.current
if (!view.isInEditMode) { if (!view.isInEditMode) {
SideEffect { SideEffect {
val window = (view.context as Activity).window val window = (view.context as Activity).window
window.statusBarColor = colorScheme.primary.toArgb() WindowCompat.setDecorFitsSystemWindows(window, false)
WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = darkTheme
window.statusBarColor = Color.Transparent.toArgb()
window.navigationBarColor = Color.Transparent.toArgb()
WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = !isDark
WindowCompat.getInsetsController(window, view).isAppearanceLightNavigationBars = !isDark
} }
} }
MaterialTheme( 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, typography = Typography,
content = content content = content
) )
} }
@Composable
fun MaterialTheme.getElevatedColor(elevation: Dp = NavigationBarDefaults.Elevation): Color =
colorScheme.surfaceColorAtElevation(elevation)

View file

@ -1,5 +1,137 @@
package com.acclorite.books_history.util 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 { 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)
)
)
)
} }

View file

@ -1,19 +1,22 @@
package com.acclorite.books_history.util 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 import androidx.datastore.preferences.core.stringPreferencesKey
object DataStoreConstants { object DataStoreConstants {
val LANGUAGE = stringPreferencesKey("language") val LANGUAGE = stringPreferencesKey("language")
val THEME = stringPreferencesKey("theme") val THEME = stringPreferencesKey("theme")
val DARK_THEME = stringPreferencesKey("dark_theme") val DARK_THEME = stringPreferencesKey("dark_theme")
val GUIDE = stringPreferencesKey("guide") val SHOW_START_SCREEN = booleanPreferencesKey("guide")
val BACKGROUND_COLOR = stringPreferencesKey("background_color") val BACKGROUND_COLOR = longPreferencesKey("background_color")
val FONT_COLOR = stringPreferencesKey("font_color") val FONT_COLOR = longPreferencesKey("font_color")
val FONT = stringPreferencesKey("font") val FONT = stringPreferencesKey("font")
val FONT_STYLE = stringPreferencesKey("font_style") val IS_ITALIC = booleanPreferencesKey("font_style")
val FONT_SIZE = stringPreferencesKey("font_size") val FONT_SIZE = intPreferencesKey("font_size")
val LINE_HEIGHT = stringPreferencesKey("line_height") val LINE_HEIGHT = intPreferencesKey("line_height")
val PARAGRAPH_HEIGHT = stringPreferencesKey("paragraph_height") val PARAGRAPH_HEIGHT = intPreferencesKey("paragraph_height")
val PARAGRAPH_INDENTATION = stringPreferencesKey("paragraph_indentation") val PARAGRAPH_INDENTATION = booleanPreferencesKey("paragraph_indentation")
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View file

@ -1,170 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
</vector>

View file

@ -1,30 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/app_icon_colored"
android:height="75.dp"
android:width="75.dp"
android:gravity="center"
/>
</layer-list>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

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