ProjectLaogai/app/src/main/java/org/mosad/seil0/projectlaogai/fragments/SettingsFragment.kt

318 lines
13 KiB
Kotlin

/**
* ProjectLaogai
*
* Copyright 2019-2020 <seil0@mosad.xyz>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
*/
package org.mosad.seil0.projectlaogai.fragments
import android.os.Bundle
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.afollestad.aesthetic.Aesthetic
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.WhichButton
import com.afollestad.materialdialogs.actions.getActionButton
import com.afollestad.materialdialogs.color.colorChooser
import com.afollestad.materialdialogs.list.listItemsMultiChoice
import com.afollestad.materialdialogs.list.listItemsSingleChoice
import de.psdev.licensesdialog.LicensesDialog
import kotlinx.coroutines.*
import org.mosad.seil0.projectlaogai.BuildConfig
import org.mosad.seil0.projectlaogai.R
import org.mosad.seil0.projectlaogai.controller.GradesController
import org.mosad.seil0.projectlaogai.controller.cache.CacheController
import org.mosad.seil0.projectlaogai.controller.cache.CacheController.Companion.coursesList
import org.mosad.seil0.projectlaogai.controller.cache.TimetableController
import org.mosad.seil0.projectlaogai.controller.preferences.EncryptedPreferences
import org.mosad.seil0.projectlaogai.controller.preferences.Preferences
import org.mosad.seil0.projectlaogai.databinding.FragmentSettingsBinding
import org.mosad.seil0.projectlaogai.uicomponents.dialogs.CourseSelectionDialog
import org.mosad.seil0.projectlaogai.uicomponents.dialogs.LoadingDialog
import org.mosad.seil0.projectlaogai.uicomponents.dialogs.LoginDialog
import org.mosad.seil0.projectlaogai.util.DataTypes
import java.util.*
/**
* The settings controller class
* contains all needed parts to display and the settings screen
*/
class SettingsFragment : Fragment() {
private lateinit var binding: FragmentSettingsBinding
private var selectedTheme = DataTypes.Theme.Light
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
binding = FragmentSettingsBinding.inflate(inflater, container, false)
return binding.root
}
/**
* initialize the settings gui
*/
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initActions()
binding.textUser.text = EncryptedPreferences.email.ifEmpty { resources.getString(R.string.sample_user) }
binding.textCourse.text = Preferences.course.courseName
binding.textAboutDesc.text = resources.getString(R.string.about_version, BuildConfig.VERSION_NAME, getString(R.string.build_time))
binding.textGradesSyncDesc.text = if (Preferences.gradesSyncInterval == 0) {
resources.getString(R.string.grades_sync_desc_never)
} else {
resources.getString(R.string.grades_sync_desc, Preferences.gradesSyncInterval)
}
binding.switchBuffet.isChecked = Preferences.showBuffet // init switch
val outValue = TypedValue()
activity!!.theme.resolveAttribute(R.attr.themeName, outValue, true)
when(outValue.string) {
"light" -> {
binding.switchBuffet.setTextColor(activity!!.resources.getColor(R.color.textPrimaryLight, activity!!.theme))
selectedTheme = DataTypes.Theme.Light
selectedTheme.string = resources.getString(R.string.themeLight)
}
"dark" -> {
binding.switchBuffet.setTextColor(activity!!.resources.getColor(R.color.textPrimaryDark, activity!!.theme))
selectedTheme = DataTypes.Theme.Dark
selectedTheme.string = resources.getString(R.string.themeDark)
}
"black" -> {
binding.switchBuffet.setTextColor(activity!!.resources.getColor(R.color.textPrimaryDark, activity!!.theme))
selectedTheme = DataTypes.Theme.Black
selectedTheme.string = resources.getString(R.string.themeBlack)
}
}
binding.textThemeSelected.text = selectedTheme.string
}
/**
* initialize some actions for SettingsFragment elements
*/
private fun initActions() {
binding.linLayoutUser.setOnClickListener {
// open a new dialog
LoginDialog(context!!)
.positiveButton {
EncryptedPreferences.saveCredentials(email, password, context)
}
.show {
email = EncryptedPreferences.email
password = ""
}
}
binding.linLayoutUser.setOnLongClickListener {
Preferences.oGiants = true // enable easter egg
return@setOnLongClickListener true
}
binding.linLayoutCourse.setOnClickListener {
CourseSelectionDialog(context!!).show {
list = coursesList.map { it.courseName }
listItems {
val loadingDialog = LoadingDialog(context)
loadingDialog.show()
GlobalScope.launch(Dispatchers.Default) {
Preferences.saveCourse(context, coursesList[selectedIndex]) // save the course
// update current & next weeks timetable
val threads = listOf(
CacheController.updateTimetable(Preferences.course.courseName, 0, context),
CacheController.updateTimetable(Preferences.course.courseName, 1, context)
)
threads.joinAll() // blocking since we want the new data
withContext(Dispatchers.Main) {
loadingDialog.dismiss()
}
}
}
onDismiss {
binding.textCourse.text = Preferences.course.courseName // update txtView after the dialog is dismissed
}
}
}
binding.linLayoutManageLessons.setOnClickListener {
val lessons = ArrayList<String>()
TimetableController.subjectMap.forEach { pair ->
pair.value.forEach {
lessons.add("${pair.key} - $it")
}
}
MaterialDialog(context!!).show {
title(R.string.manage_lessons)
positiveButton(R.string.delete)
negativeButton(R.string.cancel)
getActionButton(WhichButton.POSITIVE).updateTextColor(Preferences.colorAccent)
getActionButton(WhichButton.NEGATIVE).updateTextColor(Preferences.colorAccent)
listItemsMultiChoice(items = lessons) { _, _, items ->
items.forEach {
val list = it.split(" - ")
TimetableController.removeSubject(list[0], list[1], context)
}
}
}
}
binding.linLayoutAbout.setOnClickListener {
// open a new info dialog
MaterialDialog(context!!)
.title(R.string.about_dialog_heading)
.message(R.string.about_dialog_text)
.show()
}
binding.linLayoutLicence.setOnClickListener {
// do the theme magic, as the lib's theme support is broken
val outValue = TypedValue()
context!!.theme.resolveAttribute(R.attr.themeName, outValue, true)
val dialogCss = when (outValue.string) {
"light" -> R.string.license_dialog_style_light
else -> R.string.license_dialog_style_dark
}
val themeId = when (outValue.string) {
"light" -> R.style.AppTheme_Light
else -> R.style.LicensesDialogTheme_Dark
}
// open a new license dialog
LicensesDialog.Builder(context!!)
.setNotices(R.raw.notices)
.setTitle(R.string.licenses)
.setIncludeOwnLicense(true)
.setThemeResourceId(themeId)
.setNoticesCssStyle(dialogCss)
.build()
.show()
}
binding.linLayoutTheme.setOnClickListener {
val themes = listOf(
resources.getString(R.string.themeLight),
resources.getString(R.string.themeDark),
resources.getString(R.string.themeBlack)
)
MaterialDialog(context!!).show {
title(R.string.theme)
listItemsSingleChoice(items = themes, initialSelection = selectedTheme.ordinal) { _, index, _ ->
Aesthetic.config {
when (index) {
0 -> activityTheme(R.style.AppTheme_Light)
1 -> activityTheme(R.style.AppTheme_Dark)
2 -> activityTheme(R.style.AppTheme_Black)
else -> activityTheme(R.style.AppTheme_Light)
}
apply()
}
}
}
}
binding.linLayoutPrimaryColor.setOnClickListener {
// open a new color chooser dialog
MaterialDialog(context!!)
.colorChooser(DataTypes().primaryColors, allowCustomArgb = true, initialSelection = Preferences.colorPrimary) { _, color ->
binding.viewPrimaryColor.setBackgroundColor(color)
Aesthetic.config {
colorPrimary(color)
colorPrimaryDark(color)
apply()
}
Preferences.saveColorPrimary(context!!, color)
}
.show {
title(R.string.primary_color)
positiveButton(R.string.select)
getActionButton(WhichButton.POSITIVE).updateTextColor(Preferences.colorAccent)
}
}
binding.linLayoutAccentColor.setOnClickListener {
// open a new color chooser dialog
MaterialDialog(context!!)
.colorChooser(DataTypes().accentColors, allowCustomArgb = true, initialSelection = Preferences.colorAccent) { _, color ->
binding.viewAccentColor.setBackgroundColor(color)
Aesthetic.config {
colorAccent(color)
apply()
}
Preferences.saveColorAccent(context!!, color)
}
.show{
title(R.string.accent_color)
positiveButton(R.string.select)
getActionButton(WhichButton.POSITIVE).updateTextColor(Preferences.colorAccent)
}
}
binding.linLayoutGradesSync.setOnClickListener {
val items = resources.getStringArray(R.array.syncInterval).toList()
val initial = when (Preferences.gradesSyncInterval) {
1 -> 1
3 -> 2
6 -> 3
12 -> 4
else -> 0
}
MaterialDialog(context!!)
.title(R.string.grades_sync)
.listItemsSingleChoice(items = items, initialSelection = initial) { _, index, _ ->
val interval = when (index) {
1 -> 1
2 -> 3
3 -> 6
4 -> 12
else -> 0
}
Preferences.saveGradesSync(context!!, interval)
GradesController.updateBackgroundSync(context!!)
binding.textGradesSyncDesc.text = if (Preferences.gradesSyncInterval == 0) {
resources.getString(R.string.grades_sync_desc_never)
} else {
resources.getString(R.string.grades_sync_desc, Preferences.gradesSyncInterval)
}
}.show()
}
binding.switchBuffet.setOnClickListener {
Preferences.saveShowBuffet(context!!, binding.switchBuffet.isChecked)
}
}
}