@@ -2,60 +2,130 @@ package dev.pranav.reef.util
22
33import android.content.Context
44import androidx.core.content.edit
5- import com.google.gson.GsonBuilder
6- import com.google.gson.JsonDeserializationContext
7- import com.google.gson.JsonDeserializer
8- import com.google.gson.JsonElement
9- import com.google.gson.JsonPrimitive
10- import com.google.gson.JsonSerializationContext
11- import com.google.gson.JsonSerializer
12- import com.google.gson.reflect.TypeToken
135import dev.pranav.reef.data.Routine
146import dev.pranav.reef.data.RoutineSchedule
15- import java.lang.reflect.Type
7+ import org.json.JSONArray
8+ import org.json.JSONObject
169import java.time.DayOfWeek
1710import java.util.UUID
1811
1912object RoutineManager {
2013 private const val ROUTINES_KEY = " routines"
2114
22- private val gson = GsonBuilder ()
23- .registerTypeAdapter(DayOfWeek ::class .java, object : JsonSerializer <DayOfWeek > {
24- override fun serialize (
25- src : DayOfWeek ? ,
26- typeOfSrc : Type ? ,
27- context : JsonSerializationContext ?
28- ): JsonElement {
29- return JsonPrimitive (src?.name)
15+ fun getRoutines (): List <Routine > {
16+ val json = prefs.getString(ROUTINES_KEY , " []" ) ? : " []"
17+ return try {
18+ val jsonArray = JSONArray (json)
19+ val routines = mutableListOf<Routine >()
20+
21+ for (i in 0 until jsonArray.length()) {
22+ val routineJson = jsonArray.getJSONObject(i)
23+ val routine = parseRoutine(routineJson)
24+ if (routine != null ) {
25+ routines.add(routine)
26+ }
3027 }
31- })
32- .registerTypeAdapter(DayOfWeek ::class .java, object : JsonDeserializer <DayOfWeek > {
33- override fun deserialize (
34- json : JsonElement ? ,
35- typeOfT : Type ? ,
36- context : JsonDeserializationContext ?
37- ): DayOfWeek ? {
38- return json?.asString?.let { DayOfWeek .valueOf(it) }
28+ routines
29+ } catch (_: Exception ) {
30+ emptyList()
31+ }
32+ }
33+
34+ private fun parseRoutine (json : JSONObject ): Routine ? {
35+ return try {
36+ val scheduleJson = json.getJSONObject(" schedule" )
37+ val schedule = RoutineSchedule (
38+ type = RoutineSchedule .ScheduleType .valueOf(scheduleJson.getString(" type" )),
39+ timeHour = if (scheduleJson.has(" timeHour" )) scheduleJson.getInt(" timeHour" ) else null ,
40+ timeMinute = if (scheduleJson.has(" timeMinute" )) scheduleJson.getInt(" timeMinute" ) else null ,
41+ endTimeHour = if (scheduleJson.has(" endTimeHour" )) scheduleJson.getInt(" endTimeHour" ) else null ,
42+ endTimeMinute = if (scheduleJson.has(" endTimeMinute" )) scheduleJson.getInt(" endTimeMinute" ) else null ,
43+ daysOfWeek = parseDaysOfWeek(scheduleJson.optJSONArray(" daysOfWeek" )),
44+ isRecurring = scheduleJson.optBoolean(" isRecurring" , true )
45+ )
46+
47+ val limitsArray = json.getJSONArray(" limits" )
48+ val limits = mutableListOf<Routine .AppLimit >()
49+ for (i in 0 until limitsArray.length()) {
50+ val limitJson = limitsArray.getJSONObject(i)
51+ limits.add(
52+ Routine .AppLimit (
53+ packageName = limitJson.getString(" packageName" ),
54+ limitMinutes = limitJson.getInt(" limitMinutes" )
55+ )
56+ )
3957 }
40- })
41- .create()
4258
43- fun getRoutines (): List <Routine > {
44- val json = prefs.getString(ROUTINES_KEY , " []" ) ? : " []"
45- val type = object : TypeToken <List <Routine >>() {}.type
46- return gson.fromJson(json, type)
59+ Routine (
60+ id = json.getString(" id" ),
61+ name = json.getString(" name" ),
62+ isEnabled = json.getBoolean(" isEnabled" ),
63+ schedule = schedule,
64+ limits = limits
65+ )
66+ } catch (_: Exception ) {
67+ null
68+ }
69+ }
70+
71+ private fun parseDaysOfWeek (jsonArray : JSONArray ? ): Set <DayOfWeek > {
72+ if (jsonArray == null ) return emptySet()
73+ val days = mutableSetOf<DayOfWeek >()
74+ for (i in 0 until jsonArray.length()) {
75+ try {
76+ days.add(DayOfWeek .valueOf(jsonArray.getString(i)))
77+ } catch (_: Exception ) {
78+ // Skip invalid days
79+ }
80+ }
81+ return days
4782 }
4883
4984 fun saveRoutines (routines : List <Routine >, context : Context ? = null) {
50- val json = gson.toJson(routines)
51- prefs.edit { putString(ROUTINES_KEY , json) }
85+ val jsonArray = JSONArray ()
86+ routines.forEach { routine ->
87+ jsonArray.put(routineToJson(routine))
88+ }
89+ prefs.edit { putString(ROUTINES_KEY , jsonArray.toString()) }
5290
53- // Reschedule all routines when saved
5491 context?.let { ctx ->
5592 RoutineScheduler .scheduleAllRoutines(ctx)
5693 }
5794 }
5895
96+ private fun routineToJson (routine : Routine ): JSONObject {
97+ return JSONObject ().apply {
98+ put(" id" , routine.id)
99+ put(" name" , routine.name)
100+ put(" isEnabled" , routine.isEnabled)
101+
102+ val schedule = routine.schedule
103+ val scheduleJson = JSONObject ().apply {
104+ put(" type" , schedule?.type?.name ? : " MANUAL" )
105+ schedule?.timeHour?.let { put(" timeHour" , it) }
106+ schedule?.timeMinute?.let { put(" timeMinute" , it) }
107+ schedule?.endTimeHour?.let { put(" endTimeHour" , it) }
108+ schedule?.endTimeMinute?.let { put(" endTimeMinute" , it) }
109+
110+ val daysArray = JSONArray ()
111+ schedule?.daysOfWeek?.forEach { daysArray.put(it.name) }
112+ put(" daysOfWeek" , daysArray)
113+
114+ put(" isRecurring" , schedule?.isRecurring ? : true )
115+ }
116+ put(" schedule" , scheduleJson)
117+
118+ val limitsArray = JSONArray ()
119+ routine.limits.forEach { limit ->
120+ limitsArray.put(JSONObject ().apply {
121+ put(" packageName" , limit.packageName)
122+ put(" limitMinutes" , limit.limitMinutes)
123+ })
124+ }
125+ put(" limits" , limitsArray)
126+ }
127+ }
128+
59129 fun addRoutine (routine : Routine , context : Context ? = null) {
60130 val routines = getRoutines().toMutableList()
61131 routines.add(routine)
@@ -89,16 +159,13 @@ object RoutineManager {
89159
90160 context?.let { ctx ->
91161 if (oldRoutine.isEnabled) {
92- // Was enabled, now disabled - cancel scheduling and clear limits if active
93162 RoutineScheduler .cancelRoutine(ctx, routineId)
94163
95- // Check if this routine is currently active and clear its limits
96164 val activeRoutineId = RoutineLimits .getActiveRoutineId()
97165 if (activeRoutineId == routineId) {
98166 RoutineLimits .clearRoutineLimits()
99167 }
100168 } else {
101- // Was disabled, now enabled - schedule it
102169 RoutineScheduler .scheduleRoutine(ctx, routines[index])
103170 }
104171 }
0 commit comments