Food menu now splits up holiday messages; added documentation

This commit is contained in:
Deniz Düzgören
2019-10-01 10:38:41 +02:00
parent 56c7e8ba53
commit f6283c8221
7 changed files with 83 additions and 53 deletions
@@ -25,6 +25,7 @@ import com.denizd.substitutionplan.data.HelperFunctions
import com.denizd.substitutionplan.data.LoginWebViewClient
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
import com.google.android.material.snackbar.Snackbar
import java.lang.Exception
import kotlin.math.hypot
/**
@@ -80,7 +81,8 @@ internal class Login : AppCompatActivity(R.layout.activity_login_webview), Login
private fun success() {
prefs.edit().putBoolean("successful_login", true).apply()
val handler = Handler()
try {
val layoutAfterCircleReveal = findViewById<LinearLayout>(R.id.layoutAfterCircleReveal)
val x: Int = logInButton.right - logInButton.width / 2
@@ -88,7 +90,6 @@ internal class Login : AppCompatActivity(R.layout.activity_login_webview), Login
val endRadius = hypot(parentLayout.width.toDouble(), parentLayout.height.toDouble()).toInt()
View.inflate(this, R.layout.unlock_screen, layoutAfterCircleReveal)
val anim = ViewAnimationUtils.createCircularReveal(layoutAfterCircleReveal, x, y, 0F, endRadius.toFloat())
val handler = Handler()
val animOut = AnimationUtils.loadAnimation(this, R.anim.fade_out_short)
anim.duration = 600
val colour = findViewById<LinearLayout>(R.id.colourLayout)
@@ -115,10 +116,14 @@ internal class Login : AppCompatActivity(R.layout.activity_login_webview), Login
mImgCheck.start()
}
}, 600)
} catch (e: Exception) {
} finally {
handler.postDelayed({
val main = Intent(this, Main::class.java)
startActivity(main)
finish()
}, 3000)
}
}
}
@@ -86,8 +86,10 @@ internal class Main : AppCompatActivity(R.layout.app_bar_main) {
val contextView = findViewById<View>(R.id.coordination)
val window = this.window
/// Sets the theme explicitly to dismiss the splash screen
setTheme(R.style.AppTheme0)
/// Sets the system bar's colours according to the current Android version
val barColour = when {
Build.VERSION.SDK_INT < Build.VERSION_CODES.M -> ContextCompat.getColor(context, R.color.legacyBlack)
Build.VERSION.SDK_INT <= Build.VERSION_CODES.P -> ContextCompat.getColor(context, R.color.colorBackground)
@@ -98,6 +100,7 @@ internal class Main : AppCompatActivity(R.layout.app_bar_main) {
window.statusBarColor = barColour
}
/// Applies theming with additional workarounds for API levels 23-28 (M-P)
when (prefs.getInt("themeInt", 0)) {
0 -> {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
@@ -114,12 +117,18 @@ internal class Main : AppCompatActivity(R.layout.app_bar_main) {
}
}
/// Displays the date and time of the last refresh of the substitution plan in a snack bar
if (!prefs.getBoolean("autoRefresh", false) && prefs.getInt("firstTimeOpening", 0) != 0) {
try {
Snackbar.make(contextView, "${getString(R.string.last_updated)} ${prefs.getString("timeNew", "")}", Snackbar.LENGTH_LONG).show()
} catch (e: IllegalArgumentException) {}
}
/**
* Retrieves the greeting string if enabled by the user, sets it empty otherwise.
* Don't set the text view of the greeting string to View.GONE, as that will mess
* with the constraints
*/
val textViewGreeting = findViewById<TextView>(R.id.text_greeting)
textViewGreeting.text = if (prefs.getBoolean("greeting", true) && (prefs.getString("username", "") ?: "").isNotEmpty()) {
getGreetingString()
@@ -127,6 +136,7 @@ internal class Main : AppCompatActivity(R.layout.app_bar_main) {
""
}
/// Legacy function
if (prefs.getInt("firstTimeOpening", 0) == 0) {
edit.putInt("firstTimeOpening", prefs.getInt("firstTimeOpening", 0) + 1).apply()
}
@@ -143,6 +153,7 @@ internal class Main : AppCompatActivity(R.layout.app_bar_main) {
}
loadFragment(defaultFragment)
/// Opens the corresponding fragment or the info dialog
bottomNav.setOnNavigationItemSelectedListener { item: MenuItem ->
var fragmentLoading = true
lateinit var fragment: Fragment
@@ -176,6 +187,7 @@ internal class Main : AppCompatActivity(R.layout.app_bar_main) {
}
}
/// Scrolls to the top of any currently displayed fragment
bottomNav.setOnNavigationItemReselectedListener { item: MenuItem ->
when (item.itemId) {
R.id.plan, R.id.personal -> {
@@ -231,6 +243,10 @@ internal class Main : AppCompatActivity(R.layout.app_bar_main) {
}, prefs.getString("username", ""))
}
/**
* Retrieves the strings provided in the substitution plan's info boxes as well as the
* refresh date and time from Shared Preferences and displays them in a dialog
*/
private fun openInfoDialog() {
val dialog = AlertDialog.Builder(context)
val dialogView = View.inflate(context, R.layout.simple_dialog, null)
@@ -247,9 +263,7 @@ internal class Main : AppCompatActivity(R.layout.app_bar_main) {
return true
}
/**
* Triggers FBPingService.kt to re-subscribe to the selected Firebase topics every 15 minutes
*/
/// Triggers FBPingService.kt to re-subscribe to the selected Firebase topics every 15 minutes
private fun pingFirebaseTopics() {
val componentName = ComponentName(this, FBPingService::class.java)
val info = JobInfo.Builder(42, componentName)
@@ -30,6 +30,13 @@ import java.util.*
*/
internal class SubstitutionAdapter(private var substitutions: List<Substitution>, private val prefs: SharedPreferences) : RecyclerView.Adapter<SubstitutionAdapter.CardViewHolder>() {
/**
* The ViewHolder class used by SubstitutionAdapter.kt to resolve references to views in
* course_card.xml that will be inflated and populated with data in
* SubstitutionAdapter#onBindViewHolder
*
* @param view a reference to the xml that is to be inflated
*/
internal class CardViewHolder(view: View) : RecyclerView.ViewHolder(view), View.OnClickListener {
var iconView: ImageView = view.findViewById(R.id.iconView)
@@ -43,7 +50,9 @@ internal class SubstitutionAdapter(private var substitutions: List<Substitution>
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 {
@@ -77,14 +86,14 @@ internal class SubstitutionAdapter(private var substitutions: List<Substitution>
}
}
val add = currentItem.additional.toLowerCase(Locale.ROOT)
val add = currentItem.additional
val type = currentItem.type.toLowerCase(Locale.ROOT)
if (add.isNotEmpty()) {
if (HelperFunctions.checkStringForArray(add, HelperFunctions.cancellations)) {
if (HelperFunctions.checkStringForArray(add, HelperFunctions.cancellations, true)) {
strikeThrough(strings)
}
} else {
if (HelperFunctions.checkStringForArray(type, HelperFunctions.cancellations)) {
if (HelperFunctions.checkStringForArray(type, HelperFunctions.cancellations, true)) {
strikeThrough(strings)
}
}
@@ -161,6 +170,7 @@ internal class SubstitutionAdapter(private var substitutions: List<Substitution>
notifyDataSetChanged()
}
/// Strikes through the strings for course, room and teacher
private fun strikeThrough(strings: Array<SpannableString>) {
for (i in 2..4) { strings[i].setSpan(StrikethroughSpan(), 0, strings[i].length, 0) }
}
@@ -122,9 +122,9 @@ internal class DataFetcher(isPlan: Boolean, isMenu: Boolean, isJobService: Boole
foodRepository.deleteAll()
val indices = ArrayList<Int>()
val daysAndVon = arrayOf("Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "von")
val daysAndVon = arrayOf("montag", "dienstag", "mittwoch", "donnerstag", "freitag", "von", "wünschen")
for (i in 0 until foodElements.size) {
if (HelperFunctions.checkStringForArray(foodElements[i].text(), daysAndVon)) indices.add(i)
if (HelperFunctions.checkStringForArray(foodElements[i].text(), daysAndVon, true)) indices.add(i)
}
indices.add(foodElements.size)
@@ -47,8 +47,8 @@ internal object HelperFunctions {
"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
* A lowercased 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")
@@ -305,8 +305,9 @@ internal object HelperFunctions {
}
}
fun checkStringForArray(s: String, checking: Array<String>): Boolean {
checking.forEach { check ->
fun checkStringForArray(checkedString: String, checkingArray: Array<String>, lowerCased: Boolean): Boolean {
val s = if (lowerCased) checkedString.toLowerCase(Locale.ROOT) else checkedString
checkingArray.forEach { check ->
if (s.contains(check)) return true
}
return false
@@ -330,7 +331,7 @@ internal object HelperFunctions {
val a = group.substring(0, 2).toInt()
-a
}
checkStringForArray(group.substring(0, 1), juniors) -> -101
checkStringForArray(group.substring(0, 1), juniors, false) -> -101
else -> -100
}
} catch (e: Exception) {
@@ -2,7 +2,7 @@ package com.denizd.substitutionplan.data
/**
* Enum class for declaring Firebase Cloud Messaging topics without using the raw strings
* throughout the project
* throughout the project to avoid human error
*/
internal enum class Topic(val tag: String) {
ANDROID("substitutions-android"),
@@ -12,7 +12,7 @@ import com.google.firebase.messaging.FirebaseMessaging
* issues regarding the app being force-closed in the background and not being able to receive
* notifications.
*
* I am unsure about its effectiveness, though notifications do seem to arrive
* I am unsure about its effectiveness, though notifications do seem to arrive relatively reliably
*/
internal class FBPingService : JobService() {