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

320 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 com.afollestad.aesthetic.Aesthetic
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 androidx.lifecycle.lifecycleScope
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.WhichButton
import com.afollestad.materialdialogs.actions.getActionButton
import com.afollestad.materialdialogs.list.listItemsMultiChoice
import com.afollestad.materialdialogs.list.listItemsSingleChoice
import de.psdev.licensesdialog.LicensesDialog
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.joinAll
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
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
/**
* 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()
requireActivity().theme.resolveAttribute(R.attr.themeName, outValue, true)
when(outValue.string) {
"light" -> {
binding.switchBuffet.setTextColor(requireActivity().resources.getColor(R.color.textPrimaryLight, requireActivity().theme))
selectedTheme = DataTypes.Theme.Light
selectedTheme.string = resources.getString(R.string.themeLight)
}
"dark" -> {
binding.switchBuffet.setTextColor(requireActivity().resources.getColor(R.color.textPrimaryDark, requireActivity().theme))
selectedTheme = DataTypes.Theme.Dark
selectedTheme.string = resources.getString(R.string.themeDark)
}
"black" -> {
binding.switchBuffet.setTextColor(requireActivity().resources.getColor(R.color.textPrimaryDark, requireActivity().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(requireContext())
.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(requireContext()).show {
list = coursesList.map { it.courseName }
listItems {
val loadingDialog = LoadingDialog(context)
loadingDialog.show()
lifecycleScope.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(requireContext()).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(requireContext())
.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()
requireContext().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(requireContext())
.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(requireContext()).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(requireContext())
// .colorChooser(DataTypes().primaryColors, allowCustomArgb = true, initialSelection = Preferences.colorPrimary) { _, color ->
// binding.viewPrimaryColor.setBackgroundColor(color)
// Aesthetic.config {
// colorPrimary(color)
// colorPrimaryDark(color)
// apply()
// }
// Preferences.saveColorPrimary(requireContext(), 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(requireContext())
// .colorChooser(DataTypes().accentColors, allowCustomArgb = true, initialSelection = Preferences.colorAccent) { _, color ->
// binding.viewAccentColor.setBackgroundColor(color)
// Aesthetic.config {
// colorAccent(color)
// apply()
// }
//
// Preferences.saveColorAccent(requireContext(), 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(requireContext())
.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(requireContext(), interval)
GradesController.updateBackgroundSync(requireContext())
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(requireContext(), binding.switchBuffet.isChecked)
}
}
}