Info table now recognises line breaks from the website and shows them in the dialog; implemented debug dialog that presents the most recent exception caused in DataFetcher.kt

This commit is contained in:
Deniz Düzgören
2019-10-18 21:25:54 +02:00
parent b332381342
commit 0c5f075fd0
5 changed files with 98 additions and 71 deletions
+2 -2
View File
@@ -10,8 +10,8 @@ android {
applicationId "com.denizd.substitutionplan"
minSdkVersion 21
targetSdkVersion 29
versionCode 41
versionName "2.3.3"
versionCode 42
versionName "2.3.4"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
@@ -86,10 +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
// 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
// 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)
@@ -100,7 +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)
// Applies theming with additional workarounds for API levels 23-28 (M-P)
when (prefs.getInt("themeInt", 0)) {
0 -> {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
@@ -113,7 +113,7 @@ internal class Main : AppCompatActivity(R.layout.app_bar_main) {
else -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
}
/// Displays the date and time of the last refresh of the substitution plan in a snack bar
// 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()
@@ -136,12 +136,12 @@ internal class Main : AppCompatActivity(R.layout.app_bar_main) {
""
}
/// Legacy function
// Legacy function
if (prefs.getInt("firstTimeOpening", 0) == 0) {
edit.putInt("firstTimeOpening", prefs.getInt("firstTimeOpening", 0) + 1).apply()
}
/// Launch the user-specified fragment (general or personal plan)
// Launch the user-specified fragment (general or personal plan)
val defaultFragment = if (prefs.getBoolean("defaultPersonalised", false)) {
bottomNav.selectedItemId = R.id.personal
toolbarTxt.text = personalPlanTitle()
@@ -153,7 +153,7 @@ internal class Main : AppCompatActivity(R.layout.app_bar_main) {
}
loadFragment(defaultFragment)
/// Opens the corresponding fragment or the info dialog
// Opens the corresponding fragment or the info dialog
bottomNav.setOnNavigationItemSelectedListener { item: MenuItem ->
val fragment = when (item.itemId) {
R.id.plan -> {
@@ -185,7 +185,7 @@ internal class Main : AppCompatActivity(R.layout.app_bar_main) {
}
}
/// Scrolls to the top of any currently displayed fragment
// Scrolls to the top of any currently displayed fragment
bottomNav.setOnNavigationItemReselectedListener { item: MenuItem ->
when (item.itemId) {
R.id.plan, R.id.personal, R.id.menu -> {
@@ -255,7 +255,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)
@@ -7,9 +7,12 @@ import android.media.RingtoneManager
import android.net.Uri
import android.os.AsyncTask
import android.os.Build
import android.util.Log
import androidx.preference.PreferenceManager
import android.view.View
import android.widget.RemoteViews
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import androidx.core.app.NotificationCompat
import androidx.core.content.ContextCompat
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
@@ -73,6 +76,8 @@ internal class DataFetcher(
if (prefs.getBoolean("testUrls", false)) {
substUrl = "https://djd4rkn355.github.io/subst_test.html"
foodUrl = "https://djd4rkn355.github.io/food_test.html"
} else if ((prefs.getString("custom_test_url", "") ?: "").isNotEmpty()) {
substUrl = "https://djd4rkn355.github.io/${prefs.getString("custom_test_url", "")}"
}
if (forceRefresh) {
@@ -99,13 +104,13 @@ internal class DataFetcher(
}
}
} catch (e: Exception) {
e.printStackTrace()
mView.get()?.let { v: View ->
val snackBarView = v.findViewById<View>(R.id.coordination)
Snackbar.make(snackBarView, mContext.get()?.getString(R.string.no_internet_connection) ?: "", Snackbar.LENGTH_LONG).setBackgroundTint(ContextCompat.getColor(mContext.get()!!,
R.color.colorError
)).show()
}
prefs.edit().putString("debug_recent_exception", Log.getStackTraceString(e)).apply()
}
return null
}
@@ -157,7 +162,7 @@ internal class DataFetcher(
val substRepo = SubstRepository(mApplication)
if (currentTime != prefs.getString("timeNew", "")) {
val rows = doc.select("tr")
val paragraphs = doc.select("p")
val paragraphs = doc.select("h6")
val substArray = ArrayList<Substitution>()
val coursePreference = prefs.getString("courses", "") ?: ""
@@ -165,9 +170,9 @@ internal class DataFetcher(
for (i in 0 until paragraphs.size) {
if (i == 0) {
informational = paragraphs[i].text()
informational = formatElement(paragraphs[i].html())
} else {
informational += "\n\n" + paragraphs[i].text()
informational += "\n\n" + formatElement(paragraphs[i].html())
}
}
edit.putString("informational", informational).apply()
@@ -189,7 +194,7 @@ internal class DataFetcher(
additional = cols[5].text(),
teacher = cols[6].text(),
type = cols[7].text(),
priority = HelperFunctions.assignRanking(group, date.substring(0, 3) == "psa"),
priority = HelperFunctions.assignRanking(group, (date.length > 2 && date.substring(0, 3) == "psa")),
date_priority = HelperFunctions.assignDatePriority(date),
website_priority = websitePriority
)
@@ -268,4 +273,9 @@ internal class DataFetcher(
manager.notify(1, notification.build())
}
}
private fun formatElement(element: String): String {
return element
.replace("<br>", "\n")
}
}
@@ -414,68 +414,83 @@ internal class SettingsFragment : Fragment(), View.OnClickListener, View.OnLongC
R.string.experimental_menu_dialog_text
)
dialogButton.setOnClickListener {
when (dialogEditText.text.toString()) {
"_statistics" -> {
val alertDialogDev = AlertDialog.Builder(mContext)
val devDialogView = View.inflate(mContext, R.layout.diagnostics_dialog, null)
val devDialogText = devDialogView.findViewById<TextView>(R.id.dialogtext)
val resetLaunchBtn = devDialogView.findViewById<MaterialButton>(R.id.btnResetLaunch)
val resetNotificationBtn = devDialogView.findViewById<MaterialButton>(R.id.btnResetNotif)
with (dialogEditText.text.toString()) {
when {
this == "_statistics" -> {
val alertDialogDev = AlertDialog.Builder(mContext)
val devDialogView = View.inflate(mContext, R.layout.diagnostics_dialog, null)
val devDialogText = devDialogView.findViewById<TextView>(R.id.dialogtext)
val resetLaunchBtn = devDialogView.findViewById<MaterialButton>(R.id.btnResetLaunch)
val resetNotificationBtn = devDialogView.findViewById<MaterialButton>(R.id.btnResetNotif)
devDialogView.findViewById<TextView>(R.id.textviewtitle).text = getString(R.string.statistics_dialog_title)
devDialogText.text = getDiagnosticsText()
resetLaunchBtn.setOnClickListener {
prefs.edit().putInt("launchDev", 0).apply()
devDialogView.findViewById<TextView>(R.id.textviewtitle).text = getString(R.string.statistics_dialog_title)
devDialogText.text = getDiagnosticsText()
}
resetNotificationBtn.setOnClickListener {
prefs.edit().putInt("pingFB", 0).apply()
devDialogText.text = getDiagnosticsText()
}
resetLaunchBtn.setOnClickListener {
prefs.edit().putInt("launchDev", 0).apply()
devDialogText.text = getDiagnosticsText()
}
alertDialogDev.setView(devDialogView)
alertDialogDev.show()
}
"_login" -> {
prefs.edit().putBoolean("successful_login", false).apply()
makeToast("Login flag cleared")
}
"_firsttime" -> {
prefs.edit().putBoolean("firstTime", true).apply()
makeToast("First time flag cleared")
}
"_testurls" -> {
val currentTest = !prefs.getBoolean("testUrls", false)
prefs.edit().putBoolean("testUrls", currentTest).apply()
makeToast("Test URLs set to $currentTest")
}
"_devchannel" -> {
val subbed = if (prefs.getBoolean("subscribedToFBDebugChannel", false)) {
unsubscribeFromTopic(Topic.DEVELOPMENT)
"Unsubscribed from"
} else {
subscribeToTopic(Topic.DEVELOPMENT)
"Subscribed to"
resetNotificationBtn.setOnClickListener {
prefs.edit().putInt("pingFB", 0).apply()
devDialogText.text = getDiagnosticsText()
}
alertDialogDev.setView(devDialogView)
alertDialogDev.show()
}
prefs.edit().putBoolean("subscribedToFBDebugChannel", !prefs.getBoolean("subscribedToFBDebugChannel", false)).apply()
makeToast("$subbed Firebase development channel")
}
"_ioschannel" -> {
val subbed = if (prefs.getBoolean("subscribedToiOSChannel", false)) {
unsubscribeFromTopic(Topic.IOS)
"Unsubscribed from"
} else {
subscribeToTopic(Topic.IOS)
"Subscribed to"
this == "_login" -> {
prefs.edit().putBoolean("successful_login", false).apply()
makeToast("Login flag cleared")
}
prefs.edit().putBoolean("subscribedToiOSChannel", !prefs.getBoolean("subscribedToiOSChannel", false)).apply()
makeToast("$subbed iOS channel")
this == "_firsttime" -> {
prefs.edit().putBoolean("firstTime", true).apply()
makeToast("First time flag cleared")
}
this == "_testurls" -> {
val currentTest = !prefs.getBoolean("testUrls", false)
prefs.edit().putBoolean("testUrls", currentTest)
.putString("custom_test_url", "").apply()
makeToast("Cleared custom URL")
makeToast("Test URLs set to $currentTest")
}
length > 4 && substring(0, 4) == "_url" -> {
prefs.edit().putString("custom_test_url", substring(4, length)).apply()
makeToast("Successfully entered custom URL")
}
length == 4 && substring(0, 4) == "_url" -> {
prefs.edit().putString("custom_test_url", "").apply()
makeToast("Cleared custom URL")
}
this == "_devchannel" -> {
val subbed = if (prefs.getBoolean("subscribedToFBDebugChannel", false)) {
unsubscribeFromTopic(Topic.DEVELOPMENT)
"Unsubscribed from"
} else {
subscribeToTopic(Topic.DEVELOPMENT)
"Subscribed to"
}
prefs.edit().putBoolean("subscribedToFBDebugChannel", !prefs.getBoolean("subscribedToFBDebugChannel", false)).apply()
makeToast("$subbed Firebase development channel")
}
this == "_ioschannel" -> {
val subbed = if (prefs.getBoolean("subscribedToiOSChannel", false)) {
unsubscribeFromTopic(Topic.IOS)
"Unsubscribed from"
} else {
subscribeToTopic(Topic.IOS)
"Subscribed to"
}
prefs.edit().putBoolean("subscribedToiOSChannel", !prefs.getBoolean("subscribedToiOSChannel", false)).apply()
makeToast("$subbed iOS channel")
}
this == "_viewstacktrace" -> {
createDialog("Debug Stack Trace", prefs.getString("debug_recent_exception", "") ?: "")
}
this == "_write" -> HelperFunctions.writePrefsToXml(prefs, mContext, activity!!)
this == "_read" -> HelperFunctions.readPrefsFromXml(prefs, mContext, activity!!)
else -> makeToast(getString(R.string.invalid_code))
}
"_write" -> HelperFunctions.writePrefsToXml(prefs, mContext, activity!!)
"_read" -> HelperFunctions.readPrefsFromXml(prefs, mContext, activity!!)
else -> makeToast(getString(R.string.invalid_code))
}
}
alertDialog.setView(dialogView)
+2
View File
@@ -33,4 +33,6 @@
<item name="dialogCornerRadius">12dp</item>
</style>
<style name="AppTheme0.LegacyAlert" parent="Theme.AppCompat.Dialog.Alert"/>
</resources>