app/src/main/java/com/github/ybecker/epforuml/util/MainActivity.kt
package com.github.ybecker.epforuml.util
import android.content.Context
import android.content.SharedPreferences
import android.net.ConnectivityManager
import android.os.Bundle
import android.view.MenuItem
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.app.AppCompatActivity
import androidx.drawerlayout.widget.DrawerLayout
import androidx.fragment.app.Fragment
import com.github.ybecker.epforuml.HomeFragment
import com.github.ybecker.epforuml.R
import com.github.ybecker.epforuml.features.cache.SavedQuestionsFragment
import com.github.ybecker.epforuml.basicEntities.account.AccountFragment
import com.github.ybecker.epforuml.basicEntities.account.AccountFragmentGuest
import com.github.ybecker.epforuml.features.chat.ChatHomeFragment
import com.github.ybecker.epforuml.features.chat.RealChatFragment
import com.github.ybecker.epforuml.database.DatabaseManager
import com.github.ybecker.epforuml.database.DatabaseManager.db
import com.github.ybecker.epforuml.database.Model
import com.github.ybecker.epforuml.basicEntities.questions.MyQuestionsFragment
import com.github.ybecker.epforuml.basicEntities.questions.NewQuestionFragment
import com.github.ybecker.epforuml.features.maps.MapsFragment
import com.github.ybecker.epforuml.structure.CoursesFragment
import com.github.ybecker.epforuml.structure.SettingsFragment
import com.google.android.material.navigation.NavigationView
import com.google.firebase.FirebaseApp
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
open class MainActivity : AppCompatActivity() {
companion object {
lateinit var context: Context
private var connectivityManager : ConnectivityManager? = null
private var isConnectionEnabled = true
fun isConnected() : Boolean {
if (connectivityManager == null || !isConnectionEnabled) { return false }
return (connectivityManager?.getNetworkCapabilities(connectivityManager?.activeNetwork) != null)
}
fun enableConnection() {
isConnectionEnabled = true
}
fun disableConnection() {
isConnectionEnabled = false
}
/**
* Saved question cache and answer cache to device
*/
fun saveAllUsersToDevice(usersCache: ArrayList<Model.User>) {
val sharedUsers: SharedPreferences =
context.getSharedPreferences("USERS", MODE_PRIVATE)
val usersEditor = sharedUsers.edit()
var uGson = Gson()
var uJson = uGson.toJson(usersCache)
usersEditor.putString("users", uJson)
usersEditor.apply()
}
/**
* Saved question cache and answer cache to device
*/
fun saveDataToDevice(questionCache: ArrayList<Model.Question>, answerCache: ArrayList<Model.Answer>,
allQuestionCache: ArrayList<Model.Question>, allAnswerCache: ArrayList<Model.Answer>,
allCoursesCache: ArrayList<Model.Course>) {
val sharedQuestions : SharedPreferences = context.getSharedPreferences("QUESTIONS", MODE_PRIVATE)
val sharedAnswers : SharedPreferences = context.getSharedPreferences("ANSWERS", MODE_PRIVATE)
var questionsEditor = sharedQuestions.edit()
var answersEditor = sharedAnswers.edit()
var qGson = Gson()
var aGson = Gson()
var qJson = qGson.toJson(questionCache)
var aJson = aGson.toJson(answerCache)
questionsEditor.putString("questions", qJson)
answersEditor.putString("answers", aJson)
questionsEditor.apply()
answersEditor.apply()
// TODO : check
val allQuestions : SharedPreferences = context.getSharedPreferences("ALL_QUESTIONS", MODE_PRIVATE)
val allAnswers : SharedPreferences = context.getSharedPreferences("ALL_ANSWERS", MODE_PRIVATE)
val allCourses : SharedPreferences = context.getSharedPreferences("ALL_COURSES", MODE_PRIVATE)
questionsEditor = allQuestions.edit()
answersEditor = allAnswers.edit()
val coursesEditor = allCourses.edit()
qGson = Gson()
aGson = Gson()
val cGson = Gson()
qJson = qGson.toJson(allQuestionCache)
aJson = aGson.toJson(allAnswerCache)
val cJson = cGson.toJson(allCoursesCache)
questionsEditor.putString("all_questions", qJson)
answersEditor.putString("all_answers", aJson)
coursesEditor.putString("all_courses", cJson)
questionsEditor.apply()
answersEditor.apply()
coursesEditor.apply()
}
}
lateinit var toggle : ActionBarDrawerToggle
lateinit var drawerLayout: DrawerLayout
private var cache = ArrayList<Model.Question>()
private var allQuestionsCache = ArrayList<Model.Question>()
/**
* List of all existing answers
*/
private var answersCache = ArrayList<Model.Answer>()
private var allAnswersCache = ArrayList<Model.Answer>()
private var allCoursesCache = ArrayList<Model.Course>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
FirebaseApp.initializeApp(this)
context = applicationContext
if (isConnected()) {
db.getAllUsers().thenAccept {
saveAllUsersToDevice(it as ArrayList<Model.User>)
}
}
// get app connectivity
connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
updateAnswersCacheIfConnected()
// initialize DB to Mock
//DatabaseManager.useMockDatabase()
drawerLayout = findViewById(R.id.drawer_layout)
val navView : NavigationView = findViewById(R.id.nav_view)
toggle = ActionBarDrawerToggle(this, drawerLayout, R.string.open, R.string.close)
drawerLayout.addDrawerListener(toggle)
toggle.syncState()
supportActionBar?.setDisplayHomeAsUpEnabled(true)
// load all data from device
loadDataFromDevice()
// get retrieve name of fragment to display if any
val fragment : String? = intent.extras?.getString("fragment")
if(savedInstanceState == null) {
replaceFragment(HomeFragment())
}
when(fragment) {
"HomeFragment" -> replaceFragment(HomeFragment())
"NewQuestionFragment" -> replaceFragment(NewQuestionFragment())
"SavedQuestionsFragment" -> replaceFragment(SavedQuestionsFragment())
"RealChat" -> replaceFragment(RealChatFragment())
"chatHome" -> replaceFragment(ChatHomeFragment())
"MyQuestionsFragment" -> replaceFragment(MyQuestionsFragment())
else -> {}
}
// Remove it otherwise we might jump back to this fragment later
intent.removeExtra("fragment")
navView.setNavigationItemSelectedListener {
when(it.itemId) {
R.id.nav_home -> replaceFragmentAndClose(HomeFragment())
R.id.nav_courses -> replaceFragmentAndClose(CoursesFragment())
R.id.nav_my_questions -> replaceFragmentAndClose(MyQuestionsFragment())
R.id.nav_saved_questions -> replaceFragmentAndClose(SavedQuestionsFragment())
R.id.nav_account ->
if (DatabaseManager.user == null) {
replaceFragmentAndClose(AccountFragmentGuest())
} else {
replaceFragmentAndClose(AccountFragment())
}
R.id.nav_settings -> replaceFragmentAndClose(SettingsFragment())
R.id.nav_chat -> replaceFragmentAndClose(ChatHomeFragment())
R.id.nav_map -> replaceFragment(MapsFragment())
}
true
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (toggle.onOptionsItemSelected(item)) {
return true
}
return super.onOptionsItemSelected(item)
}
fun replaceFragment(fragment: Fragment) {
val bundle = Bundle()
// send cache to any of the fragments we are going to
bundle.putParcelableArrayList("savedQuestions", cache)
bundle.putParcelableArrayList("savedAnswers", answersCache)
// TODO : check
bundle.putParcelableArrayList("allQuestions", allQuestionsCache)
bundle.putParcelableArrayList("allAnswers", allAnswersCache)
bundle.putParcelableArrayList("allCourses", allCoursesCache)
fragment.arguments = bundle
supportFragmentManager.beginTransaction().replace(R.id.frame_layout, fragment).commit()
drawerLayout.closeDrawers()
}
private fun replaceFragmentAndClose(fragment: Fragment) {
replaceFragment(fragment)
drawerLayout.closeDrawers()
}
private fun updateAnswersCacheIfConnected() {
if (isConnected()) {
answersCache.clear()
for (question in cache) {
db.getQuestionAnswers(question.questionId).thenAccept { answerList ->
answersCache.addAll(answerList)
}
}
}
}
/**
* Helper function for function below
*/
inline fun <reified T> Gson.fromJson(json: String) = fromJson<T>(json, object: TypeToken<T>() {}.type)
private fun loadDataFromDevice() {
val sharedQuestions : SharedPreferences = context.getSharedPreferences("QUESTIONS", MODE_PRIVATE)
val sharedAnswers : SharedPreferences = context.getSharedPreferences("ANSWERS", MODE_PRIVATE)
val qGson = Gson()
val aGson = Gson()
var qJson = sharedQuestions.getString("questions", null)
var aJson = sharedAnswers.getString("answers", null)
if (qJson != null) {
val cacheTmp = qGson.fromJson<ArrayList<Model.Question>>(qJson)
if (cacheTmp != null) {
cache = cacheTmp
}
}
if (aJson != null) {
val answerCacheTmp = aGson.fromJson<ArrayList<Model.Answer>>(aJson)
if (answerCacheTmp != null) {
answersCache = answerCacheTmp
}
}
// TODO : check
val allQuestions : SharedPreferences = context.getSharedPreferences("ALL_QUESTIONS", MODE_PRIVATE)
val allAnswers : SharedPreferences = context.getSharedPreferences("ALL_ANSWERS", MODE_PRIVATE)
val allCourses : SharedPreferences = context.getSharedPreferences("ALL_COURSES", MODE_PRIVATE)
val cGson = Gson()
qJson = allQuestions.getString("all_questions", null)
aJson = allAnswers.getString("all_answers", null)
val cJson = allCourses.getString("all_courses", null)
if (qJson != null) {
val allQuestionsTmp = qGson.fromJson<ArrayList<Model.Question>>(qJson)
if (allQuestionsTmp != null) {
allQuestionsCache = allQuestionsTmp
}
}
if (aJson != null) {
val allAnswersTmp = aGson.fromJson<ArrayList<Model.Answer>>(aJson)
if (allAnswersTmp != null) {
allAnswersCache = allAnswersTmp
}
}
if (cJson != null) {
val allCoursesTmp = cGson.fromJson<ArrayList<Model.Course>>(cJson)
if (allCoursesTmp != null) {
allCoursesCache = allCoursesTmp
}
}
// is it necessary ?
//saveDataToDevice(cache, answersCache, allQuestionsCache, allAnswersCache, allCourses)
}
}