@@ -19,19 +19,13 @@ package com.codelab.android.datastore.data
19
19
import android.content.Context
20
20
import android.util.Log
21
21
import androidx.datastore.DataStore
22
- import androidx.datastore.preferences.PreferenceDataStoreFactory
23
- import androidx.datastore.preferences.Preferences
24
- import androidx.datastore.preferences.SharedPreferencesMigration
22
+ import androidx.datastore.preferences.*
25
23
import kotlinx.coroutines.flow.Flow
26
24
import kotlinx.coroutines.flow.catch
27
25
import kotlinx.coroutines.flow.map
28
- import java.io.File
29
26
import java.io.IOException
30
27
31
28
private const val USER_PREFERENCES_NAME = " user_preferences"
32
- private const val USER_PREFERENCES_STORE_FILE_NAME = " user.preferences_pb"
33
- private const val SORT_ORDER_KEY = " sort_order"
34
- private const val SHOW_COMPLETED_KEY = " show_completed"
35
29
36
30
enum class SortOrder {
37
31
NONE ,
@@ -41,24 +35,10 @@ enum class SortOrder {
41
35
}
42
36
43
37
data class UserPreferences (
44
- val showCompleted : Boolean ,
38
+ val showCompleted : Boolean = false ,
45
39
val sortOrder : SortOrder
46
40
)
47
41
48
- /* *
49
- * Extension function on Preferences to easily get the sort order
50
- */
51
- private fun Preferences.getSortOrder (): SortOrder {
52
- val order = getString(SORT_ORDER_KEY , SortOrder .NONE .name)
53
- return SortOrder .valueOf(order)
54
- }
55
-
56
- /* *
57
- * Extension function on Preferences to easily set the sort order
58
- */
59
- private fun Preferences.withSortOrder (newSortOrder : SortOrder ) =
60
- this .toBuilder().setString(SORT_ORDER_KEY , newSortOrder.name).build()
61
-
62
42
/* *
63
43
* Class that handles saving and retrieving user preferences
64
44
*/
@@ -67,19 +47,17 @@ class UserPreferencesRepository private constructor(context: Context) {
67
47
private val TAG : String = " UserPreferencesRepo"
68
48
69
49
private val dataStore: DataStore <Preferences > by lazy {
70
- PreferenceDataStoreFactory ().create(
71
- produceFile = {
72
- File (
73
- context.applicationContext.filesDir,
74
- USER_PREFERENCES_STORE_FILE_NAME
75
- )
76
- },
77
- // Since we're migrating from SharedPreferences, add a migration based on the
78
- // SharedPreferences name
79
- migrationProducers = listOf (SharedPreferencesMigration (context, USER_PREFERENCES_NAME ))
50
+ context.createDataStore(
51
+ name = USER_PREFERENCES_NAME ,
52
+ migrations = listOf (SharedPreferencesMigration (context, USER_PREFERENCES_NAME ))
80
53
)
81
54
}
82
55
56
+ private object Keys {
57
+ internal val SORT_ORDER_KEY = preferencesKey<String >(" sort_order" )
58
+ internal val SHOW_COMPLETED_KEY = preferencesKey<Boolean >(" show_completed" )
59
+ }
60
+
83
61
/* *
84
62
* Get the user preferences flow.
85
63
*/
@@ -88,14 +66,17 @@ class UserPreferencesRepository private constructor(context: Context) {
88
66
// dataStore.data throws an IOException when an error is encountered when reading data
89
67
if (exception is IOException ) {
90
68
Log .e(TAG , " Error reading preferences." , exception)
91
- emit(Preferences .empty ())
69
+ emit(emptyPreferences ())
92
70
} else {
93
71
throw exception
94
72
}
95
73
}.map { preferences ->
96
74
// Get the sort order from preferences and convert it to a [SortOrder] object
97
- val sortOrder = preferences.getSortOrder()
98
- val showCompleted = preferences.getBoolean(SHOW_COMPLETED_KEY , false )
75
+ val sortOrder =
76
+ SortOrder .valueOf(
77
+ preferences[Keys .SORT_ORDER_KEY ] ? : SortOrder .NONE .name
78
+ )
79
+ val showCompleted = preferences[Keys .SHOW_COMPLETED_KEY ] ? : false
99
80
UserPreferences (showCompleted, sortOrder)
100
81
}
101
82
@@ -105,9 +86,10 @@ class UserPreferencesRepository private constructor(context: Context) {
105
86
suspend fun enableSortByDeadline (enable : Boolean ) {
106
87
// updateData handles data transactionally, ensuring that if the sort is updated at the same
107
88
// time from another thread, we won't have conflicts
108
- dataStore.updateData { currentPreferences ->
109
- val currentOrder = currentPreferences.getSortOrder()
110
- val newSortOrder =
89
+ dataStore.edit { prefs ->
90
+ val currentOrder = prefs[Keys .SORT_ORDER_KEY ]?.let { SortOrder .valueOf(it) }
91
+
92
+ val newSortOrder =
111
93
if (enable) {
112
94
if (currentOrder == SortOrder .BY_PRIORITY ) {
113
95
SortOrder .BY_DEADLINE_AND_PRIORITY
@@ -121,7 +103,8 @@ class UserPreferencesRepository private constructor(context: Context) {
121
103
SortOrder .NONE
122
104
}
123
105
}
124
- currentPreferences.withSortOrder(newSortOrder)
106
+
107
+ prefs[Keys .SORT_ORDER_KEY ] = newSortOrder.name
125
108
}
126
109
}
127
110
@@ -131,8 +114,9 @@ class UserPreferencesRepository private constructor(context: Context) {
131
114
suspend fun enableSortByPriority (enable : Boolean ) {
132
115
// updateData handles data transactionally, ensuring that if the sort is updated at the same
133
116
// time from another thread, we won't have conflicts
134
- dataStore.updateData { currentPreferences ->
135
- val currentOrder = currentPreferences.getSortOrder()
117
+ dataStore.edit { prefs ->
118
+ val currentOrder = prefs[Keys .SORT_ORDER_KEY ]?.let { SortOrder .valueOf(it) }
119
+
136
120
val newSortOrder =
137
121
if (enable) {
138
122
if (currentOrder == SortOrder .BY_DEADLINE ) {
@@ -147,13 +131,14 @@ class UserPreferencesRepository private constructor(context: Context) {
147
131
SortOrder .NONE
148
132
}
149
133
}
150
- currentPreferences.withSortOrder(newSortOrder)
134
+
135
+ prefs[Keys .SORT_ORDER_KEY ] = newSortOrder.name
151
136
}
152
137
}
153
138
154
139
suspend fun updateShowCompleted (showCompleted : Boolean ) {
155
- dataStore.updateData { currentPreferences ->
156
- currentPreferences.toBuilder().setBoolean( SHOW_COMPLETED_KEY , showCompleted).build()
140
+ dataStore.edit { prefs ->
141
+ prefs[ Keys . SHOW_COMPLETED_KEY ] = showCompleted
157
142
}
158
143
}
159
144
0 commit comments