-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
22 changed files
with
703 additions
and
397 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
16 changes: 16 additions & 0 deletions
16
app/src/main/java/com/android/periodpals/model/location/UserLocationDto.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package com.android.periodpals.model.location | ||
|
||
import kotlinx.serialization.SerialName | ||
import kotlinx.serialization.Serializable | ||
|
||
/** | ||
* Data Transfer Object (DTO) representing a user's location. | ||
* | ||
* @property uid The unique identifier of the user. | ||
* @property location The geographical location of the user. | ||
*/ | ||
@Serializable | ||
data class UserLocationDto( | ||
@SerialName("uid") val uid: String, | ||
@SerialName("locationGIS") val location: LocationGIS, | ||
) |
31 changes: 31 additions & 0 deletions
31
app/src/main/java/com/android/periodpals/model/location/UserLocationModel.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package com.android.periodpals.model.location | ||
|
||
/** Interface representing a model for user location. */ | ||
interface UserLocationModel { | ||
|
||
/** | ||
* Creates a new location. | ||
* | ||
* @param locationDto The [Location] data transfer object to be inserted. | ||
* @param onSuccess A callback function to be invoked upon successful operation. | ||
* @param onFailure A callback function to be invoked with an `Exception` if the operation fails. | ||
*/ | ||
suspend fun create( | ||
locationDto: UserLocationDto, | ||
onSuccess: () -> Unit, | ||
onFailure: (Exception) -> Unit, | ||
) | ||
|
||
/** | ||
* Inserts or updates a location. | ||
* | ||
* @param locationDto The [Location] data transfer object to be inserted or updated. | ||
* @param onSuccess A callback function to be invoked upon successful operation. | ||
* @param onFailure A callback function to be invoked with an `Exception` if the operation fails. | ||
*/ | ||
suspend fun update( | ||
locationDto: UserLocationDto, | ||
onSuccess: () -> Unit, | ||
onFailure: (Exception) -> Unit, | ||
) | ||
} |
70 changes: 70 additions & 0 deletions
70
app/src/main/java/com/android/periodpals/model/location/UserLocationModelSupabase.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package com.android.periodpals.model.location | ||
|
||
import android.util.Log | ||
import io.github.jan.supabase.SupabaseClient | ||
import io.github.jan.supabase.postgrest.postgrest | ||
import kotlinx.coroutines.Dispatchers | ||
import kotlinx.coroutines.withContext | ||
|
||
/** | ||
* Implementation of the UserLocationModel interface using Supabase. | ||
* | ||
* @property supabase The Supabase client used for database operations. | ||
*/ | ||
class UserLocationModelSupabase(private val supabase: SupabaseClient) : UserLocationModel { | ||
|
||
companion object { | ||
private const val TAG = "UserLocationModelSupabase" | ||
private const val LOCATIONS = "locations" | ||
} | ||
|
||
/** | ||
* Creates a new location in the Supabase database. | ||
* | ||
* @param locationDto The [LocationGIS] data transfer object to be inserted. | ||
* @param onSuccess A callback function to be invoked upon successful operation. | ||
* @param onFailure A callback function to be invoked with an Exception if the operation fails. | ||
*/ | ||
override suspend fun create( | ||
locationDto: UserLocationDto, | ||
onSuccess: () -> Unit, | ||
onFailure: (Exception) -> Unit, | ||
) { | ||
Log.d(TAG, "create: sending location dto: $locationDto") | ||
try { | ||
withContext(Dispatchers.IO) { | ||
supabase.postgrest[LOCATIONS].insert(locationDto) | ||
Log.d(TAG, "create: success") | ||
onSuccess() | ||
} | ||
} catch (e: Exception) { | ||
Log.e(TAG, "create: fail to create location of user ${locationDto.uid}: ${e.message}") | ||
onFailure(e) | ||
} | ||
} | ||
|
||
/** | ||
* Updates a location in the Supabase database. | ||
* | ||
* @param locationDto The [LocationGIS] data transfer object to be inserted or updated. | ||
* @param onSuccess A callback function to be invoked upon successful operation. | ||
* @param onFailure A callback function to be invoked with an Exception if the operation fails. | ||
*/ | ||
override suspend fun update( | ||
locationDto: UserLocationDto, | ||
onSuccess: () -> Unit, | ||
onFailure: (Exception) -> Unit, | ||
) { | ||
Log.d(TAG, "update: sending location dto: $locationDto") | ||
try { | ||
withContext(Dispatchers.IO) { | ||
supabase.postgrest[LOCATIONS].update(locationDto) { filter { eq("uid", locationDto.uid) } } | ||
Log.d(TAG, "update: success") | ||
onSuccess() | ||
} | ||
} catch (e: Exception) { | ||
Log.e(TAG, "update: fail to update location of user ${locationDto.uid}: ${e.message}") | ||
onFailure(e) | ||
} | ||
} | ||
} |
70 changes: 70 additions & 0 deletions
70
app/src/main/java/com/android/periodpals/model/location/UserLocationViewModel.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package com.android.periodpals.model.location | ||
|
||
import android.util.Log | ||
import androidx.lifecycle.ViewModel | ||
import androidx.lifecycle.viewModelScope | ||
import kotlinx.coroutines.launch | ||
|
||
class UserLocationViewModel(private val userLocationModel: UserLocationModel) : ViewModel() { | ||
|
||
companion object { | ||
private const val TAG = "UserLocationViewModel" | ||
} | ||
|
||
/** | ||
* Create a user location, or update it if it does already exists. | ||
* | ||
* Note: This implementation does not use upsert for security reasons. | ||
* | ||
* @param uid The unique identifier of the user. | ||
* @param location The new [LocationGIS] of the user. | ||
* @param onSuccess A callback function to be invoked upon successful operation. | ||
* @param onFailure A callback function to be invoked with an `Exception` if the operation fails. | ||
*/ | ||
fun uploadUserLocation( | ||
uid: String, | ||
location: LocationGIS, | ||
onSuccess: () -> Unit = { Log.d(TAG, "uploadUserLocation success callback") }, | ||
onFailure: (Exception) -> Unit = { e: Exception -> | ||
Log.d(TAG, "uploadUserLocation failure callback: ${e.message}") | ||
}, | ||
) { | ||
val locationDto = UserLocationDto(uid = uid, location = location) | ||
viewModelScope.launch { | ||
// try to create a new location | ||
Log.d(TAG, "uploadUserLocation: trying to create location $locationDto for user $uid") | ||
userLocationModel.create( | ||
locationDto = locationDto, | ||
onSuccess = { | ||
Log.d(TAG, "uploadUserLocation: create user location successful") | ||
onSuccess() | ||
}, | ||
onFailure = { e: Exception -> | ||
Log.d(TAG, "createUserLocation: location already exists, updating instead") | ||
update(locationDto, onSuccess, onFailure) | ||
}, | ||
) | ||
} | ||
} | ||
|
||
private fun update( | ||
locationDto: UserLocationDto, | ||
onSuccess: () -> Unit, | ||
onFailure: (Exception) -> Unit, | ||
) { | ||
Log.d(TAG, "update: trying to update location $locationDto") | ||
viewModelScope.launch { | ||
userLocationModel.update( | ||
locationDto = locationDto, | ||
onSuccess = { | ||
Log.d(TAG, "update: update user location successful") | ||
onSuccess() | ||
}, | ||
onFailure = { e: Exception -> | ||
Log.d(TAG, "update: failed to upsert location of user ${locationDto.uid}: ${e.message}") | ||
onFailure(e) | ||
}, | ||
) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.