Skip to content

Commit 6389309

Browse files
authored
- updates backup method from csv to json
in order to support multiple database tables #40 #28
1 parent e8638cc commit 6389309

File tree

7 files changed

+197
-125
lines changed

7 files changed

+197
-125
lines changed

app/src/main/AndroidManifest.xml

-1
Original file line numberDiff line numberDiff line change
@@ -46,5 +46,4 @@
4646
android:resource="@xml/file_paths" />
4747
</provider>
4848
</application>
49-
5049
</manifest>

app/src/main/java/cloud/pablos/overload/data/item/ItemDao.kt

+35-14
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import androidx.room.Upsert
77
import cloud.pablos.overload.ui.tabs.home.getItemsOfDay
88
import cloud.pablos.overload.ui.views.extractDate
99
import cloud.pablos.overload.ui.views.parseToLocalDateTime
10+
import com.google.gson.Gson
1011
import kotlinx.coroutines.flow.Flow
1112
import java.time.LocalDate
1213
import java.time.LocalDateTime
@@ -29,25 +30,45 @@ interface ItemDao {
2930
fun getAllItems(): Flow<List<Item>>
3031
}
3132

33+
data class DatabaseBackup(
34+
val data: Map<String, List<Map<String, Any>>>,
35+
val backupVersion: Int,
36+
val backupDate: String,
37+
)
38+
3239
// Export function
33-
fun backupItemsToCsv(state: ItemState): String {
34-
val items = state.items
35-
/*val gson = Gson()
40+
fun backupItemsToJson(state: ItemState): String {
41+
val gson = Gson()
42+
43+
val itemsTable =
44+
state.items.map { item ->
45+
mapOf(
46+
"id" to item.id,
47+
"startTime" to item.startTime,
48+
"endTime" to item.endTime,
49+
"ongoing" to item.ongoing,
50+
"pause" to item.pause,
51+
)
52+
}
53+
54+
val data =
55+
mapOf(
56+
"items" to itemsTable,
57+
)
58+
59+
val backup =
60+
DatabaseBackup(
61+
data,
62+
2,
63+
LocalDateTime.now().toString(),
64+
)
3665

3766
return try {
38-
val json = gson.toJson(items)
67+
val json = gson.toJson(backup)
3968
json
4069
} catch (e: Exception) {
41-
"{}" // Return a placeholder JSON object
42-
}*/
43-
44-
val csvHeader = "id,startTime,endTime,ongoing,pause\n"
45-
val csvData =
46-
items.joinToString("\n") { item ->
47-
"${item.id},${item.startTime},${item.endTime},${item.ongoing},${item.pause}"
48-
}
49-
50-
return csvHeader + csvData
70+
"{}"
71+
}
5172
}
5273

5374
fun startOrStopPause(
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,30 @@
11
package cloud.pablos.overload.data.item
22

3+
import android.content.Context
34
import androidx.room.Database
5+
import androidx.room.Room
46
import androidx.room.RoomDatabase
57

68
@Database(entities = [Item::class], version = 1)
79
abstract class ItemDatabase : RoomDatabase() {
810
abstract fun itemDao(): ItemDao
11+
12+
companion object {
13+
const val DATABASE_NAME = "items"
14+
15+
@Volatile private var instance: ItemDatabase? = null
16+
17+
fun getInstance(context: Context): ItemDatabase =
18+
instance
19+
?: synchronized(this) {
20+
instance ?: buildDatabase(context).also { instance = it }
21+
}
22+
23+
private fun buildDatabase(context: Context) =
24+
Room.databaseBuilder(
25+
context.applicationContext,
26+
ItemDatabase::class.java,
27+
DATABASE_NAME,
28+
).build()
29+
}
930
}

app/src/main/java/cloud/pablos/overload/ui/MainActivity.kt

+22
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
package cloud.pablos.overload.ui
22

33
import android.annotation.SuppressLint
4+
import android.app.Activity
45
import android.content.pm.ActivityInfo
56
import android.content.res.Configuration
67
import android.os.Build
78
import android.os.Bundle
89
import androidx.activity.ComponentActivity
910
import androidx.activity.compose.setContent
11+
import androidx.activity.result.contract.ActivityResultContracts
1012
import androidx.activity.viewModels
1113
import androidx.annotation.RequiresApi
1214
import androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi
@@ -22,8 +24,11 @@ import cloud.pablos.overload.R
2224
import cloud.pablos.overload.data.item.ItemDatabase
2325
import cloud.pablos.overload.data.item.ItemViewModel
2426
import cloud.pablos.overload.ui.tabs.configurations.handleIntent
27+
import cloud.pablos.overload.ui.tabs.configurations.importJsonFile
28+
import cloud.pablos.overload.ui.tabs.configurations.showImportFailedToast
2529
import cloud.pablos.overload.ui.theme.OverloadTheme
2630
import com.google.accompanist.adaptive.calculateDisplayFeatures
31+
import kotlinx.coroutines.launch
2732

2833
class MainActivity : ComponentActivity() {
2934
private val db by lazy {
@@ -44,6 +49,22 @@ class MainActivity : ComponentActivity() {
4449
},
4550
)
4651

52+
private val filePickerLauncher =
53+
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
54+
if (result.resultCode == Activity.RESULT_OK) {
55+
val uri = result.data?.data
56+
uri?.let {
57+
lifecycleScope.launch {
58+
importJsonFile(it, contentResolver, applicationContext, db, lifecycleScope)
59+
}
60+
} ?: run {
61+
showImportFailedToast(applicationContext)
62+
}
63+
} else {
64+
showImportFailedToast(applicationContext)
65+
}
66+
}
67+
4768
@SuppressLint("SourceLockedOrientationActivity") // The text of dialogs does not fit the screen when not in portrait
4869
@RequiresApi(Build.VERSION_CODES.S)
4970
@OptIn(ExperimentalMaterial3WindowSizeClassApi::class)
@@ -72,6 +93,7 @@ class MainActivity : ComponentActivity() {
7293
displayFeatures = displayFeatures,
7394
state = state,
7495
onEvent = onEvent,
96+
filePickerLauncher = filePickerLauncher,
7597
)
7698
}
7799
}

app/src/main/java/cloud/pablos/overload/ui/OverloadApp.kt

+11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package cloud.pablos.overload.ui
22

3+
import android.content.Intent
34
import android.os.Build
5+
import androidx.activity.result.ActivityResultLauncher
46
import androidx.annotation.RequiresApi
57
import androidx.compose.animation.AnimatedVisibility
68
import androidx.compose.foundation.background
@@ -64,6 +66,7 @@ fun OverloadApp(
6466
displayFeatures: List<DisplayFeature>,
6567
state: ItemState,
6668
onEvent: (ItemEvent) -> Unit,
69+
filePickerLauncher: ActivityResultLauncher<Intent>,
6770
) {
6871
val navigationType: OverloadNavigationType
6972
val contentType: OverloadContentType
@@ -136,6 +139,7 @@ fun OverloadApp(
136139
navigationContentPosition = navigationContentPosition,
137140
state = state,
138141
onEvent = onEvent,
142+
filePickerLauncher = filePickerLauncher,
139143
)
140144
}
141145

@@ -147,6 +151,7 @@ private fun OverloadNavigationWrapper(
147151
navigationContentPosition: OverloadNavigationContentPosition,
148152
state: ItemState,
149153
onEvent: (ItemEvent) -> Unit,
154+
filePickerLauncher: ActivityResultLauncher<Intent>,
150155
) {
151156
val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
152157
val scope = rememberCoroutineScope()
@@ -176,6 +181,7 @@ private fun OverloadNavigationWrapper(
176181
},
177182
state = state,
178183
onEvent = onEvent,
184+
filePickerLauncher = filePickerLauncher,
179185
)
180186
}
181187

@@ -211,6 +217,7 @@ private fun OverloadNavigationWrapper(
211217
},
212218
state = state,
213219
onEvent = onEvent,
220+
filePickerLauncher = filePickerLauncher,
214221
)
215222
}
216223
}
@@ -230,6 +237,7 @@ fun OverloadAppContent(
230237
onDrawerClicked: () -> Unit = {},
231238
state: ItemState,
232239
onEvent: (ItemEvent) -> Unit,
240+
filePickerLauncher: ActivityResultLauncher<Intent>,
233241
) {
234242
var forgotDialogState by remember { mutableStateOf(false) }
235243
LaunchedEffect(state.isForgotToStopDialogShown) {
@@ -269,6 +277,7 @@ fun OverloadAppContent(
269277
navController = navController,
270278
state = state,
271279
onEvent = onEvent,
280+
filePickerLauncher = filePickerLauncher,
272281
modifier =
273282
Modifier
274283
.weight(1f)
@@ -328,6 +337,7 @@ private fun OverloadNavHost(
328337
modifier: Modifier = Modifier,
329338
state: ItemState,
330339
onEvent: (ItemEvent) -> Unit,
340+
filePickerLauncher: ActivityResultLauncher<Intent>,
331341
) {
332342
NavHost(
333343
modifier = modifier,
@@ -359,6 +369,7 @@ private fun OverloadNavHost(
359369
ConfigurationsTab(
360370
state = state,
361371
onEvent = onEvent,
372+
filePickerLauncher = filePickerLauncher,
362373
)
363374
}
364375
}

0 commit comments

Comments
 (0)