forked from Writand/writand
feat: datastore for settings with repository
This commit is contained in:
parent
bfd19884a7
commit
0016931726
8 changed files with 274 additions and 0 deletions
|
@ -0,0 +1,31 @@
|
|||
package be.re.writand.data.local
|
||||
|
||||
import androidx.datastore.core.CorruptionException
|
||||
import androidx.datastore.core.Serializer
|
||||
import be.re.writand.ProtoSettings
|
||||
import com.google.protobuf.InvalidProtocolBufferException
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Serializer that helps with storing and transferring the data of the UserSettings DataStore.
|
||||
*/
|
||||
class SettingsSerializer @Inject constructor() : Serializer<ProtoSettings> {
|
||||
|
||||
override val defaultValue: ProtoSettings = ProtoSettings.getDefaultInstance()
|
||||
|
||||
override suspend fun readFrom(input: InputStream): ProtoSettings {
|
||||
try {
|
||||
return ProtoSettings.parseFrom(input)
|
||||
} catch (exception: InvalidProtocolBufferException) {
|
||||
throw CorruptionException("Cannot read proto.", exception)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun writeTo(
|
||||
t: ProtoSettings,
|
||||
output: OutputStream
|
||||
) = t.writeTo(output)
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package be.re.writand.data.local.models
|
||||
|
||||
/**
|
||||
* Enum class containing the possible languages supported by the app.
|
||||
*/
|
||||
enum class UserLanguage {
|
||||
ENGLISH,
|
||||
DUTCH
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum class containing the possible themes supported by the app.
|
||||
*/
|
||||
enum class UserTheme {
|
||||
DARK,
|
||||
LIGHT
|
||||
}
|
||||
|
||||
/**
|
||||
* Data class that stores all the information of the user settings.
|
||||
* @param[userLanguage] the language used in the app, by default English.
|
||||
* @param[userTheme] the theme that is currently used by the user or the default dark theme.
|
||||
* @param[maxSavedProjects] the amount of different projects to save extra information
|
||||
* on the local device such as UserSettings and ProjectEntity.
|
||||
* @param[maxSavedFiles] the amount of open files to be saved per project in local storage
|
||||
* for when the project is opened again.
|
||||
* @param[fontSize] font size used in the GUI.
|
||||
*/
|
||||
data class UserSettings(
|
||||
var userLanguage: UserLanguage = UserLanguage.ENGLISH,
|
||||
var userTheme: UserTheme = UserTheme.DARK,
|
||||
var maxSavedProjects: Int = 3,
|
||||
var maxSavedFiles: Int = 5,
|
||||
var fontSize: Int = 10
|
||||
)
|
|
@ -0,0 +1,23 @@
|
|||
package be.re.writand.data.repos.settings
|
||||
|
||||
import be.re.writand.data.local.models.UserLanguage
|
||||
import be.re.writand.data.local.models.UserSettings
|
||||
import be.re.writand.data.local.models.UserTheme
|
||||
|
||||
/**
|
||||
* Repository containing getters and setters to interact with all of the user settings
|
||||
*/
|
||||
interface IUserSettingsRepository {
|
||||
|
||||
suspend fun getUserSettings(): UserSettings
|
||||
|
||||
suspend fun setLanguage(userLanguage: UserLanguage)
|
||||
|
||||
suspend fun setTheme(userTheme: UserTheme)
|
||||
|
||||
suspend fun setMaxSavedProjects(maxSaved: Int)
|
||||
|
||||
suspend fun setMaxSavedFiles(maxSaved: Int)
|
||||
|
||||
suspend fun setFontSize(size: Int)
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
package be.re.writand.data.repos.settings
|
||||
|
||||
import androidx.datastore.core.DataStore
|
||||
import be.re.writand.ProtoSettings
|
||||
import be.re.writand.data.local.models.UserLanguage
|
||||
import be.re.writand.data.local.models.UserSettings
|
||||
import be.re.writand.data.local.models.UserTheme
|
||||
import be.re.writand.utils.toProtoLanguage
|
||||
import be.re.writand.utils.toProtoTheme
|
||||
import be.re.writand.utils.toUserLanguage
|
||||
import be.re.writand.utils.toUserTheme
|
||||
import kotlinx.coroutines.flow.first
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class UserSettingsRepository @Inject constructor(
|
||||
private val store: DataStore<ProtoSettings>
|
||||
) : IUserSettingsRepository {
|
||||
|
||||
private val userSettings = store.data
|
||||
|
||||
override suspend fun getUserSettings(): UserSettings {
|
||||
return UserSettings(
|
||||
userLanguage = userSettings.first().language.toUserLanguage(),
|
||||
userTheme = userSettings.first().theme.toUserTheme(),
|
||||
maxSavedProjects = userSettings.first().maxSavedProjects,
|
||||
maxSavedFiles = userSettings.first().maxSavedFiles,
|
||||
fontSize = userSettings.first().fontSize
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun setLanguage(userLanguage: UserLanguage) {
|
||||
store.updateData {
|
||||
val builder = it.toBuilder()
|
||||
builder.setLanguage(userLanguage.toProtoLanguage())
|
||||
builder.build()
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun setTheme(userTheme: UserTheme) {
|
||||
store.updateData {
|
||||
val builder = it.toBuilder()
|
||||
builder.setTheme(userTheme.toProtoTheme())
|
||||
builder.build()
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun setMaxSavedProjects(maxSaved: Int) {
|
||||
store.updateData {
|
||||
val builder = it.toBuilder()
|
||||
builder.setMaxSavedProjects(maxSaved)
|
||||
builder.build()
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun setMaxSavedFiles(maxSaved: Int) {
|
||||
store.updateData {
|
||||
val builder = it.toBuilder()
|
||||
builder.setMaxSavedFiles(maxSaved)
|
||||
builder.build()
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun setFontSize(size: Int) {
|
||||
store.updateData {
|
||||
val builder = it.toBuilder()
|
||||
builder.setFontSize(size)
|
||||
builder.build()
|
||||
}
|
||||
}
|
||||
}
|
31
app/src/main/java/be/re/writand/di/DataStoreModule.kt
Normal file
31
app/src/main/java/be/re/writand/di/DataStoreModule.kt
Normal file
|
@ -0,0 +1,31 @@
|
|||
package be.re.writand.di
|
||||
|
||||
import android.content.Context
|
||||
import androidx.datastore.core.DataStore
|
||||
import androidx.datastore.core.DataStoreFactory
|
||||
import androidx.datastore.dataStoreFile
|
||||
import be.re.writand.ProtoSettings
|
||||
import be.re.writand.data.local.SettingsSerializer
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import javax.inject.Singleton
|
||||
|
||||
/**
|
||||
* Stores data locally, contains the settings information (see file: settings.proto).
|
||||
*/
|
||||
@InstallIn(SingletonComponent::class)
|
||||
@Module
|
||||
class DataStoreModule {
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideDataStore(
|
||||
@ApplicationContext context: Context,
|
||||
serializer: SettingsSerializer
|
||||
): DataStore<ProtoSettings> =
|
||||
DataStoreFactory.create(serializer = serializer) {
|
||||
context.dataStoreFile("settings.proto")
|
||||
}
|
||||
}
|
50
app/src/main/java/be/re/writand/utils/ObjectMapping.kt
Normal file
50
app/src/main/java/be/re/writand/utils/ObjectMapping.kt
Normal file
|
@ -0,0 +1,50 @@
|
|||
package be.re.writand.utils
|
||||
|
||||
import be.re.writand.ProtoLanguage
|
||||
import be.re.writand.ProtoTheme
|
||||
import be.re.writand.data.local.models.UserLanguage
|
||||
import be.re.writand.data.local.models.UserTheme
|
||||
|
||||
/**
|
||||
* Method of ProtoLanguage to get the corresponding UserLanguage.
|
||||
*/
|
||||
fun ProtoLanguage.toUserLanguage(): UserLanguage {
|
||||
return if (this == ProtoLanguage.PROTO_LANGUAGE_ENGLISH) {
|
||||
UserLanguage.ENGLISH
|
||||
} else {
|
||||
UserLanguage.DUTCH
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method of UserLanguage to get the corresponding ProtoLanguage.
|
||||
*/
|
||||
fun UserLanguage.toProtoLanguage(): ProtoLanguage {
|
||||
return if (this == UserLanguage.ENGLISH) {
|
||||
ProtoLanguage.PROTO_LANGUAGE_ENGLISH
|
||||
} else {
|
||||
ProtoLanguage.PROTO_LANGUAGE_DUTCH
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method of ProtoTheme to get the corresponding UserTheme.
|
||||
*/
|
||||
fun ProtoTheme.toUserTheme(): UserTheme {
|
||||
return if (this == ProtoTheme.PROTO_THEME_DARK) {
|
||||
UserTheme.DARK
|
||||
} else {
|
||||
UserTheme.LIGHT
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method of UserTheme to get the corresponding ProtoTheme.
|
||||
*/
|
||||
fun UserTheme.toProtoTheme(): ProtoTheme {
|
||||
return if (this == UserTheme.DARK) {
|
||||
ProtoTheme.PROTO_THEME_DARK
|
||||
} else {
|
||||
ProtoTheme.PROTO_THEME_LIGHT
|
||||
}
|
||||
}
|
32
app/src/main/proto/settings.proto
Normal file
32
app/src/main/proto/settings.proto
Normal file
|
@ -0,0 +1,32 @@
|
|||
syntax = "proto3";
|
||||
|
||||
option java_package = "be.re.writand";
|
||||
option java_multiple_files = true;
|
||||
|
||||
/**
|
||||
* The available languages supported by the app that will be stored locally.
|
||||
*/
|
||||
enum ProtoLanguage {
|
||||
PROTO_LANGUAGE_ENGLISH = 0;
|
||||
PROTO_LANGUAGE_DUTCH = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* The available themes supported by the app that will be stored locally.
|
||||
*/
|
||||
enum ProtoTheme {
|
||||
PROTO_THEME_DARK = 0;
|
||||
PROTO_THEME_LIGHT = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* The structure of what user settings holds, this is stored locally.
|
||||
* NOTE: the "= x" does not initialize the values of the elements, these are field numbers.
|
||||
*/
|
||||
message ProtoSettings {
|
||||
ProtoLanguage language = 1;
|
||||
ProtoTheme theme = 2;
|
||||
uint32 max_saved_projects = 3;
|
||||
uint32 max_saved_files = 4;
|
||||
uint32 font_size = 5;
|
||||
};
|
Loading…
Reference in a new issue