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

279 lines
11 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.content.Context
import android.os.Bundle
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.Switch
import android.widget.TextView
import androidx.fragment.app.Fragment
import com.afollestad.aesthetic.Aesthetic
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.callbacks.onDismiss
import com.afollestad.materialdialogs.color.colorChooser
import com.afollestad.materialdialogs.customview.customView
import com.afollestad.materialdialogs.list.listItems
import com.afollestad.materialdialogs.list.listItemsSingleChoice
import de.psdev.licensesdialog.LicensesDialog
import kotlinx.android.synthetic.main.fragment_settings.*
import kotlinx.coroutines.*
import org.mosad.seil0.projectlaogai.BuildConfig
import org.mosad.seil0.projectlaogai.R
import org.mosad.seil0.projectlaogai.controller.CacheController
import org.mosad.seil0.projectlaogai.controller.CacheController.Companion.coursesList
import org.mosad.seil0.projectlaogai.controller.PreferencesController
import org.mosad.seil0.projectlaogai.controller.PreferencesController.Companion.cColorAccent
import org.mosad.seil0.projectlaogai.controller.PreferencesController.Companion.cColorPrimary
import org.mosad.seil0.projectlaogai.controller.PreferencesController.Companion.cCourse
import org.mosad.seil0.projectlaogai.controller.PreferencesController.Companion.cShowBuffet
import org.mosad.seil0.projectlaogai.controller.TCoRAPIController
import org.mosad.seil0.projectlaogai.hsoparser.DataTypes
import java.util.*
/**
* The settings controller class
* contains all needed parts to display and the settings screen
*/
class SettingsFragment : Fragment() {
private lateinit var linLayoutUser: LinearLayout
private lateinit var linLayoutCourse: LinearLayout
private lateinit var linLayoutAbout: LinearLayout
private lateinit var linLayoutLicence: LinearLayout
private lateinit var linLayoutTheme: LinearLayout
private lateinit var linLayoutPrimaryColor: LinearLayout
private lateinit var linLayoutAccentColor: LinearLayout
private lateinit var switchBuffet: Switch
private lateinit var txtViewCourse: TextView
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view: View = inflater.inflate(R.layout.fragment_settings, container, false)
linLayoutUser = view.findViewById(R.id.linLayout_User)
linLayoutCourse = view.findViewById(R.id.linLayout_Course)
linLayoutAbout = view.findViewById(R.id.linLayout_About)
linLayoutLicence = view.findViewById(R.id.linLayout_Licence)
linLayoutTheme = view.findViewById(R.id.linLayout_Theme)
linLayoutPrimaryColor = view.findViewById(R.id.linLayout_PrimaryColor)
linLayoutAccentColor = view.findViewById(R.id.linLayout_AccentColor)
switchBuffet = view.findViewById(R.id.switch_buffet)
// if we call txtView_Course via KAE view binding it'll result in a NPE in the onDismissed call
txtViewCourse = view.findViewById(R.id.txtView_Course)
initActions()
// Inflate the layout for this fragment
return view
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// initialize the settings gui
txtView_Course.text = cCourse.courseName
txtView_AboutDesc.text = resources.getString(R.string.about_version, BuildConfig.VERSION_NAME, getString(R.string.build_time))
switch_buffet.isChecked = cShowBuffet // init switch
val outValue = TypedValue()
activity!!.theme.resolveAttribute(R.attr.themeName, outValue, true)
when(outValue.string) {
"light" -> {
switch_buffet.setTextColor(activity!!.resources.getColor(R.color.textPrimaryLight, activity!!.theme))
txtView_SelectedTheme.text = resources.getString(R.string.themeLight)
}
"dark" -> {
switch_buffet.setTextColor(activity!!.resources.getColor(R.color.textPrimaryDark, activity!!.theme))
txtView_SelectedTheme.text = resources.getString(R.string.themeDark)
}
"black" -> {
switch_buffet.setTextColor(activity!!.resources.getColor(R.color.textPrimaryDark, activity!!.theme))
txtView_SelectedTheme.text = resources.getString(R.string.themeBlack)
}
}
}
/**
* initialize some actions for SettingsFragment elements
*/
private fun initActions() {
linLayoutUser.setOnClickListener {
// open a new dialog
}
linLayoutUser.setOnLongClickListener {
PreferencesController.oGiants = true // enable easter egg
return@setOnLongClickListener true
}
linLayoutCourse.setOnClickListener {
selectCourse(context!!).show {
onDismiss {
txtViewCourse.text = cCourse.courseName // update txtView after the dialog is dismissed
}
}
}
linLayoutAbout.setOnClickListener {
// open a new info dialog
MaterialDialog(context!!)
.title(R.string.about_dialog_heading)
.message(R.string.about_dialog_text)
.show()
}
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()
}
linLayoutTheme.setOnClickListener {
val themes = listOf(
resources.getString(R.string.themeLight),
resources.getString(R.string.themeDark),
resources.getString(R.string.themeBlack)
)
MaterialDialog(context!!)
.title(R.string.theme)
.show {
listItemsSingleChoice(items = themes) { _, 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()
}
}
}
}
linLayoutPrimaryColor.setOnClickListener {
// open a new color chooser dialog
MaterialDialog(context!!)
.title(R.string.primary_color)
.colorChooser(DataTypes().primaryColors, allowCustomArgb = true, initialSelection = cColorPrimary) { _, color ->
view_PrimaryColor.setBackgroundColor(color)
Aesthetic.config {
colorPrimary(color)
colorPrimaryDark(color)
apply()
}
PreferencesController.saveColorPrimary(context!!, color)
}
.positiveButton(R.string.select)
.show()
}
linLayoutAccentColor.setOnClickListener {
// open a new color chooser dialog
MaterialDialog(context!!)
.title(R.string.accent_color)
.colorChooser(DataTypes().accentColors, allowCustomArgb = true, initialSelection = cColorAccent) { _, color ->
view_AccentColor.setBackgroundColor(color)
Aesthetic.config {
colorAccent(color)
apply()
}
PreferencesController.saveColorAccent(context!!, color)
}
.positiveButton(R.string.select)
.show()
}
switchBuffet.setOnClickListener {
PreferencesController.saveShowBuffet(context!!, switchBuffet.isChecked)
}
}
fun selectCourse(context: Context) : MaterialDialog {
val courseNameList = ArrayList<String>()
coursesList.forEach { (_, courseName) ->
courseNameList.add(courseName)
}
// return a new course selection dialog
return MaterialDialog(context)
.title(R.string.select_course)
.listItems(items = courseNameList) { _, index, _ ->
val loadingDialog = MaterialDialog(context).cancelable(false)
.cancelOnTouchOutside(false)
.customView(R.layout.dialog_loading)
loadingDialog.show()
GlobalScope.launch(Dispatchers.Default) {
PreferencesController.saveCourse(context, coursesList[index]) // save the course
// update current & next weeks timetable
val threads = listOf(
TCoRAPIController.getTimetable(cCourse.courseName, 0, context),
TCoRAPIController.getTimetable(cCourse.courseName, 1, context)
)
threads.joinAll() // blocking since we want the new data
CacheController.readTimetable(cCourse.courseName, 0, context)
CacheController.readTimetable(cCourse.courseName, 1, context)
withContext(Dispatchers.Main) {
loadingDialog.dismiss()
}
}
}
}
}