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