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.denizd.substitutionplan.R
|
||||||
import com.google.android.material.card.MaterialCardView
|
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
|
internal class ColourViewHolder(view: View, private val clickListener: OnClickListener) : RecyclerView.ViewHolder(view), View.OnClickListener {
|
||||||
|
|
||||||
class ColourViewHolder(view: View, clickListener: OnClickListener) : RecyclerView.ViewHolder(view), View.OnClickListener {
|
|
||||||
val title: TextView = view.findViewById(R.id.item_text)
|
val title: TextView = view.findViewById(R.id.item_text)
|
||||||
var image: ImageView = view.findViewById(R.id.item_image)
|
var image: ImageView = view.findViewById(R.id.item_image)
|
||||||
val titleNoLang: TextView = view.findViewById(R.id.item_text_no_lang)
|
val titleNoLang: TextView = view.findViewById(R.id.item_text_no_lang)
|
||||||
val cardView: MaterialCardView = view.findViewById(R.id.cardView)
|
val cardView: MaterialCardView = view.findViewById(R.id.cardView)
|
||||||
private val mClickListener = clickListener
|
|
||||||
init { view.setOnClickListener(this) }
|
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 {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ColourViewHolder {
|
||||||
val v = LayoutInflater.from(parent.context).inflate(R.layout.list_item, parent, false)
|
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) {
|
override fun onBindViewHolder(holder: ColourViewHolder, position: Int) {
|
||||||
val currentItem = mColours[position]
|
val currentItem = colours[position]
|
||||||
|
|
||||||
holder.title.text = currentItem.title
|
holder.title.text = currentItem.title
|
||||||
holder.titleNoLang.text = currentItem.titleNoLang
|
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))
|
holder.title.setTextColor(ContextCompat.getColor(holder.title.context, textColor))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int = mColours.size
|
override fun getItemCount(): Int = colours.size
|
||||||
|
|
||||||
internal interface OnClickListener {
|
internal interface OnClickListener {
|
||||||
fun onClick(position: Int, title: String, titleNoLang: String)
|
fun onClick(position: Int, title: String, titleNoLang: String)
|
||||||
|
|||||||
@@ -5,39 +5,38 @@ import android.view.View
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
|
|
||||||
import java.util.ArrayList
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.denizd.substitutionplan.models.Food
|
import com.denizd.substitutionplan.models.Food
|
||||||
import com.denizd.substitutionplan.R
|
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) {
|
internal class FoodViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||||
var mFood: TextView = itemView.findViewById(R.id.cardInfoText)
|
var text: TextView = itemView.findViewById(R.id.cardInfoText)
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FoodViewHolder {
|
||||||
mFood = food
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CardViewHolder {
|
|
||||||
val v = LayoutInflater.from(parent.context).inflate(R.layout.just_a_card, parent, false)
|
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) {
|
override fun onBindViewHolder(holder: FoodViewHolder, position: Int) {
|
||||||
val currentItem = mFood!![position]
|
val currentItem = foods[position]
|
||||||
|
|
||||||
holder.mFood.text = currentItem.food
|
holder.text.text = currentItem.food
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int {
|
override fun getItemCount(): Int {
|
||||||
return mFood!!.size
|
return foods.size
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setFood(food: List<Food>) {
|
fun setFood(foods: List<Food>) {
|
||||||
mFood = food
|
this.foods = foods
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,40 +10,39 @@ import com.denizd.substitutionplan.R
|
|||||||
import com.denizd.substitutionplan.models.Ringtone
|
import com.denizd.substitutionplan.models.Ringtone
|
||||||
import com.google.android.material.card.MaterialCardView
|
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
|
internal class RingtoneViewHolder(view: View, private val clickListener: OnClickListener) : RecyclerView.ViewHolder(view), View.OnClickListener {
|
||||||
|
|
||||||
class RingtoneViewHolder(view: View, clickListener: OnClickListener) : RecyclerView.ViewHolder(view), View.OnClickListener {
|
|
||||||
val name: TextView = view.findViewById(R.id.item_text)
|
val name: TextView = view.findViewById(R.id.item_text)
|
||||||
val uri: TextView = view.findViewById(R.id.item_text_no_lang)
|
val uri: TextView = view.findViewById(R.id.item_text_no_lang)
|
||||||
val cardView: MaterialCardView = view.findViewById(R.id.cardView)
|
val cardView: MaterialCardView = view.findViewById(R.id.cardView)
|
||||||
private val _clickListener = clickListener
|
|
||||||
init { view.setOnClickListener(this) }
|
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 {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RingtoneViewHolder {
|
||||||
val v = LayoutInflater.from(parent.context).inflate(R.layout.list_item, parent, false)
|
val v = LayoutInflater.from(parent.context).inflate(R.layout.list_item, parent, false)
|
||||||
return RingtoneViewHolder(
|
return RingtoneViewHolder(v, onClickListener)
|
||||||
v,
|
|
||||||
_onClickListener
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: RingtoneViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: RingtoneViewHolder, position: Int) {
|
||||||
val currentItem = _ringtones[position]
|
val currentItem = ringtones[position]
|
||||||
|
|
||||||
holder.name.text = currentItem.name
|
holder.name.text = currentItem.name
|
||||||
holder.uri.text = currentItem.uri
|
holder.uri.text = currentItem.uri
|
||||||
holder.cardView.setCardBackgroundColor(ContextCompat.getColor(holder.cardView.context,
|
holder.cardView.setCardBackgroundColor(ContextCompat.getColor(holder.cardView.context, R.color.colorBackground))
|
||||||
R.color.colorBackground
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int = _ringtones.size
|
override fun getItemCount(): Int = ringtones.size
|
||||||
|
|
||||||
internal interface OnClickListener {
|
internal interface OnClickListener {
|
||||||
fun onRingtoneClick(position: Int, name: String, uri: String)
|
fun onRingtoneClick(position: Int, name: String, uri: String)
|
||||||
|
|||||||
+24
-65
@@ -1,6 +1,7 @@
|
|||||||
package com.denizd.substitutionplan.adapters
|
package com.denizd.substitutionplan.adapters
|
||||||
|
|
||||||
import android.content.ActivityNotFoundException
|
import android.content.ActivityNotFoundException
|
||||||
|
import android.content.Context
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.text.SpannableString
|
import android.text.SpannableString
|
||||||
@@ -16,18 +17,20 @@ import androidx.core.content.ContextCompat
|
|||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.denizd.substitutionplan.data.HelperFunctions
|
import com.denizd.substitutionplan.data.HelperFunctions
|
||||||
import com.denizd.substitutionplan.R
|
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 com.google.android.material.card.MaterialCardView
|
||||||
import java.util.*
|
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
|
internal class CardViewHolder(view: View) : RecyclerView.ViewHolder(view), View.OnClickListener {
|
||||||
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 {
|
|
||||||
|
|
||||||
var iconView: ImageView = view.findViewById(R.id.iconView)
|
var iconView: ImageView = view.findViewById(R.id.iconView)
|
||||||
var group: TextView = view.findViewById(R.id.group)
|
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 additional: TextView = view.findViewById(R.id.additional)
|
||||||
var teacher: TextView = view.findViewById(R.id.teacher)
|
var teacher: TextView = view.findViewById(R.id.teacher)
|
||||||
var spacer: TextView = view.findViewById(R.id.spacer)
|
var spacer: TextView = view.findViewById(R.id.spacer)
|
||||||
|
|
||||||
var card: MaterialCardView = view.findViewById(R.id.planCard)
|
var card: MaterialCardView = view.findViewById(R.id.planCard)
|
||||||
|
val context: Context = card.context
|
||||||
init { view.setOnClickListener(this) }
|
init { view.setOnClickListener(this) }
|
||||||
override fun onClick(v: View?) {
|
override fun onClick(v: View?) {
|
||||||
if (date.text.toString().length > 7 && date.text.toString().substring(3, 7) == "http") {
|
if (date.text.toString().length > 7 && date.text.toString().substring(3, 7) == "http") {
|
||||||
try {
|
try {
|
||||||
CustomTabsIntent.Builder().build().launchUrl(card.context,
|
CustomTabsIntent.Builder().build().launchUrl(context,
|
||||||
Uri.parse(date.text.toString().substring(3)))
|
Uri.parse(date.text.substring(3)))
|
||||||
} catch (e: ActivityNotFoundException) {
|
} 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) {
|
override fun onBindViewHolder(holder: CardViewHolder, position: Int) {
|
||||||
val currentItem = mSubst[position]
|
val currentItem = substitutions[position]
|
||||||
var psa = false
|
var psa = false
|
||||||
val strings = arrayOf(SpannableString(currentItem.group), SpannableString(currentItem.time),
|
val strings = arrayOf(SpannableString(currentItem.group), SpannableString(currentItem.time),
|
||||||
SpannableString(currentItem.course), SpannableString(currentItem.room),
|
SpannableString(currentItem.course), SpannableString(currentItem.room),
|
||||||
SpannableString(currentItem.teacher))
|
SpannableString(currentItem.teacher))
|
||||||
var cardBackgroundColour = 0
|
val cardBackgroundColour: Int
|
||||||
|
var colour = 0
|
||||||
|
|
||||||
for (string in strings) {
|
for (string in strings) {
|
||||||
val questionMarkIndex = string.indexOf("?")
|
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 add = currentItem.additional.toLowerCase(Locale.ROOT)
|
||||||
val type = currentItem.type.toLowerCase(Locale.ROOT)
|
val type = currentItem.type.toLowerCase(Locale.ROOT)
|
||||||
if (add.isNotEmpty()) {
|
if (add.isNotEmpty()) {
|
||||||
if (HelperFunctions.checkStringForArray(add, cancellations)) {
|
if (HelperFunctions.checkStringForArray(add, HelperFunctions.cancellations)) {
|
||||||
strikeThrough(strings)
|
strikeThrough(strings)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (HelperFunctions.checkStringForArray(type, cancellations)) {
|
if (HelperFunctions.checkStringForArray(type, HelperFunctions.cancellations)) {
|
||||||
strikeThrough(strings)
|
strikeThrough(strings)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -100,7 +104,7 @@ internal class CardAdapter(private var mSubst: List<Subst>, private val prefs: S
|
|||||||
cardBackgroundColour = R.color.colorAccent
|
cardBackgroundColour = R.color.colorAccent
|
||||||
View.GONE
|
View.GONE
|
||||||
} else {
|
} else {
|
||||||
colourString = getColourString(holder.course.text.toString())
|
val colourString = HelperFunctions.getColourString(holder.course.text.toString())
|
||||||
val colourPrefsInt = if (colourString.isNotEmpty()) {
|
val colourPrefsInt = if (colourString.isNotEmpty()) {
|
||||||
prefs.getString("card$colourString", "") ?: ""
|
prefs.getString("card$colourString", "") ?: ""
|
||||||
} else {
|
} else {
|
||||||
@@ -150,58 +154,13 @@ internal class CardAdapter(private var mSubst: List<Subst>, private val prefs: S
|
|||||||
holder.teacher.setTextColor(textColor)
|
holder.teacher.setTextColor(textColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int = mSubst.size
|
override fun getItemCount(): Int = substitutions.size
|
||||||
|
|
||||||
fun setSubst(subst: List<Subst>) {
|
fun setSubst(substitutions: List<Substitution>) {
|
||||||
mSubst = subst
|
this.substitutions = substitutions
|
||||||
notifyDataSetChanged()
|
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>) {
|
private fun strikeThrough(strings: Array<SpannableString>) {
|
||||||
for (i in 2..4) { strings[i].setSpan(StrikethroughSpan(), 0, strings[i].length, 0) }
|
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.database.SubstRepository
|
||||||
import com.denizd.substitutionplan.activities.Main
|
import com.denizd.substitutionplan.activities.Main
|
||||||
import com.denizd.substitutionplan.models.Food
|
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 com.google.android.material.snackbar.Snackbar
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
@@ -57,7 +57,7 @@ internal class DataFetcher(isPlan: Boolean, isMenu: Boolean, isJobService: Boole
|
|||||||
private val edit = prefs.edit()
|
private val edit = prefs.edit()
|
||||||
private var currentTime = ""
|
private var currentTime = ""
|
||||||
private var currentFoodTime = ""
|
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"
|
private var foodUrl = "https://djd4rkn355.github.io/food.html"
|
||||||
|
|
||||||
override fun doInBackground(vararg params: Void?): Void? {
|
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", "")) {
|
if (currentTime != prefs.getString("timeNew", "")) {
|
||||||
val rows = doc.select("tr")
|
val rows = doc.select("tr")
|
||||||
val paragraphs = doc.select("p")
|
val paragraphs = doc.select("p")
|
||||||
val substArray = ArrayList<Subst>()
|
val substArray = ArrayList<Substitution>()
|
||||||
|
|
||||||
val coursePreference = prefs.getString("courses", "") ?: ""
|
val coursePreference = prefs.getString("courses", "") ?: ""
|
||||||
val classPreference = prefs.getString("classes", "") ?: ""
|
val classPreference = prefs.getString("classes", "") ?: ""
|
||||||
@@ -169,7 +169,7 @@ internal class DataFetcher(isPlan: Boolean, isMenu: Boolean, isJobService: Boole
|
|||||||
val row = rows[i]
|
val row = rows[i]
|
||||||
val cols = row.select("th")
|
val cols = row.select("th")
|
||||||
|
|
||||||
val subst = Subst(
|
val subst = Substitution(
|
||||||
group = cols[0].text(),
|
group = cols[0].text(),
|
||||||
date = cols[1].text(),
|
date = cols[1].text(),
|
||||||
time = cols[2].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)
|
val notification = NotificationCompat.Builder(context, HelperFunctions.notificationChannelId)
|
||||||
.setStyle(NotificationCompat.DecoratedCustomViewStyle())
|
.setStyle(NotificationCompat.DecoratedCustomViewStyle())
|
||||||
.setCustomContentView(notificationLayout)
|
.setCustomContentView(notificationLayout)
|
||||||
.setSmallIcon(R.drawable.ic_avhlogo)
|
|
||||||
.setContentIntent(openAppPending)
|
.setContentIntent(openAppPending)
|
||||||
.setAutoCancel(true)
|
.setAutoCancel(true)
|
||||||
.setColor(ContextCompat.getColor(context, R.color.colorAccent))
|
.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) {
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
||||||
val sound = if ((prefs.getString("ringtoneUri", "") ?: "").isNotEmpty()) {
|
val sound = if ((prefs.getString("ringtoneUri", "") ?: "").isNotEmpty()) {
|
||||||
Uri.parse(prefs.getString("ringtoneUri", "") ?: "")
|
Uri.parse(prefs.getString("ringtoneUri", "") ?: "")
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import androidx.core.content.ContextCompat
|
|||||||
import androidx.core.content.ContextCompat.checkSelfPermission
|
import androidx.core.content.ContextCompat.checkSelfPermission
|
||||||
import androidx.fragment.app.FragmentActivity
|
import androidx.fragment.app.FragmentActivity
|
||||||
import com.denizd.substitutionplan.R
|
import com.denizd.substitutionplan.R
|
||||||
import com.denizd.substitutionplan.models.Subst
|
import com.denizd.substitutionplan.models.Substitution
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileOutputStream
|
import java.io.FileOutputStream
|
||||||
@@ -45,6 +45,12 @@ internal object HelperFunctions {
|
|||||||
"brown", "grey", "pureWhite", "salmon", "tangerine", "banana", "flora", "spindrift", "sky", "orchid",
|
"brown", "grey", "pureWhite", "salmon", "tangerine", "banana", "flora", "spindrift", "sky", "orchid",
|
||||||
"lavender", "carnation", "brown2", "pureBlack")
|
"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(
|
private val colourIntegers = intArrayOf(
|
||||||
0,
|
0,
|
||||||
R.color.bgRed,
|
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
|
* 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
|
* 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
|
* 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
|
* 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 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 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
|
* @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
|
* @return true if the substitution is relevant to the user, false otherwise
|
||||||
*/
|
*/
|
||||||
fun checkPersonalSubstitutions(subst: Subst, coursePreference: String, classPreference: String, psa: Boolean): Boolean {
|
fun checkPersonalSubstitutions(substitution: Substitution, coursePreference: String, classPreference: String, psa: Boolean): Boolean {
|
||||||
val group = subst.group
|
val group = substitution.group
|
||||||
val course = subst.course
|
val course = substitution.course
|
||||||
if (psa && subst.date.isNotEmpty() && subst.date.substring(0, 3) == "psa") {
|
if (psa && substitution.date.isNotEmpty() && substitution.date.substring(0, 3) == "psa") {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if (coursePreference.isEmpty() && classPreference.isNotEmpty()) {
|
if (coursePreference.isEmpty() && classPreference.isNotEmpty()) {
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
package com.denizd.substitutionplan.data
|
package com.denizd.substitutionplan.data
|
||||||
|
|
||||||
|
import android.graphics.Bitmap
|
||||||
|
import android.util.Log
|
||||||
import android.webkit.CookieManager
|
import android.webkit.CookieManager
|
||||||
import android.webkit.WebView
|
import android.webkit.WebView
|
||||||
import android.webkit.WebViewClient
|
import android.webkit.WebViewClient
|
||||||
|
import java.lang.IllegalStateException
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class that extends WebViewClient to provide a function that checks the webpage's cookies to
|
* 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
|
* @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"
|
* OnPageFinished has been overridden to check if the cookie "joomla_user_state=logged_in"
|
||||||
* exists, and returns true to the OnLoginSuccessListener
|
* 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?) {
|
override fun onPageFinished(view: WebView?, url: String?) {
|
||||||
super.onPageFinished(view, url)
|
super.onPageFinished(view, url)
|
||||||
view?.scrollY = -4000
|
view?.scrollY = -10_000
|
||||||
|
|
||||||
val cookies = CookieManager.getInstance().getCookie(url)
|
val cookies = CookieManager.getInstance().getCookie(url)
|
||||||
|
|
||||||
if (cookies.contains("joomla_user_state=logged_in")) {
|
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
|
* 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.lifecycle.LiveData
|
||||||
import androidx.room.*
|
import androidx.room.*
|
||||||
import com.denizd.substitutionplan.models.Food
|
import com.denizd.substitutionplan.models.Food
|
||||||
import com.denizd.substitutionplan.models.Subst
|
import com.denizd.substitutionplan.models.Substitution
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
internal interface SubstDao {
|
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 date ASC, `group` ASC, time ASC, priority DESC")
|
||||||
@get:Query("SELECT * FROM subst_table ORDER BY priority DESC")
|
@get:Query("SELECT * FROM subst_table ORDER BY priority DESC")
|
||||||
val allSubst: LiveData<List<Subst>>
|
val allSubstitutions: LiveData<List<Substitution>>
|
||||||
|
|
||||||
@Insert
|
@Insert
|
||||||
fun insertSubst(subst: Subst)
|
fun insertSubst(substitution: Substitution)
|
||||||
|
|
||||||
@Update
|
@Update
|
||||||
fun updateSubst(subst: Subst)
|
fun updateSubst(substitution: Substitution)
|
||||||
|
|
||||||
@Delete
|
@Delete
|
||||||
fun deleteSubst(subst: Subst)
|
fun deleteSubst(substitution: Substitution)
|
||||||
|
|
||||||
@Query("DELETE FROM subst_table")
|
@Query("DELETE FROM subst_table")
|
||||||
fun deleteAllSubst()
|
fun deleteAllSubst()
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ import androidx.room.RoomDatabase
|
|||||||
import androidx.room.migration.Migration
|
import androidx.room.migration.Migration
|
||||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||||
import com.denizd.substitutionplan.models.Food
|
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() {
|
internal abstract class SubstDatabase : RoomDatabase() {
|
||||||
|
|
||||||
abstract fun substDao(): SubstDao
|
abstract fun substDao(): SubstDao
|
||||||
|
|||||||
@@ -4,32 +4,32 @@ import android.app.Application
|
|||||||
import android.os.AsyncTask
|
import android.os.AsyncTask
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import com.denizd.substitutionplan.models.Subst
|
import com.denizd.substitutionplan.models.Substitution
|
||||||
|
|
||||||
internal class SubstRepository(application: Application) {
|
internal class SubstRepository(application: Application) {
|
||||||
|
|
||||||
private val substDao: SubstDao?
|
private val substDao: SubstDao?
|
||||||
val allSubst: LiveData<List<Subst>>?
|
val allSubstitutions: LiveData<List<Substitution>>?
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val database =
|
val database =
|
||||||
SubstDatabase.getInstance(application)
|
SubstDatabase.getInstance(application)
|
||||||
substDao = database?.substDao()
|
substDao = database?.substDao()
|
||||||
allSubst = substDao?.allSubst
|
allSubstitutions = substDao?.allSubstitutions
|
||||||
}
|
}
|
||||||
|
|
||||||
fun insert(subst: Subst) {
|
fun insert(substitution: Substitution) {
|
||||||
InsertSubstAsync(substDao).execute(subst)
|
InsertSubstAsync(substDao).execute(substitution)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deleteAllSubst() {
|
fun deleteAllSubst() {
|
||||||
DeleteAllSubstAsync(substDao).execute()
|
DeleteAllSubstAsync(substDao).execute()
|
||||||
}
|
}
|
||||||
|
|
||||||
class InsertSubstAsync(substDao: SubstDao?) : AsyncTask<Subst, Void, Void>() {
|
class InsertSubstAsync(substDao: SubstDao?) : AsyncTask<Substitution, Void, Void>() {
|
||||||
private val mSubstDao = substDao
|
private val mSubstDao = substDao
|
||||||
override fun doInBackground(vararg substs: Subst): Void? {
|
override fun doInBackground(vararg substitutions: Substitution): Void? {
|
||||||
mSubstDao?.insertSubst(substs[0])
|
mSubstDao?.insertSubst(substitutions[0])
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,16 +6,16 @@ import androidx.lifecycle.AndroidViewModel
|
|||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
import com.denizd.substitutionplan.data.DataFetcher
|
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) {
|
internal class SubstViewModel(application: Application) : AndroidViewModel(application) {
|
||||||
|
|
||||||
private val repository: SubstRepository = SubstRepository(application)
|
private val repository: SubstRepository = SubstRepository(application)
|
||||||
val allSubst: LiveData<List<Subst>>?
|
val allSubstitutions: LiveData<List<Substitution>>?
|
||||||
private val app = application
|
private val app = application
|
||||||
|
|
||||||
init {
|
init {
|
||||||
allSubst = repository.allSubst
|
allSubstitutions = repository.allSubstitutions
|
||||||
}
|
}
|
||||||
|
|
||||||
fun refresh(swipeRefreshLayout: SwipeRefreshLayout, rootView: View, refreshMenu: Boolean) {
|
fun refresh(swipeRefreshLayout: SwipeRefreshLayout, rootView: View, refreshMenu: Boolean) {
|
||||||
|
|||||||
@@ -35,17 +35,10 @@ internal class FoodFragment : Fragment(R.layout.food_layout) {
|
|||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
val pullToRefresh = view.findViewById<SwipeRefreshLayout>(R.id.pullToRefresh)
|
val pullToRefresh = view.findViewById<SwipeRefreshLayout>(R.id.pullToRefresh)
|
||||||
|
|
||||||
try {
|
recyclerView = view.findViewById(R.id.linear_food)
|
||||||
recyclerView = view.findViewById(R.id.linear_food)
|
recyclerView.hasFixedSize()
|
||||||
recyclerView.hasFixedSize()
|
recyclerView.layoutManager = GridLayoutManager(mContext, 1)
|
||||||
recyclerView.layoutManager = GridLayoutManager(mContext, 1)
|
recyclerView.adapter = mAdapter
|
||||||
recyclerView.adapter = mAdapter
|
|
||||||
|
|
||||||
try {
|
|
||||||
recyclerView.removeAllViews()
|
|
||||||
} catch (ignored: NullPointerException) {}
|
|
||||||
|
|
||||||
} catch (ignored: NullPointerException) {}
|
|
||||||
|
|
||||||
foodViewModel = ViewModelProviders.of(this).get(FoodViewModel::class.java)
|
foodViewModel = ViewModelProviders.of(this).get(FoodViewModel::class.java)
|
||||||
foodViewModel.allFoods?.observe(this, Observer<List<Food>> { foodList ->
|
foodViewModel.allFoods?.observe(this, Observer<List<Food>> { foodList ->
|
||||||
|
|||||||
@@ -3,14 +3,14 @@ package com.denizd.substitutionplan.fragments
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import com.denizd.substitutionplan.models.Subst
|
import com.denizd.substitutionplan.models.Substitution
|
||||||
|
|
||||||
internal class GeneralPlanFragment : PlanFragment() {
|
internal class GeneralPlanFragment : PlanFragment() {
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
substViewModel.allSubst?.observe(this, Observer<List<Subst>> { substitutions ->
|
substViewModel.allSubstitutions?.observe(this, Observer<List<Substitution>> { substitutions ->
|
||||||
mAdapter.setSubst(substitutions)
|
mAdapter.setSubst(substitutions)
|
||||||
recyclerView.scheduleLayoutAnimation()
|
recyclerView.scheduleLayoutAnimation()
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import android.view.View
|
|||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import com.denizd.substitutionplan.data.HelperFunctions
|
import com.denizd.substitutionplan.data.HelperFunctions
|
||||||
import com.denizd.substitutionplan.R
|
import com.denizd.substitutionplan.R
|
||||||
import com.denizd.substitutionplan.models.Subst
|
import com.denizd.substitutionplan.models.Substitution
|
||||||
|
|
||||||
internal class PersonalPlanFragment : PlanFragment() {
|
internal class PersonalPlanFragment : PlanFragment() {
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ internal class PersonalPlanFragment : PlanFragment() {
|
|||||||
val coursePreference = prefs.getString("courses", "") ?: ""
|
val coursePreference = prefs.getString("courses", "") ?: ""
|
||||||
val classPreference = prefs.getString("classes", "") ?: ""
|
val classPreference = prefs.getString("classes", "") ?: ""
|
||||||
|
|
||||||
substViewModel.allSubst?.observe(this, Observer<List<Subst>> { substitutions ->
|
substViewModel.allSubstitutions?.observe(this, Observer<List<Substitution>> { substitutions ->
|
||||||
planCardList.clear()
|
planCardList.clear()
|
||||||
personalPlanEmptyEmoticon.visibility = View.GONE
|
personalPlanEmptyEmoticon.visibility = View.GONE
|
||||||
personalPlanEmptyText.visibility = View.GONE
|
personalPlanEmptyText.visibility = View.GONE
|
||||||
|
|||||||
@@ -15,15 +15,15 @@ import androidx.recyclerview.widget.GridLayoutManager
|
|||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
import com.denizd.substitutionplan.*
|
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.database.SubstViewModel
|
||||||
import com.denizd.substitutionplan.models.Subst
|
import com.denizd.substitutionplan.models.Substitution
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
internal open class PlanFragment : Fragment(R.layout.plan) {
|
internal open class PlanFragment : Fragment(R.layout.plan) {
|
||||||
lateinit var recyclerView: RecyclerView
|
lateinit var recyclerView: RecyclerView
|
||||||
lateinit var mAdapter: CardAdapter
|
lateinit var mAdapter: SubstitutionAdapter
|
||||||
var planCardList = ArrayList<Subst>()
|
var planCardList = ArrayList<Substitution>()
|
||||||
lateinit var substViewModel: SubstViewModel
|
lateinit var substViewModel: SubstViewModel
|
||||||
private lateinit var mContext: Context
|
private lateinit var mContext: Context
|
||||||
lateinit var prefs: SharedPreferences
|
lateinit var prefs: SharedPreferences
|
||||||
@@ -53,7 +53,7 @@ internal open class PlanFragment : Fragment(R.layout.plan) {
|
|||||||
recyclerView = view.findViewById(R.id.linearRecycler)
|
recyclerView = view.findViewById(R.id.linearRecycler)
|
||||||
recyclerView.hasFixedSize()
|
recyclerView.hasFixedSize()
|
||||||
recyclerView.layoutManager = GridLayoutManager(mContext, getGridColumnCount(resources.configuration))
|
recyclerView.layoutManager = GridLayoutManager(mContext, getGridColumnCount(resources.configuration))
|
||||||
mAdapter = CardAdapter(planCardList, prefs)
|
mAdapter = SubstitutionAdapter(planCardList, prefs)
|
||||||
recyclerView.adapter = mAdapter
|
recyclerView.adapter = mAdapter
|
||||||
|
|
||||||
if (prefs.getInt("firstTimeOpening", 0) == 1) {
|
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) {
|
private fun createDialog(title: String, text: String) {
|
||||||
val alertDialog = AlertDialog.Builder(mContext,
|
val alertDialog = AlertDialog.Builder(mContext,
|
||||||
R.style.AlertDialog
|
R.style.AlertDialog
|
||||||
@@ -262,7 +199,7 @@ internal class SettingsFragment : Fragment(R.layout.content_settings), View.OnCl
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun createColourDialog() {
|
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 dialogView = View.inflate(mContext, R.layout.recycler_dialog, null)
|
||||||
val titleText = dialogView.findViewById<TextView>(R.id.empty_textviewtitle)
|
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)
|
layoutManager = GridLayoutManager(mContext, 1)
|
||||||
adapter = ColourAdapter(getColourList(), this@SettingsFragment)
|
adapter = ColourAdapter(getColourList(), this@SettingsFragment)
|
||||||
}
|
}
|
||||||
colourCustomiserBuilder.setView(dialogView)
|
colourCustomisationDialogBuilder.setView(dialogView)
|
||||||
val colourCustomiserDialog = colourCustomiserBuilder.create()
|
val colourCustomisationDialog = colourCustomisationDialogBuilder.create()
|
||||||
colourCustomiserDialog.show()
|
colourCustomisationDialog.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getColourList(): ArrayList<Colour> {
|
private fun getColourList(): ArrayList<Colour> {
|
||||||
@@ -371,15 +308,6 @@ internal class SettingsFragment : Fragment(R.layout.content_settings), View.OnCl
|
|||||||
return alarms
|
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() {
|
private fun setRingtoneText() {
|
||||||
currentRingtone.text = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
currentRingtone.text = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
mContext.getString(R.string.pick_ringtone_desc_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 {
|
private fun debugMenu(): Boolean {
|
||||||
val alertDialog = AlertDialog.Builder(mContext, R.style.AlertDialog)
|
val alertDialog = AlertDialog.Builder(mContext, R.style.AlertDialog)
|
||||||
val dialogView = View.inflate(mContext, R.layout.edittext_dialog, null)
|
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 {
|
dialogButton.setOnClickListener {
|
||||||
when (dialogEditText.text.toString()) {
|
when (dialogEditText.text.toString()) {
|
||||||
"_DIAGNOSTICS" -> {
|
"_STATISTICS" -> {
|
||||||
val alertDialogDev = AlertDialog.Builder(mContext, R.style.AlertDialog)
|
val alertDialogDev = AlertDialog.Builder(mContext, R.style.AlertDialog)
|
||||||
val devDialogView = View.inflate(mContext, R.layout.diagnostics_dialog, null)
|
val devDialogView = View.inflate(mContext, R.layout.diagnostics_dialog, null)
|
||||||
val devDialogText = devDialogView.findViewById<TextView>(R.id.dialogtext)
|
val devDialogText = devDialogView.findViewById<TextView>(R.id.dialogtext)
|
||||||
val resetLaunchBtn = devDialogView.findViewById<Button>(R.id.btnResetLaunch)
|
val resetLaunchBtn = devDialogView.findViewById<Button>(R.id.btnResetLaunch)
|
||||||
val resetNotificationBtn = devDialogView.findViewById<Button>(R.id.btnResetNotif)
|
val resetNotificationBtn = devDialogView.findViewById<Button>(R.id.btnResetNotif)
|
||||||
|
|
||||||
devDialogView.findViewById<TextView>(R.id.textviewtitle).text = getString(
|
devDialogView.findViewById<TextView>(R.id.textviewtitle).text = getString(R.string.statistics_dialog_title)
|
||||||
R.string.diagnostics_dialog_title
|
|
||||||
)
|
|
||||||
devDialogText.text = getDiagnosticsText()
|
devDialogText.text = getDiagnosticsText()
|
||||||
|
|
||||||
resetLaunchBtn.setOnClickListener {
|
resetLaunchBtn.setOnClickListener {
|
||||||
@@ -462,15 +358,19 @@ internal class SettingsFragment : Fragment(R.layout.content_settings), View.OnCl
|
|||||||
alertDialogDev.setView(devDialogView)
|
alertDialogDev.setView(devDialogView)
|
||||||
alertDialogDev.show()
|
alertDialogDev.show()
|
||||||
}
|
}
|
||||||
"2018-04-20" -> {
|
"2019-06-06" -> {
|
||||||
try {
|
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")
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK).setPackage("com.google.android.youtube")
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
} catch (e: ActivityNotFoundException) {
|
} catch (e: ActivityNotFoundException) {
|
||||||
makeToast(getString(R.string.youtube_not_found))
|
makeToast(getString(R.string.youtube_not_found))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
"_LOGIN" -> {
|
||||||
|
prefs.edit().putBoolean("successful_login", false).apply()
|
||||||
|
makeToast("Login flag cleared")
|
||||||
|
}
|
||||||
"_FIRSTTIME" -> {
|
"_FIRSTTIME" -> {
|
||||||
prefs.edit().putBoolean("firstTime", true).apply()
|
prefs.edit().putBoolean("firstTime", true).apply()
|
||||||
makeToast("First time flag cleared")
|
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 subscribeToTopic(topic: Topic) = FirebaseMessaging.getInstance().subscribeToTopic(topic.tag)
|
||||||
private fun unsubscribeFromTopic(topic: Topic) = FirebaseMessaging.getInstance().unsubscribeFromTopic(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:" +
|
private val licences = "Libraries:" +
|
||||||
"\n • jsoup HTML parser © 2009-2018 Jonathan Hedley, licensed under the open source MIT Licence" +
|
"\n • jsoup HTML parser © 2009-2018 Jonathan Hedley, licensed under the open source MIT Licence" +
|
||||||
"\n\nFont:" +
|
"\n\nFont:" +
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@ import androidx.room.Entity
|
|||||||
import androidx.room.PrimaryKey
|
import androidx.room.PrimaryKey
|
||||||
|
|
||||||
@Entity(tableName = "subst_table")
|
@Entity(tableName = "subst_table")
|
||||||
internal data class Subst(
|
internal data class Substitution(
|
||||||
val group: String,
|
val group: String,
|
||||||
val date: String,
|
val date: String,
|
||||||
val time: String,
|
val time: String,
|
||||||
@@ -106,7 +106,7 @@
|
|||||||
android:id="@+id/temporary"
|
android:id="@+id/temporary"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="subst plan"
|
android:text="substitution plan"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"/>
|
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||||
|
|
||||||
|
|||||||
@@ -14,20 +14,14 @@
|
|||||||
android:layout_marginBottom="3dp"
|
android:layout_marginBottom="3dp"
|
||||||
app:cardElevation="2dp">
|
app:cardElevation="2dp">
|
||||||
|
|
||||||
<LinearLayout
|
<TextView
|
||||||
|
android:id="@+id/cardInfoText"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="@color/colorText"
|
||||||
<TextView
|
android:layout_marginStart="16dp"
|
||||||
android:id="@+id/cardInfoText"
|
android:layout_marginEnd="16dp"
|
||||||
android:layout_width="match_parent"
|
android:layout_marginTop="16dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_marginBottom="16dp"/>
|
||||||
android:textColor="@color/colorText"
|
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:layout_marginBottom="16dp"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</com.google.android.material.card.MaterialCardView>
|
</com.google.android.material.card.MaterialCardView>
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
<string name="setup_successful">Viel Spaß!</string>
|
<string name="setup_successful">Viel Spaß!</string>
|
||||||
<string name="greeting_title">Aktiviere Begrüßungen</string>
|
<string name="greeting_title">Aktiviere Begrüßungen</string>
|
||||||
<string name="greeting_desc">Falls du möchtest, dass ich nett bin :)</string>
|
<string name="greeting_desc">Falls du möchtest, dass ich nett bin :)</string>
|
||||||
<string name="licences_title">Lizenzen und Mitwirkende</string>
|
<string name="licences_title">Lizenzen & Mitwirkende</string>
|
||||||
<string name="licences_desc">Was die App ausmacht (Englisch)</string>
|
<string name="licences_desc">Was die App ausmacht (Englisch)</string>
|
||||||
<string name="version">Versionsnummer</string>
|
<string name="version">Versionsnummer</string>
|
||||||
<string name="privacy_policy_title">Datenschutzerklärung</string>
|
<string name="privacy_policy_title">Datenschutzerklärung</string>
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
<string name="apply">Anwenden</string>
|
<string name="apply">Anwenden</string>
|
||||||
<string name="invalid_code">Ungültiger Code</string>
|
<string name="invalid_code">Ungültiger Code</string>
|
||||||
<string name="experimental_menu_dialog_title">Experimentalmenü</string>
|
<string name="experimental_menu_dialog_title">Experimentalmenü</string>
|
||||||
<string name="diagnostics_dialog_title">Diagnosemenü</string>
|
<string name="statistics_dialog_title">Statistikmenü</string>
|
||||||
<string name="enable_course_notifications">Kursbenachrichtigungen aktivieren</string>
|
<string name="enable_course_notifications">Kursbenachrichtigungen aktivieren</string>
|
||||||
<string name="no_personal_substitutions">Kein Entfall für dich</string>
|
<string name="no_personal_substitutions">Kein Entfall für dich</string>
|
||||||
<string name="customise_colours_title">Benutzerdefinierte Farben</string>
|
<string name="customise_colours_title">Benutzerdefinierte Farben</string>
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
<string name="personal">Personal</string>
|
<string name="personal">Personal</string>
|
||||||
<string name="settings">Settings</string>
|
<string name="settings">Settings</string>
|
||||||
|
|
||||||
<!-- for Settings fragment -->
|
|
||||||
<string name="enable_course_notifications_title">Enable course notifications</string>
|
<string name="enable_course_notifications_title">Enable course notifications</string>
|
||||||
<string name="enable_course_notifications_desc">This does not affect broadcasts</string>
|
<string name="enable_course_notifications_desc">This does not affect broadcasts</string>
|
||||||
|
|
||||||
@@ -39,7 +38,7 @@
|
|||||||
<string name="greeting_title">Enable greeting</string>
|
<string name="greeting_title">Enable greeting</string>
|
||||||
<string name="greeting_desc">If you want me to be nice :)</string>
|
<string name="greeting_desc">If you want me to be nice :)</string>
|
||||||
|
|
||||||
<string name="licences_title">Licences and contributors</string>
|
<string name="licences_title">Licences & contributors</string>
|
||||||
<string name="licences_desc">What went into making this app</string>
|
<string name="licences_desc">What went into making this app</string>
|
||||||
<string name="version">Version Number</string>
|
<string name="version">Version Number</string>
|
||||||
|
|
||||||
@@ -59,7 +58,7 @@
|
|||||||
<string name="courses_help_dialog_title">How to enter your courses</string>
|
<string name="courses_help_dialog_title">How to enter your courses</string>
|
||||||
<string name="courses_help_dialog_text">You need to enter the course abbreviation for every course you want in your personal plan and want to be notified about. You can find them on your time table.\n\nHere\'s a few examples:\n\nMathematics in 5th grade (juniors) would be MAT.\n\nAdvanced English in E-Phase (seniors) for the English profile may be ENP1.\n\nBasic Biology in Q1 could be bio1.\n\nIn most cases, entering courses while in junior phase is redundant.\nSeparate multiple courses by spaces, commas are optional.\nCapitalisation is required.</string>
|
<string name="courses_help_dialog_text">You need to enter the course abbreviation for every course you want in your personal plan and want to be notified about. You can find them on your time table.\n\nHere\'s a few examples:\n\nMathematics in 5th grade (juniors) would be MAT.\n\nAdvanced English in E-Phase (seniors) for the English profile may be ENP1.\n\nBasic Biology in Q1 could be bio1.\n\nIn most cases, entering courses while in junior phase is redundant.\nSeparate multiple courses by spaces, commas are optional.\nCapitalisation is required.</string>
|
||||||
<string name="experimental_menu_dialog_title">Experimental Menu</string>
|
<string name="experimental_menu_dialog_title">Experimental Menu</string>
|
||||||
<string name="diagnostics_dialog_title">Diagnostics Menu</string>
|
<string name="statistics_dialog_title">Statistics Menu</string>
|
||||||
<string name="experimental_menu_dialog_text">This menu is currently intended for testing only. Additional features may be added in the future. Feel free to try arbitrary codes.</string>
|
<string name="experimental_menu_dialog_text">This menu is currently intended for testing only. Additional features may be added in the future. Feel free to try arbitrary codes.</string>
|
||||||
<string name="apply">Apply</string>
|
<string name="apply">Apply</string>
|
||||||
<string name="invalid_code">Invalid code</string>
|
<string name="invalid_code">Invalid code</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user