/** * ProjectLaogai * * Copyright 2019-2020 * * 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() 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() } } } } }