mirror of
https://github.com/Matte23/circolapp.git
synced 2025-12-06 07:29:10 +00:00
Add database support for multiple servers (schools)
This commit is contained in:
@@ -37,6 +37,7 @@ class AlarmBroadcastReceiver : BroadcastReceiver() {
|
||||
companion object {
|
||||
const val CHANNEL_ID = "net.underdesk.circolapp.REMINDER"
|
||||
const val CIRCULAR_ID = "circular_id"
|
||||
const val SCHOOL_ID = "school_id"
|
||||
}
|
||||
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
@@ -47,6 +48,10 @@ class AlarmBroadcastReceiver : BroadcastReceiver() {
|
||||
intent.getLongExtra(
|
||||
CIRCULAR_ID,
|
||||
0
|
||||
),
|
||||
intent.getIntExtra(
|
||||
SCHOOL_ID,
|
||||
0
|
||||
)
|
||||
)
|
||||
createNotification(
|
||||
|
||||
@@ -24,7 +24,7 @@ import androidx.room.Room
|
||||
import androidx.room.RoomDatabase
|
||||
import androidx.room.TypeConverters
|
||||
|
||||
@Database(entities = [Circular::class], version = 1, exportSchema = false)
|
||||
@Database(entities = [Circular::class], version = 2, exportSchema = false)
|
||||
@TypeConverters(Converters::class)
|
||||
abstract class AppDatabase : RoomDatabase() {
|
||||
abstract fun circularDao(): CircularDao
|
||||
@@ -42,7 +42,7 @@ abstract class AppDatabase : RoomDatabase() {
|
||||
context,
|
||||
AppDatabase::class.java,
|
||||
DATABASE_NAME
|
||||
).build().also { instance = it }
|
||||
).fallbackToDestructiveMigration().build().also { instance = it }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,13 +20,13 @@ package net.underdesk.circolapp.data
|
||||
|
||||
import android.os.Parcelable
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
|
||||
@Parcelize
|
||||
@Entity(tableName = "circulars")
|
||||
@Entity(tableName = "circulars", primaryKeys = ["id", "school"])
|
||||
data class Circular(
|
||||
@PrimaryKey val id: Long,
|
||||
val id: Long,
|
||||
val school: Int,
|
||||
val name: String,
|
||||
val url: String,
|
||||
val date: String,
|
||||
|
||||
@@ -23,29 +23,29 @@ import androidx.room.*
|
||||
|
||||
@Dao
|
||||
interface CircularDao {
|
||||
@Query("SELECT * FROM circulars ORDER BY id DESC")
|
||||
fun getCirculars(): List<Circular>
|
||||
@Query("SELECT * FROM circulars WHERE school is :school ORDER BY id DESC")
|
||||
fun getCirculars(school: Int): List<Circular>
|
||||
|
||||
@Query("SELECT * FROM circulars ORDER BY id DESC")
|
||||
fun getLiveCirculars(): LiveData<List<Circular>>
|
||||
@Query("SELECT * FROM circulars WHERE school is :school ORDER BY id DESC")
|
||||
fun getLiveCirculars(school: Int): LiveData<List<Circular>>
|
||||
|
||||
@Query("SELECT * FROM circulars WHERE name LIKE :query ORDER BY id DESC")
|
||||
fun searchCirculars(query: String): LiveData<List<Circular>>
|
||||
@Query("SELECT * FROM circulars WHERE school is :school AND name LIKE :query ORDER BY id DESC")
|
||||
fun searchCirculars(query: String, school: Int): LiveData<List<Circular>>
|
||||
|
||||
@Query("SELECT * FROM circulars WHERE id = :id ORDER BY id DESC")
|
||||
fun getCircular(id: Long): Circular
|
||||
@Query("SELECT * FROM circulars WHERE school is :school AND id = :id ORDER BY id DESC")
|
||||
fun getCircular(id: Long, school: Int): Circular
|
||||
|
||||
@Query("SELECT * FROM circulars WHERE favourite ORDER BY id DESC")
|
||||
fun getFavourites(): LiveData<List<Circular>>
|
||||
@Query("SELECT * FROM circulars WHERE school is :school AND favourite ORDER BY id DESC")
|
||||
fun getFavourites(school: Int): LiveData<List<Circular>>
|
||||
|
||||
@Query("SELECT * FROM circulars WHERE favourite AND name LIKE :query ORDER BY id DESC")
|
||||
fun searchFavourites(query: String): LiveData<List<Circular>>
|
||||
@Query("SELECT * FROM circulars WHERE school is :school AND favourite AND name LIKE :query ORDER BY id DESC")
|
||||
fun searchFavourites(query: String, school: Int): LiveData<List<Circular>>
|
||||
|
||||
@Query("SELECT * FROM circulars WHERE reminder ORDER BY id DESC")
|
||||
fun getReminders(): LiveData<List<Circular>>
|
||||
@Query("SELECT * FROM circulars WHERE school is :school AND reminder ORDER BY id DESC")
|
||||
fun getReminders(school: Int): LiveData<List<Circular>>
|
||||
|
||||
@Query("SELECT * FROM circulars WHERE reminder AND name LIKE :query ORDER BY id DESC")
|
||||
fun searchReminders(query: String): LiveData<List<Circular>>
|
||||
@Query("SELECT * FROM circulars WHERE school is :school AND reminder AND name LIKE :query ORDER BY id DESC")
|
||||
fun searchReminders(query: String, school: Int): LiveData<List<Circular>>
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.IGNORE)
|
||||
fun insertAll(circulars: List<Circular>)
|
||||
|
||||
@@ -16,7 +16,7 @@ class CircularRepository(
|
||||
if (result.second == ServerAPI.Companion.Result.ERROR)
|
||||
return@withContext Pair(emptyList(), false)
|
||||
|
||||
val oldCirculars = circularDao.getCirculars()
|
||||
val oldCirculars = circularDao.getCirculars(serverAPI.serverID())
|
||||
val newCirculars = result.first
|
||||
|
||||
if (newCirculars.size != oldCirculars.size) {
|
||||
|
||||
@@ -48,7 +48,8 @@ class CircularLetterFragment :
|
||||
CircularRepository.getInstance(
|
||||
AppDatabase.getInstance(requireContext()).circularDao(),
|
||||
ServerAPI.getInstance(requireContext())
|
||||
)
|
||||
),
|
||||
requireActivity().application
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,8 @@ class FavouritesFragment : Fragment(), MainActivity.SearchCallback {
|
||||
CircularRepository.getInstance(
|
||||
AppDatabase.getInstance(requireContext()).circularDao(),
|
||||
ServerAPI.getInstance(requireContext())
|
||||
)
|
||||
),
|
||||
requireActivity().application
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -112,7 +112,8 @@ class NewReminderFragment : DialogFragment() {
|
||||
context,
|
||||
circular.id.toInt(),
|
||||
Intent(context, AlarmBroadcastReceiver::class.java)
|
||||
.putExtra(AlarmBroadcastReceiver.CIRCULAR_ID, circular.id),
|
||||
.putExtra(AlarmBroadcastReceiver.CIRCULAR_ID, circular.id)
|
||||
.putExtra(AlarmBroadcastReceiver.SCHOOL_ID, circular.school),
|
||||
0
|
||||
)
|
||||
|
||||
|
||||
@@ -42,7 +42,8 @@ class RemindersFragment : Fragment(), MainActivity.SearchCallback {
|
||||
CircularRepository.getInstance(
|
||||
AppDatabase.getInstance(requireContext()).circularDao(),
|
||||
ServerAPI.getInstance(requireContext())
|
||||
)
|
||||
),
|
||||
requireActivity().application
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ package net.underdesk.circolapp.server
|
||||
import net.underdesk.circolapp.data.Circular
|
||||
|
||||
abstract class Server {
|
||||
abstract val serverID: Int
|
||||
abstract suspend fun getCircularsFromServer(): Pair<List<Circular>, ServerAPI.Companion.Result>
|
||||
abstract suspend fun newCircularsAvailable(): Pair<Boolean, ServerAPI.Companion.Result>
|
||||
}
|
||||
|
||||
@@ -27,6 +27,8 @@ import net.underdesk.circolapp.server.porporato.PorporatoServer
|
||||
class ServerAPI(
|
||||
private var server: Server
|
||||
) {
|
||||
fun serverID(): Int = server.serverID
|
||||
|
||||
suspend fun getCircularsFromServer(): Pair<List<Circular>, Result> {
|
||||
val newCircularsAvailable = server.newCircularsAvailable()
|
||||
|
||||
@@ -52,6 +54,10 @@ class ServerAPI(
|
||||
SUCCESS, ERROR
|
||||
}
|
||||
|
||||
fun getServerId(server: Servers): Int {
|
||||
return Servers.values().indexOf(server)
|
||||
}
|
||||
|
||||
fun getServerName(server: Servers) = when (server) {
|
||||
Servers.CURIE -> "Liceo scientifico Maria Curie"
|
||||
Servers.PORPORATO -> "Liceo G.F. Porporato"
|
||||
|
||||
@@ -18,6 +18,8 @@ class CurieServer : Server() {
|
||||
private val responseAdapter = moshi.adapter(Response::class.java)
|
||||
private val client = OkHttpClient()
|
||||
|
||||
override val serverID = ServerAPI.getServerId(ServerAPI.Companion.Servers.CURIE)
|
||||
|
||||
override suspend fun getCircularsFromServer(): Pair<List<Circular>, ServerAPI.Companion.Result> {
|
||||
return try {
|
||||
withContext(Dispatchers.Default) {
|
||||
@@ -85,9 +87,9 @@ class CurieServer : Server() {
|
||||
.removePrefix("_")
|
||||
.removePrefix(" ")
|
||||
|
||||
Circular(id.toLong(), title, url, matcherDate.group(1) ?: "")
|
||||
Circular(id.toLong(), serverID, title, url, matcherDate.group(1) ?: "")
|
||||
} else {
|
||||
Circular(id.toLong(), title, url, "")
|
||||
Circular(id.toLong(), serverID, title, url, "")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,8 @@ class PorporatoServer : Server() {
|
||||
"https://www.liceoporporato.edu.it/ARCHIVIO/PR/VP/circolari.php?dirname=CIRCOLARIP/- CIRCOLARI 2020-21/-12-Agosto/"
|
||||
)
|
||||
|
||||
override val serverID = ServerAPI.getServerId(ServerAPI.Companion.Servers.PORPORATO)
|
||||
|
||||
override suspend fun getCircularsFromServer(): Pair<List<Circular>, ServerAPI.Companion.Result> {
|
||||
return try {
|
||||
val list = arrayListOf<Circular>()
|
||||
@@ -150,9 +152,9 @@ class PorporatoServer : Server() {
|
||||
title = title.removeRange(matcherDate.start(), matcherDate.end())
|
||||
.removeSuffix(" (pubb.: )")
|
||||
|
||||
Circular(id, title, fullUrl, matcherDate.group(1)?.replace("-", "/") ?: "")
|
||||
Circular(id, serverID, title, fullUrl, matcherDate.group(1)?.replace("-", "/") ?: "")
|
||||
} else {
|
||||
Circular(id, title, fullUrl, "")
|
||||
Circular(id, serverID, title, fullUrl, "")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package net.underdesk.circolapp.utils
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MediatorLiveData
|
||||
|
||||
// Taken from https://stackoverflow.com/questions/49493772/mediatorlivedata-or-switchmap-transformation-with-multiple-parameters
|
||||
class DoubleTrigger<A, B>(a: LiveData<A>, b: LiveData<B>) : MediatorLiveData<Pair<A?, B?>>() {
|
||||
init {
|
||||
addSource(a) { value = it to b.value }
|
||||
addSource(b) { value = a.value to it }
|
||||
}
|
||||
}
|
||||
@@ -18,24 +18,40 @@
|
||||
|
||||
package net.underdesk.circolapp.viewmodels
|
||||
|
||||
import android.app.Application
|
||||
import android.content.SharedPreferences
|
||||
import androidx.lifecycle.*
|
||||
import androidx.preference.PreferenceManager
|
||||
import kotlinx.coroutines.launch
|
||||
import net.underdesk.circolapp.data.Circular
|
||||
import net.underdesk.circolapp.data.CircularRepository
|
||||
import net.underdesk.circolapp.utils.DoubleTrigger
|
||||
|
||||
class CircularLetterViewModel internal constructor(
|
||||
private val circularRepository: CircularRepository
|
||||
) : ViewModel() {
|
||||
private val circularRepository: CircularRepository,
|
||||
application: Application
|
||||
) : AndroidViewModel(application), SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
private val preferenceManager = PreferenceManager.getDefaultSharedPreferences(application)
|
||||
|
||||
private val schoolID =
|
||||
MutableLiveData(preferenceManager.getString("school", "0")?.toInt() ?: 0)
|
||||
|
||||
init {
|
||||
updateCirculars()
|
||||
|
||||
preferenceManager.registerOnSharedPreferenceChangeListener(this)
|
||||
}
|
||||
|
||||
val query = MutableLiveData("")
|
||||
val circulars: LiveData<List<Circular>> = Transformations.switchMap(query) { input ->
|
||||
if (input == null || input == "") {
|
||||
circularRepository.circularDao.getLiveCirculars()
|
||||
val circulars: LiveData<List<Circular>> =
|
||||
Transformations.switchMap(DoubleTrigger(query, schoolID)) { input ->
|
||||
if (input.first == null || input.first == "") {
|
||||
circularRepository.circularDao.getLiveCirculars(input.second ?: 0)
|
||||
} else {
|
||||
circularRepository.circularDao.searchCirculars("%$input%")
|
||||
circularRepository.circularDao.searchCirculars(
|
||||
"%${input.first}%",
|
||||
input.second ?: 0
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,4 +73,9 @@ class CircularLetterViewModel internal constructor(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
|
||||
if (key == "school")
|
||||
schoolID.postValue(preferenceManager.getString("school", "0")?.toInt() ?: 0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
package net.underdesk.circolapp.viewmodels
|
||||
|
||||
import android.app.Application
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import net.underdesk.circolapp.data.CircularRepository
|
||||
|
||||
class CircularLetterViewModelFactory(
|
||||
private val circularRepository: CircularRepository
|
||||
) : ViewModelProvider.Factory {
|
||||
private val circularRepository: CircularRepository,
|
||||
val application: Application
|
||||
) : ViewModelProvider.AndroidViewModelFactory(application) {
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
return CircularLetterViewModel(circularRepository) as T
|
||||
return CircularLetterViewModel(circularRepository, application) as T
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,22 +18,45 @@
|
||||
|
||||
package net.underdesk.circolapp.viewmodels
|
||||
|
||||
import android.app.Application
|
||||
import android.content.SharedPreferences
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.Transformations
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.preference.PreferenceManager
|
||||
import net.underdesk.circolapp.data.Circular
|
||||
import net.underdesk.circolapp.data.CircularRepository
|
||||
import net.underdesk.circolapp.utils.DoubleTrigger
|
||||
|
||||
class FavouritesViewModel internal constructor(
|
||||
private val circularRepository: CircularRepository
|
||||
) : ViewModel() {
|
||||
val query = MutableLiveData("")
|
||||
val circulars: LiveData<List<Circular>> = Transformations.switchMap(query) { input ->
|
||||
if (input == null || input == "") {
|
||||
circularRepository.circularDao.getFavourites()
|
||||
} else {
|
||||
circularRepository.circularDao.searchFavourites("%$input%")
|
||||
private val circularRepository: CircularRepository,
|
||||
application: Application
|
||||
) : AndroidViewModel(application), SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
private val preferenceManager = PreferenceManager.getDefaultSharedPreferences(application)
|
||||
|
||||
private val schoolID =
|
||||
MutableLiveData(preferenceManager.getString("school", "0")?.toInt() ?: 0)
|
||||
|
||||
init {
|
||||
preferenceManager.registerOnSharedPreferenceChangeListener(this)
|
||||
}
|
||||
|
||||
val query = MutableLiveData("")
|
||||
val circulars: LiveData<List<Circular>> =
|
||||
Transformations.switchMap(DoubleTrigger(query, schoolID)) { input ->
|
||||
if (input.first == null || input.first == "") {
|
||||
circularRepository.circularDao.getFavourites(input.second ?: 0)
|
||||
} else {
|
||||
circularRepository.circularDao.searchFavourites(
|
||||
"%${input.first}%",
|
||||
input.second ?: 0
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
|
||||
if (key == "school")
|
||||
schoolID.postValue(preferenceManager.getString("school", "0")?.toInt() ?: 0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
package net.underdesk.circolapp.viewmodels
|
||||
|
||||
import android.app.Application
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import net.underdesk.circolapp.data.CircularRepository
|
||||
|
||||
class FavouritesViewModelFactory(
|
||||
private val circularRepository: CircularRepository
|
||||
) : ViewModelProvider.Factory {
|
||||
private val circularRepository: CircularRepository,
|
||||
val application: Application
|
||||
) : ViewModelProvider.AndroidViewModelFactory(application) {
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
return FavouritesViewModel(circularRepository) as T
|
||||
return FavouritesViewModel(circularRepository, application) as T
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,22 +18,45 @@
|
||||
|
||||
package net.underdesk.circolapp.viewmodels
|
||||
|
||||
import android.app.Application
|
||||
import android.content.SharedPreferences
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.Transformations
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.preference.PreferenceManager
|
||||
import net.underdesk.circolapp.data.Circular
|
||||
import net.underdesk.circolapp.data.CircularRepository
|
||||
import net.underdesk.circolapp.utils.DoubleTrigger
|
||||
|
||||
class RemindersViewModel internal constructor(
|
||||
private val circularRepository: CircularRepository
|
||||
) : ViewModel() {
|
||||
val query = MutableLiveData("")
|
||||
val circulars: LiveData<List<Circular>> = Transformations.switchMap(query) { input ->
|
||||
if (input == null || input == "") {
|
||||
circularRepository.circularDao.getReminders()
|
||||
} else {
|
||||
circularRepository.circularDao.searchReminders("%$input%")
|
||||
private val circularRepository: CircularRepository,
|
||||
application: Application
|
||||
) : AndroidViewModel(application), SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
private val preferenceManager = PreferenceManager.getDefaultSharedPreferences(application)
|
||||
|
||||
private val schoolID =
|
||||
MutableLiveData(preferenceManager.getString("school", "0")?.toInt() ?: 0)
|
||||
|
||||
init {
|
||||
preferenceManager.registerOnSharedPreferenceChangeListener(this)
|
||||
}
|
||||
|
||||
val query = MutableLiveData("")
|
||||
val circulars: LiveData<List<Circular>> =
|
||||
Transformations.switchMap(DoubleTrigger(query, schoolID)) { input ->
|
||||
if (input.first == null || input.first == "") {
|
||||
circularRepository.circularDao.getReminders(input.second ?: 0)
|
||||
} else {
|
||||
circularRepository.circularDao.searchReminders(
|
||||
"%${input.first}%",
|
||||
input.second ?: 0
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
|
||||
if (key == "school")
|
||||
schoolID.postValue(preferenceManager.getString("school", "0")?.toInt() ?: 0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
package net.underdesk.circolapp.viewmodels
|
||||
|
||||
import android.app.Application
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import net.underdesk.circolapp.data.CircularRepository
|
||||
|
||||
class RemindersViewModelFactory(
|
||||
private val circularRepository: CircularRepository
|
||||
) : ViewModelProvider.Factory {
|
||||
private val circularRepository: CircularRepository,
|
||||
val application: Application
|
||||
) : ViewModelProvider.AndroidViewModelFactory(application) {
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
return RemindersViewModel(circularRepository) as T
|
||||
return RemindersViewModel(circularRepository, application) as T
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user