Archived
Login page now disallows visiting a domain other than the school's login page to prevent a successful login from another domain allowing access to the app's content
This commit is contained in:
@@ -11,29 +11,33 @@ import com.denizd.substitutionplan.models.Colour
|
||||
import com.denizd.substitutionplan.R
|
||||
import com.google.android.material.card.MaterialCardView
|
||||
|
||||
internal class ColourAdapter(private var mColours: List<Colour>, onClickListener: OnClickListener) : RecyclerView.Adapter<ColourAdapter.ColourViewHolder>() {
|
||||
/**
|
||||
* Adapter class used for displaying the courses as well as their associated colours in the
|
||||
* customisation dialog. Used in SettingsFragment.kt
|
||||
*
|
||||
* @param colours a list of all courses and their associated colour
|
||||
* @param onClickListener a reference to an OnClickListener
|
||||
*/
|
||||
internal class ColourAdapter(private var colours: List<Colour>, private val onClickListener: OnClickListener) : RecyclerView.Adapter<ColourAdapter.ColourViewHolder>() {
|
||||
|
||||
private val mOnClickListener = onClickListener
|
||||
|
||||
class ColourViewHolder(view: View, clickListener: OnClickListener) : RecyclerView.ViewHolder(view), View.OnClickListener {
|
||||
internal class ColourViewHolder(view: View, private val clickListener: OnClickListener) : RecyclerView.ViewHolder(view), View.OnClickListener {
|
||||
val title: TextView = view.findViewById(R.id.item_text)
|
||||
var image: ImageView = view.findViewById(R.id.item_image)
|
||||
val titleNoLang: TextView = view.findViewById(R.id.item_text_no_lang)
|
||||
val cardView: MaterialCardView = view.findViewById(R.id.cardView)
|
||||
private val mClickListener = clickListener
|
||||
init { view.setOnClickListener(this) }
|
||||
|
||||
override fun onClick(v: View?) { mClickListener.onClick(adapterPosition, title.text.toString(), titleNoLang.text.toString()) }
|
||||
override fun onClick(v: View?) { clickListener.onClick(adapterPosition, title.text.toString(), titleNoLang.text.toString()) }
|
||||
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ColourViewHolder {
|
||||
val v = LayoutInflater.from(parent.context).inflate(R.layout.list_item, parent, false)
|
||||
return ColourViewHolder(v, mOnClickListener)
|
||||
return ColourViewHolder(v, onClickListener)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ColourViewHolder, position: Int) {
|
||||
val currentItem = mColours[position]
|
||||
val currentItem = colours[position]
|
||||
|
||||
holder.title.text = currentItem.title
|
||||
holder.titleNoLang.text = currentItem.titleNoLang
|
||||
@@ -54,7 +58,7 @@ internal class ColourAdapter(private var mColours: List<Colour>, onClickListener
|
||||
holder.title.setTextColor(ContextCompat.getColor(holder.title.context, textColor))
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = mColours.size
|
||||
override fun getItemCount(): Int = colours.size
|
||||
|
||||
internal interface OnClickListener {
|
||||
fun onClick(position: Int, title: String, titleNoLang: String)
|
||||
|
||||
@@ -5,39 +5,38 @@ import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
|
||||
import java.util.ArrayList
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.denizd.substitutionplan.models.Food
|
||||
import com.denizd.substitutionplan.R
|
||||
|
||||
internal class FoodAdapter(food: ArrayList<Food>) : RecyclerView.Adapter<FoodAdapter.CardViewHolder>() {
|
||||
private var mFood: List<Food>? = null
|
||||
/**
|
||||
* Adapter class used in FoodFragment.kt to display the food menu to the user
|
||||
*
|
||||
* @param foods a list of all food entries on the menu
|
||||
*/
|
||||
internal class FoodAdapter(private var foods: List<Food>) : RecyclerView.Adapter<FoodAdapter.FoodViewHolder>() {
|
||||
|
||||
class CardViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
var mFood: TextView = itemView.findViewById(R.id.cardInfoText)
|
||||
internal class FoodViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
var text: TextView = itemView.findViewById(R.id.cardInfoText)
|
||||
}
|
||||
|
||||
init {
|
||||
mFood = food
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CardViewHolder {
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FoodViewHolder {
|
||||
val v = LayoutInflater.from(parent.context).inflate(R.layout.just_a_card, parent, false)
|
||||
return CardViewHolder(v)
|
||||
return FoodViewHolder(v)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: CardViewHolder, position: Int) {
|
||||
val currentItem = mFood!![position]
|
||||
override fun onBindViewHolder(holder: FoodViewHolder, position: Int) {
|
||||
val currentItem = foods[position]
|
||||
|
||||
holder.mFood.text = currentItem.food
|
||||
holder.text.text = currentItem.food
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return mFood!!.size
|
||||
return foods.size
|
||||
}
|
||||
|
||||
fun setFood(food: List<Food>) {
|
||||
mFood = food
|
||||
fun setFood(foods: List<Food>) {
|
||||
this.foods = foods
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,40 +10,39 @@ import com.denizd.substitutionplan.R
|
||||
import com.denizd.substitutionplan.models.Ringtone
|
||||
import com.google.android.material.card.MaterialCardView
|
||||
|
||||
internal class RingtoneAdapter(private var _ringtones: List<Ringtone>, onClickListener: OnClickListener) : RecyclerView.Adapter<RingtoneAdapter.RingtoneViewHolder>() {
|
||||
/**
|
||||
* Adapter class used for displaying all available notification ringtones to the user up to
|
||||
* Android version 7 (Nougat). Used in SettingsFragment.kt
|
||||
*
|
||||
* @param ringtones a list of all ringtones including their URI
|
||||
* @param onClickListener a reference to an OnClickListener to set the ringtone
|
||||
*/
|
||||
internal class RingtoneAdapter(private val ringtones: List<Ringtone>, private val onClickListener: OnClickListener) : RecyclerView.Adapter<RingtoneAdapter.RingtoneViewHolder>() {
|
||||
|
||||
private val _onClickListener = onClickListener
|
||||
|
||||
class RingtoneViewHolder(view: View, clickListener: OnClickListener) : RecyclerView.ViewHolder(view), View.OnClickListener {
|
||||
internal class RingtoneViewHolder(view: View, private val clickListener: OnClickListener) : RecyclerView.ViewHolder(view), View.OnClickListener {
|
||||
val name: TextView = view.findViewById(R.id.item_text)
|
||||
val uri: TextView = view.findViewById(R.id.item_text_no_lang)
|
||||
val cardView: MaterialCardView = view.findViewById(R.id.cardView)
|
||||
private val _clickListener = clickListener
|
||||
init { view.setOnClickListener(this) }
|
||||
|
||||
override fun onClick(v: View?) { _clickListener.onRingtoneClick(adapterPosition, name.text.toString(), uri.text.toString()) }
|
||||
override fun onClick(v: View?) { clickListener.onRingtoneClick(adapterPosition, name.text.toString(), uri.text.toString()) }
|
||||
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RingtoneViewHolder {
|
||||
val v = LayoutInflater.from(parent.context).inflate(R.layout.list_item, parent, false)
|
||||
return RingtoneViewHolder(
|
||||
v,
|
||||
_onClickListener
|
||||
)
|
||||
return RingtoneViewHolder(v, onClickListener)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: RingtoneViewHolder, position: Int) {
|
||||
val currentItem = _ringtones[position]
|
||||
val currentItem = ringtones[position]
|
||||
|
||||
holder.name.text = currentItem.name
|
||||
holder.uri.text = currentItem.uri
|
||||
holder.cardView.setCardBackgroundColor(ContextCompat.getColor(holder.cardView.context,
|
||||
R.color.colorBackground
|
||||
))
|
||||
holder.cardView.setCardBackgroundColor(ContextCompat.getColor(holder.cardView.context, R.color.colorBackground))
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = _ringtones.size
|
||||
override fun getItemCount(): Int = ringtones.size
|
||||
|
||||
internal interface OnClickListener {
|
||||
fun onRingtoneClick(position: Int, name: String, uri: String)
|
||||
|
||||
+24
-65
@@ -1,6 +1,7 @@
|
||||
package com.denizd.substitutionplan.adapters
|
||||
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import android.net.Uri
|
||||
import android.text.SpannableString
|
||||
@@ -16,18 +17,20 @@ import androidx.core.content.ContextCompat
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.denizd.substitutionplan.data.HelperFunctions
|
||||
import com.denizd.substitutionplan.R
|
||||
import com.denizd.substitutionplan.models.Subst
|
||||
import com.denizd.substitutionplan.models.Substitution
|
||||
import com.google.android.material.card.MaterialCardView
|
||||
import java.util.*
|
||||
|
||||
internal class CardAdapter(private var mSubst: List<Subst>, private val prefs: SharedPreferences) : RecyclerView.Adapter<CardAdapter.CardViewHolder>() {
|
||||
/**
|
||||
* Adapter class for the Recycler View used to display the substitution plan in
|
||||
* PlanFragment.kt and its subclasses
|
||||
*
|
||||
* @param substitutions a list of all substitutions of data type Substitution
|
||||
* @param prefs a reference to the app's Shared Preferences used to get user-set colours
|
||||
*/
|
||||
internal class SubstitutionAdapter(private var substitutions: List<Substitution>, private val prefs: SharedPreferences) : RecyclerView.Adapter<SubstitutionAdapter.CardViewHolder>() {
|
||||
|
||||
private var colour = 0
|
||||
private var colourString = ""
|
||||
private var colorCheck = ""
|
||||
private val cancellations = arrayOf("eigenverantwortliches arbeiten", "entfall", "entfällt", "fällt aus", "freisetzung", "vtr. ohne lehrer")
|
||||
|
||||
class CardViewHolder(view: View) : RecyclerView.ViewHolder(view), View.OnClickListener {
|
||||
internal class CardViewHolder(view: View) : RecyclerView.ViewHolder(view), View.OnClickListener {
|
||||
|
||||
var iconView: ImageView = view.findViewById(R.id.iconView)
|
||||
var group: TextView = view.findViewById(R.id.group)
|
||||
@@ -38,16 +41,16 @@ internal class CardAdapter(private var mSubst: List<Subst>, private val prefs: S
|
||||
var additional: TextView = view.findViewById(R.id.additional)
|
||||
var teacher: TextView = view.findViewById(R.id.teacher)
|
||||
var spacer: TextView = view.findViewById(R.id.spacer)
|
||||
|
||||
var card: MaterialCardView = view.findViewById(R.id.planCard)
|
||||
val context: Context = card.context
|
||||
init { view.setOnClickListener(this) }
|
||||
override fun onClick(v: View?) {
|
||||
if (date.text.toString().length > 7 && date.text.toString().substring(3, 7) == "http") {
|
||||
try {
|
||||
CustomTabsIntent.Builder().build().launchUrl(card.context,
|
||||
Uri.parse(date.text.toString().substring(3)))
|
||||
CustomTabsIntent.Builder().build().launchUrl(context,
|
||||
Uri.parse(date.text.substring(3)))
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
Toast.makeText(card.context, card.context.getString(R.string.chrome_not_found), Toast.LENGTH_LONG).show()
|
||||
Toast.makeText(context, context.getString(R.string.chrome_not_found), Toast.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -59,12 +62,13 @@ internal class CardAdapter(private var mSubst: List<Subst>, private val prefs: S
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: CardViewHolder, position: Int) {
|
||||
val currentItem = mSubst[position]
|
||||
val currentItem = substitutions[position]
|
||||
var psa = false
|
||||
val strings = arrayOf(SpannableString(currentItem.group), SpannableString(currentItem.time),
|
||||
SpannableString(currentItem.course), SpannableString(currentItem.room),
|
||||
SpannableString(currentItem.teacher))
|
||||
var cardBackgroundColour = 0
|
||||
val cardBackgroundColour: Int
|
||||
var colour = 0
|
||||
|
||||
for (string in strings) {
|
||||
val questionMarkIndex = string.indexOf("?")
|
||||
@@ -76,11 +80,11 @@ internal class CardAdapter(private var mSubst: List<Subst>, private val prefs: S
|
||||
val add = currentItem.additional.toLowerCase(Locale.ROOT)
|
||||
val type = currentItem.type.toLowerCase(Locale.ROOT)
|
||||
if (add.isNotEmpty()) {
|
||||
if (HelperFunctions.checkStringForArray(add, cancellations)) {
|
||||
if (HelperFunctions.checkStringForArray(add, HelperFunctions.cancellations)) {
|
||||
strikeThrough(strings)
|
||||
}
|
||||
} else {
|
||||
if (HelperFunctions.checkStringForArray(type, cancellations)) {
|
||||
if (HelperFunctions.checkStringForArray(type, HelperFunctions.cancellations)) {
|
||||
strikeThrough(strings)
|
||||
}
|
||||
}
|
||||
@@ -100,7 +104,7 @@ internal class CardAdapter(private var mSubst: List<Subst>, private val prefs: S
|
||||
cardBackgroundColour = R.color.colorAccent
|
||||
View.GONE
|
||||
} else {
|
||||
colourString = getColourString(holder.course.text.toString())
|
||||
val colourString = HelperFunctions.getColourString(holder.course.text.toString())
|
||||
val colourPrefsInt = if (colourString.isNotEmpty()) {
|
||||
prefs.getString("card$colourString", "") ?: ""
|
||||
} else {
|
||||
@@ -150,58 +154,13 @@ internal class CardAdapter(private var mSubst: List<Subst>, private val prefs: S
|
||||
holder.teacher.setTextColor(textColor)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = mSubst.size
|
||||
override fun getItemCount(): Int = substitutions.size
|
||||
|
||||
fun setSubst(subst: List<Subst>) {
|
||||
mSubst = subst
|
||||
fun setSubst(substitutions: List<Substitution>) {
|
||||
this.substitutions = substitutions
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
private fun getColourString(course: String): String {
|
||||
return try {
|
||||
colorCheck = course.toLowerCase(Locale.ROOT).substring(0, 3)
|
||||
when (colorCheck) {
|
||||
"deu", "dep", "daz", "fda" -> "German"
|
||||
"mat", "map" -> "Maths"
|
||||
"eng", "enp", "ena" -> "English"
|
||||
"spo", "spp", "spth" -> "PhysEd"
|
||||
"pol", "pop" -> "Politics"
|
||||
"dar", "dap" -> "Theatre"
|
||||
"phy", "php" -> "Physics"
|
||||
"bio", "bip", "nw1", "nw2", "nw3", "nw4" -> "Biology"
|
||||
"che", "chp" -> "Chemistry"
|
||||
"phi", "psp" -> "Philosophy"
|
||||
"laa", "laf", "lat" -> "Latin"
|
||||
"spa", "spf" -> "Spanish"
|
||||
"fra", "frf", "frz" -> "French"
|
||||
"inf" -> "CompSci"
|
||||
"ges" -> "History"
|
||||
"rel" -> "Religion"
|
||||
"geg" -> "Geography"
|
||||
"kun" -> "Arts"
|
||||
"mus" -> "Music"
|
||||
"tue" -> "Turkish"
|
||||
"chi" -> "Chinese"
|
||||
"gll" -> "GLL"
|
||||
"wat" -> "WAT"
|
||||
"för" -> "Forder"
|
||||
"met", "wpb" -> "WP"
|
||||
else -> ""
|
||||
}
|
||||
} catch (e: StringIndexOutOfBoundsException) {
|
||||
try {
|
||||
colorCheck = course.toLowerCase(Locale.ROOT).substring(0, 2)
|
||||
when (colorCheck) {
|
||||
"nw" -> "Biology"
|
||||
"wp" -> "WP"
|
||||
else -> ""
|
||||
}
|
||||
} catch (e2: StringIndexOutOfBoundsException) {
|
||||
""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun strikeThrough(strings: Array<SpannableString>) {
|
||||
for (i in 2..4) { strings[i].setSpan(StrikethroughSpan(), 0, strings[i].length, 0) }
|
||||
}
|
||||
@@ -18,7 +18,7 @@ import com.denizd.substitutionplan.R
|
||||
import com.denizd.substitutionplan.database.SubstRepository
|
||||
import com.denizd.substitutionplan.activities.Main
|
||||
import com.denizd.substitutionplan.models.Food
|
||||
import com.denizd.substitutionplan.models.Subst
|
||||
import com.denizd.substitutionplan.models.Substitution
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import org.jsoup.Jsoup
|
||||
import java.lang.ref.WeakReference
|
||||
@@ -57,7 +57,7 @@ internal class DataFetcher(isPlan: Boolean, isMenu: Boolean, isJobService: Boole
|
||||
private val edit = prefs.edit()
|
||||
private var currentTime = ""
|
||||
private var currentFoodTime = ""
|
||||
private var substUrl = "https://djd4rkn355.github.io/subst.html"
|
||||
private var substUrl = "https://djd4rkn355.github.io/avh_substitutions.html"
|
||||
private var foodUrl = "https://djd4rkn355.github.io/food.html"
|
||||
|
||||
override fun doInBackground(vararg params: Void?): Void? {
|
||||
@@ -149,7 +149,7 @@ internal class DataFetcher(isPlan: Boolean, isMenu: Boolean, isJobService: Boole
|
||||
if (currentTime != prefs.getString("timeNew", "")) {
|
||||
val rows = doc.select("tr")
|
||||
val paragraphs = doc.select("p")
|
||||
val substArray = ArrayList<Subst>()
|
||||
val substArray = ArrayList<Substitution>()
|
||||
|
||||
val coursePreference = prefs.getString("courses", "") ?: ""
|
||||
val classPreference = prefs.getString("classes", "") ?: ""
|
||||
@@ -169,7 +169,7 @@ internal class DataFetcher(isPlan: Boolean, isMenu: Boolean, isJobService: Boole
|
||||
val row = rows[i]
|
||||
val cols = row.select("th")
|
||||
|
||||
val subst = Subst(
|
||||
val subst = Substitution(
|
||||
group = cols[0].text(),
|
||||
date = cols[1].text(),
|
||||
time = cols[2].text(),
|
||||
@@ -237,11 +237,12 @@ internal class DataFetcher(isPlan: Boolean, isMenu: Boolean, isJobService: Boole
|
||||
val notification = NotificationCompat.Builder(context, HelperFunctions.notificationChannelId)
|
||||
.setStyle(NotificationCompat.DecoratedCustomViewStyle())
|
||||
.setCustomContentView(notificationLayout)
|
||||
.setSmallIcon(R.drawable.ic_avhlogo)
|
||||
.setContentIntent(openAppPending)
|
||||
.setAutoCancel(true)
|
||||
.setColor(ContextCompat.getColor(context, R.color.colorAccent))
|
||||
|
||||
notification.setSmallIcon(if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) R.drawable.ic_avh else R.drawable.ic_avhlogo)
|
||||
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
||||
val sound = if ((prefs.getString("ringtoneUri", "") ?: "").isNotEmpty()) {
|
||||
Uri.parse(prefs.getString("ringtoneUri", "") ?: "")
|
||||
|
||||
@@ -20,7 +20,7 @@ import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.ContextCompat.checkSelfPermission
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import com.denizd.substitutionplan.R
|
||||
import com.denizd.substitutionplan.models.Subst
|
||||
import com.denizd.substitutionplan.models.Substitution
|
||||
import java.util.*
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
@@ -45,6 +45,12 @@ internal object HelperFunctions {
|
||||
"brown", "grey", "pureWhite", "salmon", "tangerine", "banana", "flora", "spindrift", "sky", "orchid",
|
||||
"lavender", "carnation", "brown2", "pureBlack")
|
||||
|
||||
/**
|
||||
* A list of all phrases used to describe that a course has been cancelled. Expand this
|
||||
* if necessary. No further code changes required if this is expanded
|
||||
*/
|
||||
val cancellations = arrayOf("eigenverantwortliches arbeiten", "entfall", "entfällt", "fällt aus", "freisetzung", "vtr. ohne lehrer")
|
||||
|
||||
private val colourIntegers = intArrayOf(
|
||||
0,
|
||||
R.color.bgRed,
|
||||
@@ -135,6 +141,60 @@ internal object HelperFunctions {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns a string that is used to get the colour set for a specific course
|
||||
* from Shared Preferences
|
||||
*
|
||||
* @param course the course abbreviation as a string
|
||||
*
|
||||
* @return the string used to store the course's colour in Shared Preferences
|
||||
*/
|
||||
fun getColourString(course: String): String {
|
||||
var colorCheck: String
|
||||
return try {
|
||||
colorCheck = course.toLowerCase(Locale.ROOT).substring(0, 3)
|
||||
when (colorCheck) {
|
||||
"deu", "dep", "daz", "fda" -> "German"
|
||||
"mat", "map" -> "Maths"
|
||||
"eng", "enp", "ena" -> "English"
|
||||
"spo", "spp", "spth" -> "PhysEd"
|
||||
"pol", "pop" -> "Politics"
|
||||
"dar", "dap" -> "Theatre"
|
||||
"phy", "php" -> "Physics"
|
||||
"bio", "bip", "nw1", "nw2", "nw3", "nw4" -> "Biology"
|
||||
"che", "chp" -> "Chemistry"
|
||||
"phi", "psp" -> "Philosophy"
|
||||
"laa", "laf", "lat" -> "Latin"
|
||||
"spa", "spf" -> "Spanish"
|
||||
"fra", "frf", "frz" -> "French"
|
||||
"inf" -> "CompSci"
|
||||
"ges" -> "History"
|
||||
"rel" -> "Religion"
|
||||
"geg" -> "Geography"
|
||||
"kun" -> "Arts"
|
||||
"mus" -> "Music"
|
||||
"tue" -> "Turkish"
|
||||
"chi" -> "Chinese"
|
||||
"gll" -> "GLL"
|
||||
"wat" -> "WAT"
|
||||
"för" -> "Forder"
|
||||
"met", "wpb" -> "WP"
|
||||
else -> ""
|
||||
}
|
||||
} catch (e: StringIndexOutOfBoundsException) {
|
||||
try {
|
||||
colorCheck = course.toLowerCase(Locale.ROOT).substring(0, 2)
|
||||
when (colorCheck) {
|
||||
"nw" -> "Biology"
|
||||
"wp" -> "WP"
|
||||
else -> ""
|
||||
}
|
||||
} catch (e2: StringIndexOutOfBoundsException) {
|
||||
""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function served as a way to transfer a deprecated method of storing user-defined
|
||||
* course colours to a new method. It is not required otherwise, but still remains in
|
||||
@@ -163,17 +223,17 @@ internal object HelperFunctions {
|
||||
* This function serves for checking whether a course on the substitution plan is relevant to
|
||||
* the user and should be shown on their personal plan as well as in their notifications
|
||||
*
|
||||
* @param subst the substitution item
|
||||
* @param substitution the substitution item
|
||||
* @param coursePreference a string that represents the courses the user is enrolled in
|
||||
* @param classPreference a string that represents the group the user is in
|
||||
* @param psa decide whether or not any PSA items should be included in the filter
|
||||
*
|
||||
* @return true if the substitution is relevant to the user, false otherwise
|
||||
*/
|
||||
fun checkPersonalSubstitutions(subst: Subst, coursePreference: String, classPreference: String, psa: Boolean): Boolean {
|
||||
val group = subst.group
|
||||
val course = subst.course
|
||||
if (psa && subst.date.isNotEmpty() && subst.date.substring(0, 3) == "psa") {
|
||||
fun checkPersonalSubstitutions(substitution: Substitution, coursePreference: String, classPreference: String, psa: Boolean): Boolean {
|
||||
val group = substitution.group
|
||||
val course = substitution.course
|
||||
if (psa && substitution.date.isNotEmpty() && substitution.date.substring(0, 3) == "psa") {
|
||||
return true
|
||||
}
|
||||
if (coursePreference.isEmpty() && classPreference.isNotEmpty()) {
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
package com.denizd.substitutionplan.data
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.util.Log
|
||||
import android.webkit.CookieManager
|
||||
import android.webkit.WebView
|
||||
import android.webkit.WebViewClient
|
||||
import java.lang.IllegalStateException
|
||||
|
||||
/**
|
||||
* Class that extends WebViewClient to provide a function that checks the webpage's cookies to
|
||||
@@ -10,27 +13,40 @@ import android.webkit.WebViewClient
|
||||
*
|
||||
* @param successListener a reference to the OnLoginSuccessListener implemented in an activity
|
||||
*/
|
||||
internal class LoginWebViewClient(successListener: OnLoginSuccessListener) : WebViewClient() {
|
||||
internal class LoginWebViewClient(private val successListener: OnLoginSuccessListener) : WebViewClient() {
|
||||
|
||||
private val mSuccessListener = successListener
|
||||
/**
|
||||
* onPageStarted has been overridden to prevent users from reaching a domain different from
|
||||
* the school's login page
|
||||
*/
|
||||
override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
|
||||
super.onPageStarted(view, url, favicon)
|
||||
|
||||
if (url != "https://307.joomla.schule.bremen.de/index.php/component/users/profile?Itemid=171"
|
||||
&& url != "https://307.joomla.schule.bremen.de/index.php/component/users/#top") {
|
||||
reloadLoginPage(webView = view)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* OnPageFinished has been overridden to check if the cookie "joomla_user_state=logged_in"
|
||||
* exists, and returns true to the OnLoginSuccessListener
|
||||
*
|
||||
* @param view a reference to the WebView
|
||||
* @param url a reference to the url of the WebView
|
||||
*/
|
||||
override fun onPageFinished(view: WebView?, url: String?) {
|
||||
super.onPageFinished(view, url)
|
||||
view?.scrollY = -4000
|
||||
view?.scrollY = -10_000
|
||||
|
||||
val cookies = CookieManager.getInstance().getCookie(url)
|
||||
|
||||
if (cookies.contains("joomla_user_state=logged_in")) {
|
||||
mSuccessListener.onLoginSucceeded(true)
|
||||
successListener.onLoginSucceeded(true)
|
||||
}
|
||||
}
|
||||
|
||||
private fun reloadLoginPage(webView: WebView?) {
|
||||
webView?.loadUrl("https://307.joomla.schule.bremen.de/index.php/component/users/#top")
|
||||
}
|
||||
|
||||
/**
|
||||
* The interface that provides onLoginSucceeded to the activity or fragment that implements it
|
||||
*/
|
||||
|
||||
@@ -3,23 +3,23 @@ package com.denizd.substitutionplan.database
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.room.*
|
||||
import com.denizd.substitutionplan.models.Food
|
||||
import com.denizd.substitutionplan.models.Subst
|
||||
import com.denizd.substitutionplan.models.Substitution
|
||||
|
||||
@Dao
|
||||
internal interface SubstDao {
|
||||
|
||||
// @get:Query("SELECT * FROM subst_table ORDER BY date ASC, `group` ASC, time ASC, priority DESC")
|
||||
@get:Query("SELECT * FROM subst_table ORDER BY priority DESC")
|
||||
val allSubst: LiveData<List<Subst>>
|
||||
val allSubstitutions: LiveData<List<Substitution>>
|
||||
|
||||
@Insert
|
||||
fun insertSubst(subst: Subst)
|
||||
fun insertSubst(substitution: Substitution)
|
||||
|
||||
@Update
|
||||
fun updateSubst(subst: Subst)
|
||||
fun updateSubst(substitution: Substitution)
|
||||
|
||||
@Delete
|
||||
fun deleteSubst(subst: Subst)
|
||||
fun deleteSubst(substitution: Substitution)
|
||||
|
||||
@Query("DELETE FROM subst_table")
|
||||
fun deleteAllSubst()
|
||||
|
||||
@@ -7,9 +7,9 @@ import androidx.room.RoomDatabase
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
import com.denizd.substitutionplan.models.Food
|
||||
import com.denizd.substitutionplan.models.Subst
|
||||
import com.denizd.substitutionplan.models.Substitution
|
||||
|
||||
@Database(entities = [Subst::class, Food::class], version = 7, exportSchema = false)
|
||||
@Database(entities = [Substitution::class, Food::class], version = 7, exportSchema = false)
|
||||
internal abstract class SubstDatabase : RoomDatabase() {
|
||||
|
||||
abstract fun substDao(): SubstDao
|
||||
|
||||
@@ -4,32 +4,32 @@ import android.app.Application
|
||||
import android.os.AsyncTask
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import com.denizd.substitutionplan.models.Subst
|
||||
import com.denizd.substitutionplan.models.Substitution
|
||||
|
||||
internal class SubstRepository(application: Application) {
|
||||
|
||||
private val substDao: SubstDao?
|
||||
val allSubst: LiveData<List<Subst>>?
|
||||
val allSubstitutions: LiveData<List<Substitution>>?
|
||||
|
||||
init {
|
||||
val database =
|
||||
SubstDatabase.getInstance(application)
|
||||
substDao = database?.substDao()
|
||||
allSubst = substDao?.allSubst
|
||||
allSubstitutions = substDao?.allSubstitutions
|
||||
}
|
||||
|
||||
fun insert(subst: Subst) {
|
||||
InsertSubstAsync(substDao).execute(subst)
|
||||
fun insert(substitution: Substitution) {
|
||||
InsertSubstAsync(substDao).execute(substitution)
|
||||
}
|
||||
|
||||
fun deleteAllSubst() {
|
||||
DeleteAllSubstAsync(substDao).execute()
|
||||
}
|
||||
|
||||
class InsertSubstAsync(substDao: SubstDao?) : AsyncTask<Subst, Void, Void>() {
|
||||
class InsertSubstAsync(substDao: SubstDao?) : AsyncTask<Substitution, Void, Void>() {
|
||||
private val mSubstDao = substDao
|
||||
override fun doInBackground(vararg substs: Subst): Void? {
|
||||
mSubstDao?.insertSubst(substs[0])
|
||||
override fun doInBackground(vararg substitutions: Substitution): Void? {
|
||||
mSubstDao?.insertSubst(substitutions[0])
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,16 +6,16 @@ import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
import com.denizd.substitutionplan.data.DataFetcher
|
||||
import com.denizd.substitutionplan.models.Subst
|
||||
import com.denizd.substitutionplan.models.Substitution
|
||||
|
||||
internal class SubstViewModel(application: Application) : AndroidViewModel(application) {
|
||||
|
||||
private val repository: SubstRepository = SubstRepository(application)
|
||||
val allSubst: LiveData<List<Subst>>?
|
||||
val allSubstitutions: LiveData<List<Substitution>>?
|
||||
private val app = application
|
||||
|
||||
init {
|
||||
allSubst = repository.allSubst
|
||||
allSubstitutions = repository.allSubstitutions
|
||||
}
|
||||
|
||||
fun refresh(swipeRefreshLayout: SwipeRefreshLayout, rootView: View, refreshMenu: Boolean) {
|
||||
|
||||
@@ -35,17 +35,10 @@ internal class FoodFragment : Fragment(R.layout.food_layout) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
val pullToRefresh = view.findViewById<SwipeRefreshLayout>(R.id.pullToRefresh)
|
||||
|
||||
try {
|
||||
recyclerView = view.findViewById(R.id.linear_food)
|
||||
recyclerView.hasFixedSize()
|
||||
recyclerView.layoutManager = GridLayoutManager(mContext, 1)
|
||||
recyclerView.adapter = mAdapter
|
||||
|
||||
try {
|
||||
recyclerView.removeAllViews()
|
||||
} catch (ignored: NullPointerException) {}
|
||||
|
||||
} catch (ignored: NullPointerException) {}
|
||||
recyclerView = view.findViewById(R.id.linear_food)
|
||||
recyclerView.hasFixedSize()
|
||||
recyclerView.layoutManager = GridLayoutManager(mContext, 1)
|
||||
recyclerView.adapter = mAdapter
|
||||
|
||||
foodViewModel = ViewModelProviders.of(this).get(FoodViewModel::class.java)
|
||||
foodViewModel.allFoods?.observe(this, Observer<List<Food>> { foodList ->
|
||||
|
||||
@@ -3,14 +3,14 @@ package com.denizd.substitutionplan.fragments
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.lifecycle.Observer
|
||||
import com.denizd.substitutionplan.models.Subst
|
||||
import com.denizd.substitutionplan.models.Substitution
|
||||
|
||||
internal class GeneralPlanFragment : PlanFragment() {
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
substViewModel.allSubst?.observe(this, Observer<List<Subst>> { substitutions ->
|
||||
substViewModel.allSubstitutions?.observe(this, Observer<List<Substitution>> { substitutions ->
|
||||
mAdapter.setSubst(substitutions)
|
||||
recyclerView.scheduleLayoutAnimation()
|
||||
})
|
||||
|
||||
@@ -5,7 +5,7 @@ import android.view.View
|
||||
import androidx.lifecycle.Observer
|
||||
import com.denizd.substitutionplan.data.HelperFunctions
|
||||
import com.denizd.substitutionplan.R
|
||||
import com.denizd.substitutionplan.models.Subst
|
||||
import com.denizd.substitutionplan.models.Substitution
|
||||
|
||||
internal class PersonalPlanFragment : PlanFragment() {
|
||||
|
||||
@@ -19,7 +19,7 @@ internal class PersonalPlanFragment : PlanFragment() {
|
||||
val coursePreference = prefs.getString("courses", "") ?: ""
|
||||
val classPreference = prefs.getString("classes", "") ?: ""
|
||||
|
||||
substViewModel.allSubst?.observe(this, Observer<List<Subst>> { substitutions ->
|
||||
substViewModel.allSubstitutions?.observe(this, Observer<List<Substitution>> { substitutions ->
|
||||
planCardList.clear()
|
||||
personalPlanEmptyEmoticon.visibility = View.GONE
|
||||
personalPlanEmptyText.visibility = View.GONE
|
||||
|
||||
@@ -15,15 +15,15 @@ import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
import com.denizd.substitutionplan.*
|
||||
import com.denizd.substitutionplan.adapters.CardAdapter
|
||||
import com.denizd.substitutionplan.adapters.SubstitutionAdapter
|
||||
import com.denizd.substitutionplan.database.SubstViewModel
|
||||
import com.denizd.substitutionplan.models.Subst
|
||||
import com.denizd.substitutionplan.models.Substitution
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
internal open class PlanFragment : Fragment(R.layout.plan) {
|
||||
lateinit var recyclerView: RecyclerView
|
||||
lateinit var mAdapter: CardAdapter
|
||||
var planCardList = ArrayList<Subst>()
|
||||
lateinit var mAdapter: SubstitutionAdapter
|
||||
var planCardList = ArrayList<Substitution>()
|
||||
lateinit var substViewModel: SubstViewModel
|
||||
private lateinit var mContext: Context
|
||||
lateinit var prefs: SharedPreferences
|
||||
@@ -53,7 +53,7 @@ internal open class PlanFragment : Fragment(R.layout.plan) {
|
||||
recyclerView = view.findViewById(R.id.linearRecycler)
|
||||
recyclerView.hasFixedSize()
|
||||
recyclerView.layoutManager = GridLayoutManager(mContext, getGridColumnCount(resources.configuration))
|
||||
mAdapter = CardAdapter(planCardList, prefs)
|
||||
mAdapter = SubstitutionAdapter(planCardList, prefs)
|
||||
recyclerView.adapter = mAdapter
|
||||
|
||||
if (prefs.getInt("firstTimeOpening", 0) == 1) {
|
||||
|
||||
@@ -188,69 +188,6 @@ internal class SettingsFragment : Fragment(R.layout.content_settings), View.OnCl
|
||||
}
|
||||
}
|
||||
|
||||
override fun onClick(v: View?) {
|
||||
when (v?.id) {
|
||||
R.id.chipHelpCourses -> createDialog(getString(R.string.courses_help_dialog_title), getString(R.string.courses_help_dialog_text))
|
||||
R.id.chipHelpClasses -> createDialog(getString(R.string.grade_help_dialog_title), getString(
|
||||
R.string.grade_help_dialog_text
|
||||
))
|
||||
R.id.btnCustomiseColours -> createColourDialog()
|
||||
R.id.btnNoNotif -> createDialog(mContext.getString(R.string.no_notifications_title), mContext.getString(R.string.no_notifications_dialog_text))
|
||||
R.id.btnCustomiseRingtone -> createRingtoneDialog()
|
||||
R.id.btnWebsite -> {
|
||||
try {
|
||||
customTabsIntent.launchUrl(mContext, Uri.parse("http://307.joomla.schule.bremen.de"))
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
makeToast(getString(R.string.chrome_not_found))
|
||||
}
|
||||
}
|
||||
R.id.btnLicences -> {
|
||||
createDialog(mContext.getString(R.string.licences_title), licences)
|
||||
}
|
||||
R.id.btnTerms -> {
|
||||
createDialog("Terms & Conditions", termsAndConditions)
|
||||
}
|
||||
R.id.btnPrivacyP -> {
|
||||
createDialog("Privacy Policy", privacyPolicy)
|
||||
}
|
||||
R.id.btnForceRefresh -> {
|
||||
DataFetcher(
|
||||
isPlan = true,
|
||||
isMenu = true,
|
||||
isJobService = false,
|
||||
context = mContext,
|
||||
application = activity!!.application,
|
||||
parentView = view!!.rootView,
|
||||
forced = true
|
||||
).execute()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCheckedChanged(v: CompoundButton?, isChecked: Boolean) {
|
||||
if (v?.isPressed == true) {
|
||||
when (v.id) {
|
||||
R.id.switchDisableGreeting -> {
|
||||
prefs.edit().putBoolean("greeting", isChecked).apply()
|
||||
}
|
||||
R.id.switchNotifications -> {
|
||||
prefs.edit().putBoolean("notif", isChecked).apply()
|
||||
if (isChecked) {
|
||||
subscribeToTopic(Topic.ANDROID)
|
||||
} else {
|
||||
unsubscribeFromTopic(Topic.ANDROID)
|
||||
}
|
||||
}
|
||||
R.id.switchDefaultPlan -> {
|
||||
prefs.edit().putBoolean("defaultPersonalised", isChecked).apply()
|
||||
}
|
||||
R.id.switchAutoRefresh -> {
|
||||
prefs.edit().putBoolean("autoRefresh", isChecked).apply()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createDialog(title: String, text: String) {
|
||||
val alertDialog = AlertDialog.Builder(mContext,
|
||||
R.style.AlertDialog
|
||||
@@ -262,7 +199,7 @@ internal class SettingsFragment : Fragment(R.layout.content_settings), View.OnCl
|
||||
}
|
||||
|
||||
private fun createColourDialog() {
|
||||
val colourCustomiserBuilder = AlertDialog.Builder(mContext, R.style.AlertDialog)
|
||||
val colourCustomisationDialogBuilder = AlertDialog.Builder(mContext, R.style.AlertDialog)
|
||||
|
||||
val dialogView = View.inflate(mContext, R.layout.recycler_dialog, null)
|
||||
val titleText = dialogView.findViewById<TextView>(R.id.empty_textviewtitle)
|
||||
@@ -273,9 +210,9 @@ internal class SettingsFragment : Fragment(R.layout.content_settings), View.OnCl
|
||||
layoutManager = GridLayoutManager(mContext, 1)
|
||||
adapter = ColourAdapter(getColourList(), this@SettingsFragment)
|
||||
}
|
||||
colourCustomiserBuilder.setView(dialogView)
|
||||
val colourCustomiserDialog = colourCustomiserBuilder.create()
|
||||
colourCustomiserDialog.show()
|
||||
colourCustomisationDialogBuilder.setView(dialogView)
|
||||
val colourCustomisationDialog = colourCustomisationDialogBuilder.create()
|
||||
colourCustomisationDialog.show()
|
||||
}
|
||||
|
||||
private fun getColourList(): ArrayList<Colour> {
|
||||
@@ -371,15 +308,6 @@ internal class SettingsFragment : Fragment(R.layout.content_settings), View.OnCl
|
||||
return alarms
|
||||
}
|
||||
|
||||
override fun onRingtoneClick(position: Int, name: String, uri: String) {
|
||||
prefs.edit().apply {
|
||||
putString("ringtoneName", name)
|
||||
putString("ringtoneUri", uri)
|
||||
}.apply()
|
||||
setRingtoneText()
|
||||
ringtoneCustomiserDialog.dismiss()
|
||||
}
|
||||
|
||||
private fun setRingtoneText() {
|
||||
currentRingtone.text = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
mContext.getString(R.string.pick_ringtone_desc_o)
|
||||
@@ -393,36 +321,6 @@ internal class SettingsFragment : Fragment(R.layout.content_settings), View.OnCl
|
||||
}
|
||||
}
|
||||
|
||||
override fun onClick(position: Int, title: String, titleNoLang: String) {
|
||||
val colourPickerBuilder = AlertDialog.Builder(mContext, R.style.AlertDialog)
|
||||
val pickerDialogView = View.inflate(mContext, R.layout.empty_dialog, null)
|
||||
val pickerTitleText = pickerDialogView.findViewById<TextView>(R.id.empty_textviewtitle)
|
||||
val pickerLayout = pickerDialogView.findViewById<LinearLayout>(R.id.empty_linearlayout)
|
||||
pickerTitleText.text = title
|
||||
|
||||
val picker = View.inflate(mContext, R.layout.bg_colour_picker, null)
|
||||
pickerLayout.addView(picker)
|
||||
colourPickerBuilder.setView(pickerDialogView)
|
||||
val colourPickerDialog: AlertDialog = colourPickerBuilder.create()
|
||||
|
||||
val buttons = intArrayOf(R.id.def, R.id.red, R.id.orange, R.id.yellow, R.id.green,
|
||||
R.id.teal, R.id.cyan, R.id.blue, R.id.purple, R.id.pink, R.id.brown, R.id.grey,
|
||||
R.id.pureWhite, R.id.salmon, R.id.tangerine, R.id.banana, R.id.flora, R.id.spindrift,
|
||||
R.id.sky, R.id.orchid, R.id.lavender, R.id.carnation, R.id.brown2, R.id.pureBlack)
|
||||
val colours = HelperFunctions.colourNames
|
||||
|
||||
for (i2 in buttons.indices) {
|
||||
picker.findViewById<MaterialButton>(buttons[i2]).setOnClickListener {
|
||||
prefs.edit().putString("card$titleNoLang", colours[i2]).apply()
|
||||
val recyclerViewState = colourRecycler.layoutManager?.onSaveInstanceState()
|
||||
colourRecycler.adapter = ColourAdapter(getColourList(), this)
|
||||
colourRecycler.layoutManager?.onRestoreInstanceState(recyclerViewState)
|
||||
colourPickerDialog.dismiss()
|
||||
}
|
||||
}
|
||||
colourPickerDialog.show()
|
||||
}
|
||||
|
||||
private fun debugMenu(): Boolean {
|
||||
val alertDialog = AlertDialog.Builder(mContext, R.style.AlertDialog)
|
||||
val dialogView = View.inflate(mContext, R.layout.edittext_dialog, null)
|
||||
@@ -437,16 +335,14 @@ internal class SettingsFragment : Fragment(R.layout.content_settings), View.OnCl
|
||||
)
|
||||
dialogButton.setOnClickListener {
|
||||
when (dialogEditText.text.toString()) {
|
||||
"_DIAGNOSTICS" -> {
|
||||
"_STATISTICS" -> {
|
||||
val alertDialogDev = AlertDialog.Builder(mContext, R.style.AlertDialog)
|
||||
val devDialogView = View.inflate(mContext, R.layout.diagnostics_dialog, null)
|
||||
val devDialogText = devDialogView.findViewById<TextView>(R.id.dialogtext)
|
||||
val resetLaunchBtn = devDialogView.findViewById<Button>(R.id.btnResetLaunch)
|
||||
val resetNotificationBtn = devDialogView.findViewById<Button>(R.id.btnResetNotif)
|
||||
|
||||
devDialogView.findViewById<TextView>(R.id.textviewtitle).text = getString(
|
||||
R.string.diagnostics_dialog_title
|
||||
)
|
||||
devDialogView.findViewById<TextView>(R.id.textviewtitle).text = getString(R.string.statistics_dialog_title)
|
||||
devDialogText.text = getDiagnosticsText()
|
||||
|
||||
resetLaunchBtn.setOnClickListener {
|
||||
@@ -462,15 +358,19 @@ internal class SettingsFragment : Fragment(R.layout.content_settings), View.OnCl
|
||||
alertDialogDev.setView(devDialogView)
|
||||
alertDialogDev.show()
|
||||
}
|
||||
"2018-04-20" -> {
|
||||
"2019-06-06" -> {
|
||||
try {
|
||||
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://www.youtube.com/watch?v=Jc2xfYuLWgE")) // Freak
|
||||
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://www.youtube.com/watch?v=Jc2xfYuLWgE")) // 'Freak'
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK).setPackage("com.google.android.youtube")
|
||||
startActivity(intent)
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
makeToast(getString(R.string.youtube_not_found))
|
||||
}
|
||||
}
|
||||
"_LOGIN" -> {
|
||||
prefs.edit().putBoolean("successful_login", false).apply()
|
||||
makeToast("Login flag cleared")
|
||||
}
|
||||
"_FIRSTTIME" -> {
|
||||
prefs.edit().putBoolean("firstTime", true).apply()
|
||||
makeToast("First time flag cleared")
|
||||
@@ -531,6 +431,115 @@ internal class SettingsFragment : Fragment(R.layout.content_settings), View.OnCl
|
||||
private fun subscribeToTopic(topic: Topic) = FirebaseMessaging.getInstance().subscribeToTopic(topic.tag)
|
||||
private fun unsubscribeFromTopic(topic: Topic) = FirebaseMessaging.getInstance().unsubscribeFromTopic(topic.tag)
|
||||
|
||||
override fun onClick(v: View?) {
|
||||
when (v?.id) {
|
||||
R.id.chipHelpCourses -> createDialog(getString(R.string.courses_help_dialog_title), getString(R.string.courses_help_dialog_text))
|
||||
R.id.chipHelpClasses -> createDialog(getString(R.string.grade_help_dialog_title), getString(
|
||||
R.string.grade_help_dialog_text
|
||||
))
|
||||
R.id.btnCustomiseColours -> createColourDialog()
|
||||
R.id.btnNoNotif -> createDialog(mContext.getString(R.string.no_notifications_title), mContext.getString(R.string.no_notifications_dialog_text))
|
||||
R.id.btnCustomiseRingtone -> createRingtoneDialog()
|
||||
R.id.btnWebsite -> {
|
||||
try {
|
||||
customTabsIntent.launchUrl(mContext, Uri.parse("http://307.joomla.schule.bremen.de"))
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
makeToast(getString(R.string.chrome_not_found))
|
||||
}
|
||||
}
|
||||
R.id.btnLicences -> {
|
||||
createDialog(mContext.getString(R.string.licences_title), licences)
|
||||
}
|
||||
R.id.btnTerms -> {
|
||||
createDialog("Terms & Conditions", termsAndConditions)
|
||||
}
|
||||
R.id.btnPrivacyP -> {
|
||||
createDialog("Privacy Policy", privacyPolicy)
|
||||
}
|
||||
R.id.btnForceRefresh -> {
|
||||
DataFetcher(
|
||||
isPlan = true,
|
||||
isMenu = true,
|
||||
isJobService = false,
|
||||
context = mContext,
|
||||
application = activity!!.application,
|
||||
parentView = view!!.rootView,
|
||||
forced = true
|
||||
).execute()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onRingtoneClick(position: Int, name: String, uri: String) {
|
||||
prefs.edit().apply {
|
||||
putString("ringtoneName", name)
|
||||
putString("ringtoneUri", uri)
|
||||
}.apply()
|
||||
setRingtoneText()
|
||||
ringtoneCustomiserDialog.dismiss()
|
||||
}
|
||||
|
||||
/**
|
||||
* OnClick method for colour customisation dialog
|
||||
* @param position the position of the clicked item
|
||||
* @param title the title of the clicked course
|
||||
* @param titleNoLang the language-independent string used for storing the course's colour in
|
||||
* Shared Preferences
|
||||
*/
|
||||
override fun onClick(position: Int, title: String, titleNoLang: String) {
|
||||
val colourPickerBuilder = AlertDialog.Builder(mContext, R.style.AlertDialog)
|
||||
val pickerDialogView = View.inflate(mContext, R.layout.empty_dialog, null)
|
||||
val pickerTitleText = pickerDialogView.findViewById<TextView>(R.id.empty_textviewtitle)
|
||||
val pickerLayout = pickerDialogView.findViewById<LinearLayout>(R.id.empty_linearlayout)
|
||||
pickerTitleText.text = title
|
||||
|
||||
val picker = View.inflate(mContext, R.layout.bg_colour_picker, null)
|
||||
pickerLayout.addView(picker)
|
||||
colourPickerBuilder.setView(pickerDialogView)
|
||||
val colourPickerDialog: AlertDialog = colourPickerBuilder.create()
|
||||
|
||||
val buttons = intArrayOf(R.id.def, R.id.red, R.id.orange, R.id.yellow, R.id.green,
|
||||
R.id.teal, R.id.cyan, R.id.blue, R.id.purple, R.id.pink, R.id.brown, R.id.grey,
|
||||
R.id.pureWhite, R.id.salmon, R.id.tangerine, R.id.banana, R.id.flora, R.id.spindrift,
|
||||
R.id.sky, R.id.orchid, R.id.lavender, R.id.carnation, R.id.brown2, R.id.pureBlack)
|
||||
val colours = HelperFunctions.colourNames
|
||||
|
||||
for (i2 in buttons.indices) {
|
||||
picker.findViewById<MaterialButton>(buttons[i2]).setOnClickListener {
|
||||
prefs.edit().putString("card$titleNoLang", colours[i2]).apply()
|
||||
val recyclerViewState = colourRecycler.layoutManager?.onSaveInstanceState()
|
||||
colourRecycler.adapter = ColourAdapter(getColourList(), this)
|
||||
colourRecycler.layoutManager?.onRestoreInstanceState(recyclerViewState)
|
||||
colourPickerDialog.dismiss()
|
||||
}
|
||||
}
|
||||
colourPickerDialog.show()
|
||||
}
|
||||
|
||||
override fun onCheckedChanged(v: CompoundButton?, isChecked: Boolean) {
|
||||
if (v?.isPressed == true) {
|
||||
when (v.id) {
|
||||
R.id.switchDisableGreeting -> {
|
||||
prefs.edit().putBoolean("greeting", isChecked).apply()
|
||||
}
|
||||
R.id.switchNotifications -> {
|
||||
prefs.edit().putBoolean("notif", isChecked).apply()
|
||||
if (isChecked) {
|
||||
subscribeToTopic(Topic.ANDROID)
|
||||
} else {
|
||||
unsubscribeFromTopic(Topic.ANDROID)
|
||||
}
|
||||
}
|
||||
R.id.switchDefaultPlan -> {
|
||||
prefs.edit().putBoolean("defaultPersonalised", isChecked).apply()
|
||||
}
|
||||
R.id.switchAutoRefresh -> {
|
||||
prefs.edit().putBoolean("autoRefresh", isChecked).apply()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val licences = "Libraries:" +
|
||||
"\n • jsoup HTML parser © 2009-2018 Jonathan Hedley, licensed under the open source MIT Licence" +
|
||||
"\n\nFont:" +
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
@Entity(tableName = "subst_table")
|
||||
internal data class Subst(
|
||||
internal data class Substitution(
|
||||
val group: String,
|
||||
val date: String,
|
||||
val time: String,
|
||||
Reference in New Issue
Block a user