Refactoring, using view binding in all fragments, app now targets API 29, replaced deprecated support library PreferenceManager and Custom Tabs with AndroidX equivalents, version bump to 2.3.3

This commit is contained in:
Deniz Düzgören
2019-10-12 21:03:34 +02:00
parent f5666a20c6
commit 37cf130ba0
27 changed files with 827 additions and 801 deletions
+3
View File
@@ -1,8 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings"> <component name="GradleSettings">
<option name="linkedExternalProjectsSettings"> <option name="linkedExternalProjectsSettings">
<GradleProjectSettings> <GradleProjectSettings>
<option name="delegatedBuild" value="false" />
<option name="testRunner" value="PLATFORM" />
<option name="distributionType" value="DEFAULT_WRAPPED" /> <option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" /> <option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules"> <option name="modules">
+12 -9
View File
@@ -1,17 +1,17 @@
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt' apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'io.fabric' apply plugin: 'io.fabric'
android { android {
compileSdkVersion 28 compileSdkVersion 29
defaultConfig { defaultConfig {
applicationId "com.denizd.substitutionplan" applicationId "com.denizd.substitutionplan"
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 28 targetSdkVersion 29
versionCode 40 versionCode 40
versionName "2.3.2" versionName "2.3.3"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
buildTypes { buildTypes {
@@ -21,16 +21,19 @@ android {
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
} }
} }
viewBinding.enabled = true
} }
dependencies { dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs') implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta2' implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.cardview:cardview:1.0.0' implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.recyclerview:recyclerview:1.1.0-beta04' implementation 'androidx.recyclerview:recyclerview:1.1.0-beta05'
implementation 'com.google.android.material:material:1.1.0-alpha10' implementation 'androidx.browser:browser:1.0.0'
implementation 'com.android.support:customtabs:28.0.0' implementation 'androidx.preference:preference-ktx:1.1.0'
implementation 'com.google.android.material:material:1.1.0-beta01'
implementation 'com.google.firebase:firebase-core:17.2.0' implementation 'com.google.firebase:firebase-core:17.2.0'
implementation 'com.google.firebase:firebase-messaging:20.0.0' implementation 'com.google.firebase:firebase-messaging:20.0.0'
@@ -41,7 +44,7 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
def lifecycle_version = "2.0.0" def lifecycle_version = "2.0.0"
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version" implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version" kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
def room_version = "2.1.0-alpha04" def room_version = "2.1.0-alpha04"
implementation "androidx.room:room-runtime:$room_version" implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version" kapt "androidx.room:room-compiler:$room_version"
@@ -8,7 +8,7 @@ import android.graphics.drawable.AnimatedVectorDrawable
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.preference.PreferenceManager import androidx.preference.PreferenceManager
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewAnimationUtils import android.view.ViewAnimationUtils
@@ -50,11 +50,11 @@ internal class FirstTime : AppCompatActivity(R.layout.activity_first_time) {
val edit = prefs.edit() val edit = prefs.edit()
val fab = findViewById<ExtendedFloatingActionButton>(R.id.efab) val fab = findViewById<ExtendedFloatingActionButton>(R.id.efab)
val mainActivity = Intent(this, Main::class.java) val mainActivity = Intent(this, Main::class.java)
val nameEditText = findViewById<TextInputEditText>(R.id.txtName) val nameEditText = findViewById<TextInputEditText>(R.id.edittext_name)
val gradeEditText = findViewById<TextInputEditText>(R.id.txtClasses) val gradeEditText = findViewById<TextInputEditText>(R.id.edittext_group)
val courseEditText = findViewById<TextInputEditText>(R.id.txtCourses) val courseEditText = findViewById<TextInputEditText>(R.id.edittext_courses)
val helpGradeButton = findViewById<ImageButton>(R.id.chipHelpClasses) val helpGradeButton = findViewById<ImageButton>(R.id.button_group_help)
val helpCoursesButton = findViewById<ImageButton>(R.id.chipHelpCourses) val helpCoursesButton = findViewById<ImageButton>(R.id.button_courses_help)
val greetingCheckBox = findViewById<CheckBox>(R.id.cbGreetings) val greetingCheckBox = findViewById<CheckBox>(R.id.cbGreetings)
val notificationCheckBox = findViewById<CheckBox>(R.id.cbNotif) val notificationCheckBox = findViewById<CheckBox>(R.id.cbNotif)
val darkModeCheckBox = findViewById<CheckBox>(R.id.cbDark) val darkModeCheckBox = findViewById<CheckBox>(R.id.cbDark)
@@ -7,7 +7,7 @@ import android.graphics.drawable.AnimatedVectorDrawable
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.preference.PreferenceManager import androidx.preference.PreferenceManager
import android.view.View import android.view.View
import android.view.ViewAnimationUtils import android.view.ViewAnimationUtils
import android.view.animation.Animation import android.view.animation.Animation
@@ -9,7 +9,7 @@ import android.content.Intent
import android.content.SharedPreferences import android.content.SharedPreferences
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.preference.PreferenceManager import androidx.preference.PreferenceManager
import android.view.* import android.view.*
import android.widget.TextView import android.widget.TextView
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
@@ -20,7 +20,6 @@ import androidx.core.widget.NestedScrollView
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentTransaction import androidx.fragment.app.FragmentTransaction
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.crashlytics.android.Crashlytics
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.fragments.FoodFragment import com.denizd.substitutionplan.fragments.FoodFragment
@@ -33,6 +32,7 @@ import com.google.android.material.bottomnavigation.BottomNavigationView
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import com.google.firebase.FirebaseApp import com.google.firebase.FirebaseApp
import java.lang.IllegalArgumentException import java.lang.IllegalArgumentException
import java.lang.NullPointerException
import java.util.* import java.util.*
/** /**
@@ -49,173 +49,166 @@ internal class Main : AppCompatActivity(R.layout.app_bar_main) {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
context = this context = this
// prefs = PreferenceManager.getDefaultSharedPreferences(context)
prefs = PreferenceManager.getDefaultSharedPreferences(context) prefs = PreferenceManager.getDefaultSharedPreferences(context)
val edit = prefs.edit() val edit = prefs.edit()
val firstTime = Intent(context, FirstTime::class.java)
val login = Intent(context, Login::class.java)
Crashlytics.setUserIdentifier(prefs.getString("username", "") ?: "")
/** /**
* This cascade of if-else's allows the user to return to any point of the setup if they * This when-cascade allows the user to return to any point of the setup if they
* decide to postpone it, e.g. logging in but not setting up their preferences. Furthermore, * decide to postpone it, e.g. logging in but not setting up their preferences. Furthermore,
* it prevents existing users from upgrading from a previous version of the app and skip the * it prevents existing users from upgrading from a previous version of the app and skip the
* mandatory login * mandatory login
*/ */
if (!prefs.getBoolean("successful_login", false)) { when {
startActivity(login) !prefs.getBoolean("successful_login", false) -> { // launch the login screen
finish() startActivity(Intent(context, Login::class.java))
} else if (prefs.getBoolean("firstTime", true)) { finish()
startActivity(firstTime)
finish()
} else {
if (!prefs.getBoolean("colourTransferred", false)) {
HelperFunctions.transferOldColourIntsToString(prefs)
edit.putBoolean("colourTransferred", true).apply()
} }
prefs.getBoolean("firstTime", true) -> { // launch the first time setup screen
edit.putInt("launchDev", prefs.getInt("launchDev", 0) + 1) startActivity(Intent(context, FirstTime::class.java))
edit.apply() finish()
FirebaseApp.initializeApp(this)
pingFirebaseTopics()
val appBarLayout = findViewById<AppBarLayout>(R.id.appbarlayout)
val toolbarTxt = findViewById<TextView>(R.id.toolbarTxt)
val bottomNav = findViewById<BottomNavigationView>(R.id.bottom_nav)
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)
else -> 0
}
if (barColour != 0) {
window.navigationBarColor = barColour
window.statusBarColor = barColour
} }
else -> { // launch the app
/// Applies theming with additional workarounds for API levels 23-28 (M-P) if (!prefs.getBoolean("colourTransferred", false)) {
when (prefs.getInt("themeInt", 0)) { HelperFunctions.transferOldColourIntsToString(prefs)
0 -> { edit.putBoolean("colourTransferred", true).apply()
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO) }
if (Build.VERSION.SDK_INT in 23..28) {
@SuppressLint("InlinedApi") edit.putInt("launchDev", prefs.getInt("launchDev", 0) + 1)
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR edit.apply()
FirebaseApp.initializeApp(this)
pingFirebaseTopics()
val appBarLayout = findViewById<AppBarLayout>(R.id.appbarlayout)
val toolbarTxt = findViewById<TextView>(R.id.toolbarTxt)
val bottomNav = findViewById<BottomNavigationView>(R.id.bottom_nav)
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)
else -> 0
}
if (barColour != 0) {
window.navigationBarColor = barColour
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)
if (Build.VERSION.SDK_INT in 23..28) {
@SuppressLint("InlinedApi")
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
}
}
2 -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
else -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
}
/// 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) {
} }
} }
2 -> {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
}
else -> {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
}
}
/// 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) { * Retrieves the greeting string if enabled by the user, sets it empty otherwise.
try { * Don't set the text view of the greeting string to View.GONE, as that will mess
Snackbar.make(contextView, "${getString(R.string.last_updated)} ${prefs.getString("timeNew", "")}", Snackbar.LENGTH_LONG).show() * with the constraints
} catch (e: IllegalArgumentException) {} */
} val textViewGreeting = findViewById<TextView>(R.id.text_greeting)
textViewGreeting.text = if (
/** prefs.getBoolean("greeting", true)
* Retrieves the greeting string if enabled by the user, sets it empty otherwise. && (prefs.getString("username", "") ?: "").isNotEmpty()
* Don't set the text view of the greeting string to View.GONE, as that will mess ) {
* with the constraints getGreetingString()
*/
val textViewGreeting = findViewById<TextView>(R.id.text_greeting)
textViewGreeting.text = if (prefs.getBoolean("greeting", true) && (prefs.getString("username", "") ?: "").isNotEmpty()) {
getGreetingString()
} else {
""
}
/// 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)
val defaultFragment = if (prefs.getBoolean("defaultPersonalised", false)) {
bottomNav.selectedItemId = R.id.personal
toolbarTxt.text = personalPlanTitle()
PersonalPlanFragment()
} else {
bottomNav.selectedItemId = R.id.plan
toolbarTxt.text = getString(R.string.app_name)
GeneralPlanFragment()
}
loadFragment(defaultFragment)
/// Opens the corresponding fragment or the info dialog
bottomNav.setOnNavigationItemSelectedListener { item: MenuItem ->
var fragmentLoading = true
lateinit var fragment: Fragment
when (item.itemId) {
R.id.plan -> {
fragment = GeneralPlanFragment()
toolbarTxt.text = getString(R.string.app_name)
}
R.id.personal -> {
fragment = PersonalPlanFragment()
toolbarTxt.text = personalPlanTitle()
}
R.id.menu -> {
fragment = FoodFragment()
toolbarTxt.text = getString(R.string.food_menu)
}
R.id.openinfopanel -> {
openInfoDialog()
fragmentLoading = false
}
R.id.settings -> {
fragment = SettingsFragment()
toolbarTxt.text = getString(R.string.settings)
}
}
if (fragmentLoading) {
appBarLayout.setExpanded(true)
loadFragment(fragment)
} else { } else {
false ""
} }
}
/// Scrolls to the top of any currently displayed fragment /// Legacy function
bottomNav.setOnNavigationItemReselectedListener { item: MenuItem -> if (prefs.getInt("firstTimeOpening", 0) == 0) {
when (item.itemId) { edit.putInt("firstTimeOpening", prefs.getInt("firstTimeOpening", 0) + 1).apply()
R.id.plan, R.id.personal -> { }
try {
val recyclerView = findViewById<RecyclerView>(R.id.linearRecycler) /// Launch the user-specified fragment (general or personal plan)
recyclerView.post { val defaultFragment = if (prefs.getBoolean("defaultPersonalised", false)) {
recyclerView.smoothScrollToPosition(0) bottomNav.selectedItemId = R.id.personal
} toolbarTxt.text = personalPlanTitle()
appBarLayout.setExpanded(true) PersonalPlanFragment()
} catch (e: NullPointerException) {} } else {
bottomNav.selectedItemId = R.id.plan
toolbarTxt.text = getString(R.string.app_name)
GeneralPlanFragment()
}
loadFragment(defaultFragment)
/// Opens the corresponding fragment or the info dialog
bottomNav.setOnNavigationItemSelectedListener { item: MenuItem ->
val fragment = when (item.itemId) {
R.id.plan -> {
toolbarTxt.text = getString(R.string.app_name)
GeneralPlanFragment()
}
R.id.personal -> {
toolbarTxt.text = personalPlanTitle()
PersonalPlanFragment()
}
R.id.menu -> {
toolbarTxt.text = getString(R.string.food_menu)
FoodFragment()
}
R.id.openinfopanel -> {
openInfoDialog()
null
}
else -> {
toolbarTxt.text = getString(R.string.settings)
SettingsFragment()
}
} }
R.id.menu -> { if (fragment == null) {
try { false
val recyclerView = findViewById<RecyclerView>(R.id.linear_food) } else {
recyclerView.post { appBarLayout.setExpanded(true)
recyclerView.smoothScrollToPosition(0) loadFragment(fragment)
}
appBarLayout.setExpanded(true)
} catch (e: NullPointerException) {}
} }
R.id.settings -> { }
try {
val nsv = findViewById<NestedScrollView>(R.id.nsvsettings) /// Scrolls to the top of any currently displayed fragment
nsv.post { bottomNav.setOnNavigationItemReselectedListener { item: MenuItem ->
nsv.smoothScrollTo(0, 0) when (item.itemId) {
R.id.plan, R.id.personal, R.id.menu -> {
try {
val recyclerView = findViewById<RecyclerView>(R.id.recycler_view)
recyclerView.post {
recyclerView.smoothScrollToPosition(0)
}
appBarLayout.setExpanded(true)
} catch (e: NullPointerException) {
} }
appBarLayout.setExpanded(true) }
} catch (e: NullPointerException) {} R.id.settings -> {
try {
val nsv = findViewById<NestedScrollView>(R.id.settings_scroll_view)
nsv.post {
nsv.smoothScrollTo(0, 0)
}
appBarLayout.setExpanded(true)
} catch (e: NullPointerException) {
}
}
} }
} }
} }
@@ -18,16 +18,16 @@ import com.google.android.material.card.MaterialCardView
* @param colours a list of all courses and their associated colour * @param colours a list of all courses and their associated colour
* @param onClickListener a reference to an OnClickListener * @param onClickListener a reference to an OnClickListener
*/ */
internal class ColourAdapter(private var colours: List<Colour>, private val onClickListener: OnClickListener) : RecyclerView.Adapter<ColourAdapter.ColourViewHolder>() { internal class ColourAdapter(private var colours: List<Colour>, private val onClickListener: OnColourClickListener) : RecyclerView.Adapter<ColourAdapter.ColourViewHolder>() {
internal class ColourViewHolder(view: View, private val clickListener: OnClickListener) : RecyclerView.ViewHolder(view), View.OnClickListener { internal class ColourViewHolder(view: View, private val clickListener: OnColourClickListener) : 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) var titleNoLang: String = ""
val cardView: MaterialCardView = view.findViewById(R.id.cardView) val cardView: MaterialCardView = view.findViewById(R.id.cardView)
init { view.setOnClickListener(this) } init { view.setOnClickListener(this) }
override fun onClick(v: View?) { clickListener.onClick(adapterPosition, title.text.toString(), titleNoLang.text.toString()) } override fun onClick(v: View?) { clickListener.onColourClick(adapterPosition, title.text.toString(), titleNoLang) }
} }
@@ -40,7 +40,7 @@ internal class ColourAdapter(private var colours: List<Colour>, private val onCl
val currentItem = colours[position] val currentItem = colours[position]
holder.title.text = currentItem.title holder.title.text = currentItem.title
holder.titleNoLang.text = currentItem.titleNoLang holder.titleNoLang = currentItem.titleNoLang
holder.image.setImageDrawable(ContextCompat.getDrawable(holder.image.context, currentItem.icon)) holder.image.setImageDrawable(ContextCompat.getDrawable(holder.image.context, currentItem.icon))
val colour = if (currentItem.colour != 0) { val colour = if (currentItem.colour != 0) {
currentItem.colour currentItem.colour
@@ -60,7 +60,7 @@ internal class ColourAdapter(private var colours: List<Colour>, private val onCl
override fun getItemCount(): Int = colours.size override fun getItemCount(): Int = colours.size
internal interface OnClickListener { internal interface OnColourClickListener {
fun onClick(position: Int, title: String, titleNoLang: String) fun onColourClick(position: Int, title: String, titleNoLang: String)
} }
} }
@@ -3,6 +3,7 @@ package com.denizd.substitutionplan.adapters
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
@@ -17,15 +18,16 @@ import com.google.android.material.card.MaterialCardView
* @param ringtones a list of all ringtones including their URI * @param ringtones a list of all ringtones including their URI
* @param onClickListener a reference to an OnClickListener to set the ringtone * @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>() { internal class RingtoneAdapter(private val ringtones: List<Ringtone>, private val onClickListener: OnRingtoneClickListener) : RecyclerView.Adapter<RingtoneAdapter.RingtoneViewHolder>() {
internal class RingtoneViewHolder(view: View, private val clickListener: OnClickListener) : RecyclerView.ViewHolder(view), View.OnClickListener { internal class RingtoneViewHolder(view: View, private val clickListener: OnRingtoneClickListener) : 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 imageView: ImageView = view.findViewById(R.id.item_image)
var uri: String = ""
val cardView: MaterialCardView = view.findViewById(R.id.cardView) val cardView: MaterialCardView = view.findViewById(R.id.cardView)
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) }
} }
@@ -38,13 +40,14 @@ internal class RingtoneAdapter(private val ringtones: List<Ringtone>, private va
val currentItem = ringtones[position] val currentItem = ringtones[position]
holder.name.text = currentItem.name holder.name.text = currentItem.name
holder.uri.text = currentItem.uri holder.imageView.visibility = View.GONE
holder.cardView.setCardBackgroundColor(ContextCompat.getColor(holder.cardView.context, R.color.colorBackground)) holder.uri = currentItem.uri
holder.cardView.setCardBackgroundColor(ContextCompat.getColor(holder.cardView.context, R.color.colorBackgroundLight))
} }
override fun getItemCount(): Int = ringtones.size override fun getItemCount(): Int = ringtones.size
internal interface OnClickListener { internal interface OnRingtoneClickListener {
fun onRingtoneClick(position: Int, name: String, uri: String) fun onRingtoneClick(position: Int, name: String, uri: String)
} }
} }
@@ -7,7 +7,7 @@ import android.media.RingtoneManager
import android.net.Uri import android.net.Uri
import android.os.AsyncTask import android.os.AsyncTask
import android.os.Build import android.os.Build
import android.preference.PreferenceManager import androidx.preference.PreferenceManager
import android.view.View import android.view.View
import android.widget.RemoteViews import android.widget.RemoteViews
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
@@ -33,14 +33,22 @@ import kotlin.collections.ArrayList
* @param isPlan substitution plan will be downloaded and persisted in the database if true * @param isPlan substitution plan will be downloaded and persisted in the database if true
* @param isMenu food menu will be downloaded and persisted in the database if true * @param isMenu food menu will be downloaded and persisted in the database if true
* @param isJobService enables sending of a notification if true * @param isJobService enables sending of a notification if true
* @param forced if true, times for food menu and substitution table will be overwritten
* with empty values to enable a forced refresh
* @param context the context of the application that will be stored as a WeakReference * @param context the context of the application that will be stored as a WeakReference
* to avoid memory leakage * to avoid memory leakage
* @param application a reference to the application that will be stored as a WeakReference * @param application a reference to the application that will be stored as a WeakReference
* @param parentView a reference to the parent view that will be stored as a WeakReference * @param parentView a reference to the parent view that will be stored as a WeakReference
* @param forced if true, times for food menu and substitution table will be overwritten
* with empty values to enable a forced refresh
*/ */
internal class DataFetcher(isPlan: Boolean, isMenu: Boolean, isJobService: Boolean, context: Context, application: Application, parentView: View?, forced: Boolean) : AsyncTask<Void, Void, Void>() { internal class DataFetcher(
isPlan: Boolean,
isMenu: Boolean,
isJobService: Boolean = false,
forced: Boolean = false,
context: Context,
application: Application,
parentView: View?
) : AsyncTask<Void, Void, Void>() {
private var jobService = isJobService private var jobService = isJobService
private var plan = isPlan private var plan = isPlan
@@ -105,7 +113,7 @@ internal class DataFetcher(isPlan: Boolean, isMenu: Boolean, isJobService: Boole
override fun onPostExecute(result: Void?) { override fun onPostExecute(result: Void?) {
mView.get()?.let { mView.get()?.let {
try { try {
it.findViewById<SwipeRefreshLayout>(R.id.pullToRefresh).isRefreshing = false it.findViewById<SwipeRefreshLayout>(R.id.swipe_refresh_layout).isRefreshing = false
} catch (ignored: Exception) { } catch (ignored: Exception) {
} }
} }
@@ -47,7 +47,7 @@ internal object HelperFunctions {
"lavender", "carnation", "brown2", "pureBlack") "lavender", "carnation", "brown2", "pureBlack")
/** /**
* A lowercased list of all phrases used to describe that a course has been cancelled. Expand * A lower-cased 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 * 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") val cancellations = arrayOf("eigenverantwortliches arbeiten", "entfall", "entfällt", "fällt aus", "freisetzung", "vtr. ohne lehrer")
@@ -80,6 +80,7 @@ internal object HelperFunctions {
R.color.bgBrown2, R.color.bgBrown2,
R.color.bgPureBlack R.color.bgPureBlack
) )
const val notificationChannelId = "general" const val notificationChannelId = "general"
fun getColourForString(name: String): Int { fun getColourForString(name: String): Int {
@@ -314,8 +315,8 @@ internal object HelperFunctions {
} }
/** /**
* Assigns an integer to a given group used to sort the substitution plan in SQL. * Assigns an integer to a given group used to sort the substitution plan when retrieving from
* The ranking is stored as 'priority' in the database * Room database. The ranking is stored as 'priority' in the database
* *
* @param group the group string that should be assigned a ranking * @param group the group string that should be assigned a ranking
* @param isPSA used to determine a PSA, assigns lowest value if true, therefore putting * @param isPSA used to determine a PSA, assigns lowest value if true, therefore putting
@@ -377,7 +378,7 @@ internal object HelperFunctions {
private fun getPrefValue(prefs: SharedPreferences, type: String, key: String): Any { private fun getPrefValue(prefs: SharedPreferences, type: String, key: String): Any {
return when (type) { return when (type) {
"string" -> prefs.getString(key, "") "string" -> prefs.getString(key, "") ?: ""
"int" -> prefs.getInt(key, 0) "int" -> prefs.getInt(key, 0)
"bool" -> prefs.getBoolean(key, false) "bool" -> prefs.getBoolean(key, false)
else -> "" else -> ""
@@ -404,6 +405,8 @@ internal object HelperFunctions {
localPrefKeys.add("card${languageIndependentCourses[i]}") localPrefKeys.add("card${languageIndependentCourses[i]}")
localPrefTypes.add("string") localPrefTypes.add("string")
} }
// if bothered, replace this with an API 29-friendly solution
// if not, who cares really, this is not even accessible without special codes
val dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS) val dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS)
val file = File(dir, "avh_plan_data.xml") val file = File(dir, "avh_plan_data.xml")
val out = OutputStreamWriter(FileOutputStream(file, false)) val out = OutputStreamWriter(FileOutputStream(file, false))
@@ -414,9 +417,11 @@ internal object HelperFunctions {
"\n\t<value>${getPrefValue(prefs, localPrefTypes[i], localPrefKeys[i])}</value>" "\n\t<value>${getPrefValue(prefs, localPrefTypes[i], localPrefKeys[i])}</value>"
} }
input += "\n</items>" input += "\n</items>"
out.write(input) out.apply {
out.flush() write(input)
out.close() flush()
close()
}
Toast.makeText(context, context.getString(R.string.success), Toast.LENGTH_LONG).show() Toast.makeText(context, context.getString(R.string.success), Toast.LENGTH_LONG).show()
} else { } else {
Toast.makeText(context, context.getString(R.string.permission_denied), Toast.LENGTH_LONG).show() Toast.makeText(context, context.getString(R.string.permission_denied), Toast.LENGTH_LONG).show()
@@ -8,7 +8,7 @@ import android.webkit.WebViewClient
import java.lang.IllegalStateException 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 website's cookies to
* verify a login * verify a login
* *
* @param successListener a reference to the OnLoginSuccessListener implemented in an activity * @param successListener a reference to the OnLoginSuccessListener implemented in an activity
@@ -26,8 +26,7 @@ internal class FoodViewModel(application: Application) : AndroidViewModel(applic
isJobService = false, isJobService = false,
context = app, context = app,
application = app, application = app,
parentView = rootView, parentView = rootView
forced = false
).execute() ).execute()
} }
} }
@@ -28,8 +28,7 @@ internal class SubstViewModel(application: Application) : AndroidViewModel(appli
isJobService = false, isJobService = false,
context = app, context = app,
application = app, application = app,
parentView = rootView, parentView = rootView
forced = false
).execute() ).execute()
} }
} }
@@ -3,42 +3,48 @@ package com.denizd.substitutionplan.fragments
import android.content.Context import android.content.Context
import android.content.SharedPreferences import android.content.SharedPreferences
import android.os.Bundle import android.os.Bundle
import android.preference.PreferenceManager import androidx.preference.PreferenceManager
import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders import androidx.lifecycle.ViewModelProviders
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.denizd.substitutionplan.*
import com.denizd.substitutionplan.adapters.FoodAdapter import com.denizd.substitutionplan.adapters.FoodAdapter
import com.denizd.substitutionplan.database.FoodViewModel import com.denizd.substitutionplan.database.FoodViewModel
import com.denizd.substitutionplan.databinding.FoodLayoutBinding
import com.denizd.substitutionplan.models.Food import com.denizd.substitutionplan.models.Food
internal class FoodFragment : Fragment(R.layout.food_layout) { internal class FoodFragment : Fragment() {
private val foodArrayList = ArrayList<Food>() private val foodArrayList = ArrayList<Food>()
private val mAdapter = FoodAdapter(foodArrayList) private val mAdapter = FoodAdapter(foodArrayList)
private lateinit var mContext: Context private lateinit var mContext: Context
private lateinit var prefs: SharedPreferences private lateinit var prefs: SharedPreferences
private lateinit var recyclerView: RecyclerView
private lateinit var foodViewModel: FoodViewModel private lateinit var foodViewModel: FoodViewModel
private lateinit var binding: FoodLayoutBinding
override fun onAttach(context: Context) { override fun onAttach(context: Context) {
super.onAttach(context) super.onAttach(context)
mContext = context mContext = context
prefs = PreferenceManager.getDefaultSharedPreferences(mContext) prefs = PreferenceManager.getDefaultSharedPreferences(mContext)
} }
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
binding = FoodLayoutBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
val pullToRefresh = view.findViewById<SwipeRefreshLayout>(R.id.pullToRefresh)
recyclerView = view.findViewById(R.id.linear_food) binding.recyclerView.apply {
recyclerView.hasFixedSize() hasFixedSize()
recyclerView.layoutManager = GridLayoutManager(mContext, 1) layoutManager = GridLayoutManager(mContext, 1)
recyclerView.adapter = mAdapter adapter = mAdapter
}
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 ->
@@ -46,16 +52,16 @@ internal class FoodFragment : Fragment(R.layout.food_layout) {
for (item in foodList) { for (item in foodList) {
foodArrayList.add(item) foodArrayList.add(item)
} }
recyclerView.scheduleLayoutAnimation() binding.recyclerView.scheduleLayoutAnimation()
mAdapter.setFood(foodArrayList) mAdapter.setFood(foodArrayList)
}) })
if (prefs.getBoolean("autoRefresh", false)) { if (prefs.getBoolean("autoRefresh", false)) {
foodViewModel.refresh(swipeRefreshLayout = pullToRefresh, rootView = view.rootView) foodViewModel.refresh(swipeRefreshLayout = binding.swipeRefreshLayout, rootView = view.rootView)
} }
pullToRefresh.setOnRefreshListener { binding.swipeRefreshLayout.setOnRefreshListener {
foodViewModel.refresh(swipeRefreshLayout = pullToRefresh, rootView = view.rootView) foodViewModel.refresh(swipeRefreshLayout = binding.swipeRefreshLayout, rootView = view.rootView)
} }
} }
} }
@@ -12,7 +12,7 @@ internal class GeneralPlanFragment : PlanFragment() {
substitutionPlan?.observe(this, Observer<List<Substitution>> { substitutions -> substitutionPlan?.observe(this, Observer<List<Substitution>> { substitutions ->
mAdapter.setSubst(substitutions) mAdapter.setSubst(substitutions)
recyclerView.scheduleLayoutAnimation() binding.recyclerView.scheduleLayoutAnimation()
}) })
} }
} }
@@ -4,7 +4,6 @@ import android.os.Bundle
import android.view.View 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.models.Substitution import com.denizd.substitutionplan.models.Substitution
internal class PersonalPlanFragment : PlanFragment() { internal class PersonalPlanFragment : PlanFragment() {
@@ -12,20 +11,16 @@ internal class PersonalPlanFragment : PlanFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
personalPlanEmptyEmoticon = view.findViewById(R.id.smileydown)
personalPlanEmptyText = view.findViewById(R.id.smileydowntext)
personalPlanEmptyLayout = view.findViewById(R.id.linearsmiley)
val coursePreference = prefs.getString("courses", "") ?: "" val coursePreference = prefs.getString("courses", "") ?: ""
val classPreference = prefs.getString("classes", "") ?: "" val classPreference = prefs.getString("classes", "") ?: ""
substitutionPlan?.observe(this, Observer<List<Substitution>> { substitutions -> substitutionPlan?.observe(this, Observer<List<Substitution>> { substitutions ->
planCardList.clear() planCardList.clear()
personalPlanEmptyEmoticon.visibility = View.GONE binding.emptyPlanEmoticon.visibility = View.GONE
personalPlanEmptyText.visibility = View.GONE binding.emptyPlanText.visibility = View.GONE
personalPlanEmptyLayout.visibility = View.GONE binding.emptyPlanLayout.visibility = View.GONE
isPersonalPlanEmpty = true isPersonalPlanEmpty = true
recyclerView.visibility = View.VISIBLE binding.recyclerView.visibility = View.VISIBLE
substitutions.filter { substItem -> substitutions.filter { substItem ->
HelperFunctions.checkPersonalSubstitutions( HelperFunctions.checkPersonalSubstitutions(
@@ -38,15 +33,15 @@ internal class PersonalPlanFragment : PlanFragment() {
planCardList.add(substItem) planCardList.add(substItem)
} }
isPersonalPlanEmpty = (planCardList.size == 1 && planCardList[0].date.substring(0, 3) == "psa") || planCardList.isEmpty() isPersonalPlanEmpty = (planCardList.size == 1 && planCardList[0].date.substring(0, 3) == "psa") || planCardList.isEmpty()
recyclerView.scheduleLayoutAnimation() binding.recyclerView.scheduleLayoutAnimation()
mAdapter.setSubst(planCardList) mAdapter.setSubst(planCardList)
handler.postDelayed({ handler.postDelayed({
if (isPersonalPlanEmpty) { if (isPersonalPlanEmpty) {
personalPlanEmptyEmoticon.visibility = View.VISIBLE binding.emptyPlanEmoticon.visibility = View.VISIBLE
personalPlanEmptyText.visibility = View.VISIBLE binding.emptyPlanText.visibility = View.VISIBLE
personalPlanEmptyLayout.visibility = View.VISIBLE binding.emptyPlanLayout.visibility = View.VISIBLE
personalPlanEmptyLayout.scheduleLayoutAnimation() binding.emptyPlanLayout.scheduleLayoutAnimation()
} }
}, 64) }, 64)
}) })
@@ -5,46 +5,48 @@ import android.content.SharedPreferences
import android.content.res.Configuration import android.content.res.Configuration
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.preference.PreferenceManager import androidx.preference.PreferenceManager
import android.view.LayoutInflater
import android.view.View import android.view.View
import android.widget.LinearLayout import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.ViewModelProviders import androidx.lifecycle.ViewModelProviders
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView import com.denizd.substitutionplan.R
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.denizd.substitutionplan.*
import com.denizd.substitutionplan.adapters.SubstitutionAdapter import com.denizd.substitutionplan.adapters.SubstitutionAdapter
import com.denizd.substitutionplan.database.SubstViewModel import com.denizd.substitutionplan.database.SubstViewModel
import com.denizd.substitutionplan.databinding.PlanBinding
import com.denizd.substitutionplan.models.Substitution 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() {
internal lateinit var recyclerView: RecyclerView
internal lateinit var mAdapter: SubstitutionAdapter internal lateinit var mAdapter: SubstitutionAdapter
internal var planCardList = ArrayList<Substitution>() internal var planCardList = ArrayList<Substitution>()
private lateinit var substViewModel: SubstViewModel private lateinit var substViewModel: SubstViewModel
private lateinit var mContext: Context private lateinit var mContext: Context
internal lateinit var prefs: SharedPreferences internal lateinit var prefs: SharedPreferences
internal lateinit var personalPlanEmptyEmoticon: TextView
internal lateinit var personalPlanEmptyText: TextView
internal lateinit var personalPlanEmptyLayout: LinearLayout
internal var isPersonalPlanEmpty: Boolean = true internal var isPersonalPlanEmpty: Boolean = true
internal val handler = Handler() internal val handler = Handler()
internal var substitutionPlan: LiveData<List<Substitution>>? = null internal var substitutionPlan: LiveData<List<Substitution>>? = null
internal lateinit var binding: PlanBinding
override fun onAttach(context: Context) { override fun onAttach(context: Context) {
super.onAttach(context) super.onAttach(context)
mContext = context mContext = context
prefs = PreferenceManager.getDefaultSharedPreferences(mContext) prefs = PreferenceManager.getDefaultSharedPreferences(mContext)
} }
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
binding = PlanBinding.inflate(inflater, container, false)
return binding.root
}
override fun onConfigurationChanged(newConfig: Configuration) { override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig) super.onConfigurationChanged(newConfig)
recyclerView.layoutManager = GridLayoutManager(mContext, getGridColumnCount(newConfig)) binding.recyclerView.layoutManager = GridLayoutManager(mContext, getGridColumnCount(newConfig))
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@@ -56,24 +58,24 @@ internal open class PlanFragment : Fragment(R.layout.plan) {
substViewModel.allSubstitutionsOriginal substViewModel.allSubstitutionsOriginal
} }
val pullToRefresh = view.findViewById<SwipeRefreshLayout>(R.id.pullToRefresh)
recyclerView = view.findViewById(R.id.linearRecycler)
recyclerView.hasFixedSize()
recyclerView.layoutManager = GridLayoutManager(mContext, getGridColumnCount(resources.configuration))
mAdapter = SubstitutionAdapter(planCardList, prefs) mAdapter = SubstitutionAdapter(planCardList, prefs)
recyclerView.adapter = mAdapter binding.recyclerView.apply {
hasFixedSize()
layoutManager = GridLayoutManager(mContext, getGridColumnCount(resources.configuration))
adapter = mAdapter
}
if (prefs.getInt("firstTimeOpening", 0) == 1) { if (prefs.getInt("firstTimeOpening", 0) == 1) {
substViewModel.refresh(swipeRefreshLayout = pullToRefresh, rootView = view.rootView, refreshMenu = true) substViewModel.refresh(swipeRefreshLayout = binding.swipeRefreshLayout, rootView = view.rootView, refreshMenu = true)
prefs.edit().putInt("firstTimeOpening", 2).apply() prefs.edit().putInt("firstTimeOpening", 2).apply()
} }
if (prefs.getBoolean("autoRefresh", false)) { if (prefs.getBoolean("autoRefresh", false)) {
substViewModel.refresh(swipeRefreshLayout = pullToRefresh, rootView = view.rootView, refreshMenu = false) substViewModel.refresh(swipeRefreshLayout = binding.swipeRefreshLayout, rootView = view.rootView, refreshMenu = false)
} }
pullToRefresh.setOnRefreshListener { binding.swipeRefreshLayout.setOnRefreshListener {
substViewModel.refresh(swipeRefreshLayout = pullToRefresh, rootView = view.rootView, refreshMenu = false) substViewModel.refresh(swipeRefreshLayout = binding.swipeRefreshLayout, rootView = view.rootView, refreshMenu = false)
} }
} }
@@ -10,11 +10,13 @@ import android.media.RingtoneManager
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.preference.PreferenceManager import androidx.preference.PreferenceManager
import android.provider.Settings import android.provider.Settings
import android.text.Editable import android.text.Editable
import android.text.TextWatcher import android.text.TextWatcher
import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup
import android.view.Window import android.view.Window
import android.widget.* import android.widget.*
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
@@ -30,27 +32,33 @@ import com.denizd.substitutionplan.adapters.RingtoneAdapter
import com.denizd.substitutionplan.data.DataFetcher import com.denizd.substitutionplan.data.DataFetcher
import com.denizd.substitutionplan.data.HelperFunctions import com.denizd.substitutionplan.data.HelperFunctions
import com.denizd.substitutionplan.data.Topic import com.denizd.substitutionplan.data.Topic
import com.denizd.substitutionplan.databinding.ContentSettingsBinding
import com.denizd.substitutionplan.models.Colour import com.denizd.substitutionplan.models.Colour
import com.denizd.substitutionplan.models.Ringtone import com.denizd.substitutionplan.models.Ringtone
import com.google.android.material.bottomnavigation.BottomNavigationView import com.google.android.material.bottomnavigation.BottomNavigationView
import com.google.android.material.button.MaterialButton import com.google.android.material.button.MaterialButton
import com.google.android.material.textfield.TextInputEditText
import com.google.firebase.messaging.FirebaseMessaging import com.google.firebase.messaging.FirebaseMessaging
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
internal class SettingsFragment : Fragment(R.layout.content_settings), View.OnClickListener, internal class SettingsFragment : Fragment(), View.OnClickListener,
CompoundButton.OnCheckedChangeListener, ColourAdapter.OnClickListener, CompoundButton.OnCheckedChangeListener, ColourAdapter.OnColourClickListener,
RingtoneAdapter.OnClickListener { RingtoneAdapter.OnRingtoneClickListener {
private lateinit var mContext: Context private lateinit var mContext: Context
private lateinit var prefs: SharedPreferences private lateinit var prefs: SharedPreferences
private val builder = CustomTabsIntent.Builder() private val customTabsIntent = CustomTabsIntent.Builder().build() as CustomTabsIntent
private val customTabsIntent = builder.build() as CustomTabsIntent
private var window: Window? = null private var window: Window? = null
private lateinit var colourRecycler: RecyclerView
private lateinit var ringtoneCustomiserDialog: AlertDialog
private lateinit var currentRingtone: TextView
private var longPressed = false private var longPressed = false
private var courseHelpClicks = 0
private val ringtones: List<Ringtone> by lazy {
getRingtones()
}
private lateinit var colourRecycler: RecyclerView
private lateinit var ringtoneDialog: AlertDialog
private lateinit var binding: ContentSettingsBinding
override fun onAttach(context: Context) { override fun onAttach(context: Context) {
super.onAttach(context) super.onAttach(context)
@@ -59,164 +67,268 @@ internal class SettingsFragment : Fragment(R.layout.content_settings), View.OnCl
window = activity?.window window = activity?.window
} }
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
binding = ContentSettingsBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
val nameEditText = view.findViewById<TextInputEditText>(R.id.txtName) binding.apply {
val gradeEditText = view.findViewById<TextInputEditText>(R.id.txtClasses) val thisFragment = this@SettingsFragment
val courseEditText = view.findViewById<TextInputEditText>(R.id.txtCourses)
val greetingSwitch = view.findViewById<Switch>(R.id.switchDisableGreeting) // Set text
val notificationSwitch = view.findViewById<Switch>(R.id.switchNotifications) setRingtoneText()
val defaultPlanSwitch = view.findViewById<Switch>(R.id.switchDefaultPlan)
val autoRefreshSwitch = view.findViewById<Switch>(R.id.switchAutoRefresh)
val versionNumberText = view.findViewById<TextView>(R.id.txtVersionTwo)
val helpGradeButton = view.findViewById<ImageButton>(R.id.chipHelpClasses)
val helpCoursesButton = view.findViewById<ImageButton>(R.id.chipHelpCourses)
val colourCustomisationButton = view.findViewById<LinearLayout>(R.id.btnCustomiseColours)
val versionButton = view.findViewById<LinearLayout>(R.id.btnVersion)
currentRingtone = view.findViewById(R.id.txtCustomiseRingtone2)
setRingtoneText()
val forceRefreshButton = view.findViewById<LinearLayout>(R.id.btnForceRefresh)
val colourTextTitle = view.findViewById<TextView>(R.id.txtCustomiseColours1) textAppVersionDesc.text = BuildConfig.VERSION_NAME
val colourTextDesc = view.findViewById<TextView>(R.id.txtCustomiseColours2)
greetingSwitch.setOnCheckedChangeListener(this) // Set on click listeners
notificationSwitch.setOnCheckedChangeListener(this) buttonCustomiseColours.setOnClickListener(thisFragment)
defaultPlanSwitch.setOnCheckedChangeListener(this) buttonNotificationsHelp.setOnClickListener(thisFragment)
autoRefreshSwitch.setOnCheckedChangeListener(this) buttonCustomiseRingtone.setOnClickListener(thisFragment)
helpCoursesButton.setOnClickListener(this)
helpGradeButton.setOnClickListener(this) buttonGroupHelp.setOnClickListener(thisFragment)
view.findViewById<ImageButton>(R.id.chip_help_ordering).setOnClickListener(this) buttonCoursesHelp.setOnClickListener(thisFragment)
colourCustomisationButton.setOnClickListener(this) buttonOrderHelp.setOnClickListener(thisFragment)
colourCustomisationButton.setOnLongClickListener {
if (!longPressed) { buttonForcedRefresh.setOnClickListener(thisFragment)
colourTextTitle.text = getString(R.string.made_by_deniz) buttonVisitWebsite.setOnClickListener(thisFragment)
colourTextDesc.text = getString(R.string.thanks_for_using) buttonLicences.setOnClickListener(thisFragment)
} else { buttonVersion.setOnClickListener(thisFragment)
colourTextTitle.text = getString(R.string.customise_colours_title)
colourTextDesc.text = getString(R.string.customise_colours_desc) // Set on long click listeners
buttonCustomiseColours.setOnLongClickListener {
if (!longPressed) {
textCustomiseColoursTitle.text = getString(R.string.made_by_deniz)
textCustomiseColoursDesc.text = getString(R.string.thanks_for_using)
} else {
textCustomiseColoursTitle.text = getString(R.string.customise_colours_title)
textCustomiseColoursDesc.text = getString(R.string.customise_colours_desc)
}
longPressed = !longPressed
true
} }
longPressed = !longPressed
true
}
view.findViewById<LinearLayout>(R.id.btnNoNotif).setOnClickListener(this)
view.findViewById<LinearLayout>(R.id.btnCustomiseRingtone).setOnClickListener(this)
view.findViewById<LinearLayout>(R.id.btnWebsite).setOnClickListener(this)
view.findViewById<LinearLayout>(R.id.btnLicences).setOnClickListener(this)
versionButton.setOnClickListener(this)
forceRefreshButton.setOnClickListener(this)
forceRefreshButton.setOnLongClickListener {
prefs.edit().putString("timeNew", "").putString("newFoodTime", "").apply()
makeToast(mContext.getString(R.string.force_refresh_cleared_times))
true
}
val darkModeDropDown = view.findViewById<AutoCompleteTextView>(R.id.darkModeDropDownText) buttonForcedRefresh.setOnLongClickListener {
val darkModeList = if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) { prefs.edit().putString("timeNew", "").putString("newFoodTime", "").apply()
R.array.themes_pre_q makeToast(mContext.getString(R.string.force_refresh_cleared_times))
} else { true
R.array.themes }
}
val darkModeAdapter = ArrayAdapter.createFromResource( buttonVersion.setOnLongClickListener {
mContext, debugMenu()
darkModeList, }
R.layout.dropdown_item
)
darkModeAdapter.setDropDownViewResource(R.layout.dropdown_item)
darkModeDropDown.setAdapter(darkModeAdapter)
darkModeDropDown.setText(darkModeDropDown.adapter.getItem(prefs.getInt("themeInt", 0)).toString(), false) // Set on checked change listeners
switchGreeting.setOnCheckedChangeListener(thisFragment)
switchNotifications.setOnCheckedChangeListener(thisFragment)
switchPersonalisedPlan.setOnCheckedChangeListener(thisFragment)
switchAutoRefresh.setOnCheckedChangeListener(thisFragment)
darkModeDropDown.setOnItemClickListener { _, _, position, _ -> // Set checked
prefs.edit().putInt("themeInt", position).apply() switchGreeting.isChecked = prefs.getBoolean("greeting", true)
switchNotifications.isChecked = prefs.getBoolean("notif", false)
val bottomNav = view.rootView.findViewById<BottomNavigationView>(R.id.bottom_nav) switchPersonalisedPlan.isChecked = prefs.getBoolean("defaultPersonalised", false)
when (position) { switchAutoRefresh.isChecked = prefs.getBoolean("autoRefresh", false)
0 -> {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO) // Set edit text (+ listeners)
if (Build.VERSION.SDK_INT in 23..28) { edittextName.setText(prefs.getString("username", ""))
@SuppressLint("InlinedApi") edittextName.addTextChangedListener(object : TextWatcher {
window?.decorView?.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR override fun afterTextChanged(s: Editable) {}
window?.navigationBarColor = ContextCompat.getColor(mContext, R.color.colorBackground) override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
prefs.edit().putString("username", edittextName.text.toString().trim()).apply()
}
})
edittextGroup.setText(prefs.getString("classes", ""))
edittextGroup.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable) {}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
prefs.edit().putString("classes", edittextGroup.text.toString()).apply()
}
})
edittextCourses.setText(prefs.getString("courses", ""))
edittextCourses.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable) {}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
prefs.edit().putString("courses", edittextCourses.text.toString()).apply()
}
})
// Set spinners (+ listeners)
val darkModeList = if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
R.array.themes_pre_q
} else {
R.array.themes
}
val darkModeAdapter = ArrayAdapter.createFromResource(
mContext,
darkModeList,
R.layout.dropdown_item
)
autocompleteDarkMode.setAdapter(darkModeAdapter)
autocompleteDarkMode.setText(autocompleteDarkMode.adapter.getItem(prefs.getInt("themeInt", 0)).toString(), false)
autocompleteDarkMode.setOnItemClickListener { _, _, position, _ ->
prefs.edit().putInt("themeInt", position).apply()
when (position) {
0 -> {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
if (Build.VERSION.SDK_INT in 23..28) {
@SuppressLint("InlinedApi")
window?.decorView?.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
window?.navigationBarColor = ContextCompat.getColor(mContext, R.color.colorBackground)
}
}
2 -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) // only accessible on API 29+
else -> {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
window?.navigationBarColor = ContextCompat.getColor(mContext, R.color.colorBackground)
}
} }
} }
2 -> { // only accessible on Android 10 (and above) view.rootView.findViewById<BottomNavigationView>(R.id.bottom_nav).selectedItemId = if (prefs.getBoolean("defaultPersonalised", false)) {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) R.id.personal
} } else {
else -> { R.id.plan
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
window?.navigationBarColor = ContextCompat.getColor(mContext, R.color.colorBackground)
}
} }
} }
if (prefs.getBoolean("defaultPersonalised", false)) {
bottomNav.selectedItemId = R.id.personal val selectedOrderingOption = if (prefs.getBoolean("app_specific_sorting", true)) 0 else 1
} else { val orderingArrayAdapter = ArrayAdapter.createFromResource(
bottomNav.selectedItemId = R.id.plan mContext,
R.array.ordering_systems,
R.layout.dropdown_item
)
autocompleteOrder.setAdapter(orderingArrayAdapter)
autocompleteOrder.setText(autocompleteOrder.adapter.getItem(selectedOrderingOption).toString(), false)
autocompleteOrder.setOnItemClickListener { _, _, position, _ ->
prefs.edit().putBoolean("app_specific_sorting", position == 0).apply()
} }
} }
val orderingDropDownText = view.findViewById<AutoCompleteTextView>(R.id.order_drop_down_text)
val orderingArrayAdapter = ArrayAdapter.createFromResource(
mContext,
R.array.ordering_systems,
R.layout.dropdown_item
)
orderingArrayAdapter.setDropDownViewResource(R.layout.dropdown_item)
orderingDropDownText.setAdapter(orderingArrayAdapter)
val selectedOrderingOption = if (prefs.getBoolean("app_specific_sorting", true)) 0 else 1
orderingDropDownText.setText(orderingDropDownText.adapter.getItem(selectedOrderingOption).toString(), false)
orderingDropDownText.setOnItemClickListener { _, _, position, _ ->
prefs.edit().putBoolean("app_specific_sorting", position == 0).apply()
}
greetingSwitch.isChecked = prefs.getBoolean("greeting", true)
notificationSwitch.isChecked = prefs.getBoolean("notif", false)
defaultPlanSwitch.isChecked = prefs.getBoolean("defaultPersonalised", false)
autoRefreshSwitch.isChecked = prefs.getBoolean("autoRefresh", false)
versionNumberText.text = BuildConfig.VERSION_NAME
nameEditText.setText(prefs.getString("username", ""))
nameEditText.addTextChangedListener(object: TextWatcher {
override fun afterTextChanged(s: Editable) {}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
prefs.edit().putString("username", nameEditText.text.toString().trim()).apply()
}
})
gradeEditText.setText(prefs.getString("classes", ""))
gradeEditText.addTextChangedListener(object: TextWatcher {
override fun afterTextChanged(s: Editable) {}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
prefs.edit().putString("classes", gradeEditText.text.toString()).apply()
}
})
courseEditText.setText(prefs.getString("courses", ""))
courseEditText.addTextChangedListener(object: TextWatcher {
override fun afterTextChanged(s: Editable) {}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
prefs.edit().putString("courses", courseEditText.text.toString()).apply()
}
})
versionButton.setOnLongClickListener {
debugMenu()
}
} }
// Functions for handling touch events in this fragment
override fun onClick(v: View?) {
when (v?.id) {
R.id.button_customise_colours -> createColourDialog()
R.id.button_notifications_help -> createDialog(mContext.getString(R.string.no_notifications_title), mContext.getString(R.string.no_notifications_dialog_text))
R.id.button_customise_ringtone -> createRingtoneDialog()
R.id.button_group_help -> createDialog(getString(R.string.grade_help_dialog_title), getString(
R.string.grade_help_dialog_text
))
R.id.button_courses_help -> {
if (courseHelpClicks < 11) {
courseHelpClicks += 1
createDialog(getString(R.string.courses_help_dialog_title), getString(R.string.courses_help_dialog_text))
} else {
courseHelpClicks = 0
try {
makeToast(String(Character.toChars(0x2764)))
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))
}
}
}
R.id.button_order_help -> createDialog(getString(R.string.ordering_systems_dialog_title), getString(R.string.ordering_systems_dialog_text))
R.id.button_forced_refresh -> {
DataFetcher(
isPlan = true,
isMenu = true,
forced = true,
context = mContext,
application = activity!!.application,
parentView = view!!.rootView
).execute()
}
R.id.button_visit_website -> {
try {
customTabsIntent.launchUrl(mContext, Uri.parse("http://307.joomla.schule.bremen.de"))
} catch (e: ActivityNotFoundException) {
makeToast(getString(R.string.chrome_not_found))
}
}
R.id.button_licences -> {
createDialog(mContext.getString(R.string.licences_title), licences)
}
}
}
override fun onCheckedChanged(v: CompoundButton?, isChecked: Boolean) {
if (v?.isPressed == true) {
when (v.id) {
R.id.switch_greeting -> {
prefs.edit().putBoolean("greeting", isChecked).apply()
}
R.id.switch_notifications -> {
prefs.edit().putBoolean("notif", isChecked).apply()
if (isChecked) {
subscribeToTopic(Topic.ANDROID)
} else {
unsubscribeFromTopic(Topic.ANDROID)
}
}
R.id.switch_personalised_plan -> {
prefs.edit().putBoolean("defaultPersonalised", isChecked).apply()
}
R.id.switch_auto_refresh -> {
prefs.edit().putBoolean("autoRefresh", isChecked).apply()
}
}
}
}
// Functions for handling touch events for recycler view elements
override fun onColourClick(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 onRingtoneClick(position: Int, name: String, uri: String) {
prefs.edit().apply {
putString("ringtoneName", name)
putString("ringtoneUri", uri)
}.apply()
setRingtoneText()
ringtoneDialog.dismiss()
}
// Functions for handling dialog creation
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
@@ -233,7 +345,7 @@ internal class SettingsFragment : Fragment(R.layout.content_settings), View.OnCl
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)
titleText.text = getString(R.string.customise_colours_title) titleText.text = getString(R.string.customise_colours_title)
colourRecycler = dialogView.findViewById(R.id.recyclerView) val colourRecycler = dialogView.findViewById<RecyclerView>(R.id.recyclerView)
colourRecycler.apply { colourRecycler.apply {
hasFixedSize() hasFixedSize()
layoutManager = GridLayoutManager(mContext, 1) layoutManager = GridLayoutManager(mContext, 1)
@@ -244,48 +356,6 @@ internal class SettingsFragment : Fragment(R.layout.content_settings), View.OnCl
colourCustomisationDialog.show() colourCustomisationDialog.show()
} }
private fun getColourList(): ArrayList<Colour> {
val colours = ArrayList<Colour>()
val coursesNoLang = HelperFunctions.languageIndependentCourses
val courses = arrayOf(getString(R.string.course_deu), getString(
R.string.course_eng
), getString(R.string.course_fra), getString(R.string.course_spa), getString(
R.string.course_lat
), getString(R.string.course_tue), getString(R.string.course_chi), getString(
R.string.course_kun
), getString(R.string.course_mus), getString(R.string.course_dar), getString(
R.string.course_geg
), getString(R.string.course_ges), getString(R.string.course_pol), getString(
R.string.course_phi
), getString(R.string.course_rel), getString(R.string.course_mat), getString(
R.string.course_bio
), getString(R.string.course_che), getString(R.string.course_phy), getString(
R.string.course_inf
), getString(R.string.course_spo), getString(R.string.course_gll), getString(
R.string.course_wat
), getString(R.string.course_foer), getString(R.string.course_wp))
val coursesIcons = intArrayOf(R.drawable.ic_german, R.drawable.ic_english, R.drawable.ic_french,
R.drawable.ic_spanish, R.drawable.ic_latin, R.drawable.ic_turkish, R.drawable.ic_chinese,
R.drawable.ic_arts, R.drawable.ic_music, R.drawable.ic_drama, R.drawable.ic_geography,
R.drawable.ic_history, R.drawable.ic_politics, R.drawable.ic_philosophy, R.drawable.ic_religion,
R.drawable.ic_maths, R.drawable.ic_biology, R.drawable.ic_chemistry, R.drawable.ic_physics,
R.drawable.ic_compsci, R.drawable.ic_pe, R.drawable.ic_gll, R.drawable.ic_wat,
R.drawable.ic_help, R.drawable.ic_pencil
)
for (i in coursesNoLang.indices) {
colours.add(
Colour(
courses[i],
coursesNoLang[i],
coursesIcons[i],
HelperFunctions.getColourForString(prefs.getString("card${coursesNoLang[i]}", "") ?: "")
)
)
}
return colours
}
private fun createRingtoneDialog() { private fun createRingtoneDialog() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
HelperFunctions.getNotificationChannel(mContext, prefs) HelperFunctions.getNotificationChannel(mContext, prefs)
@@ -305,48 +375,15 @@ internal class SettingsFragment : Fragment(R.layout.content_settings), View.OnCl
recycler.apply { recycler.apply {
hasFixedSize() hasFixedSize()
layoutManager = GridLayoutManager(mContext, 1) layoutManager = GridLayoutManager(mContext, 1)
adapter = RingtoneAdapter(ringtones, this@SettingsFragment)
} }
ringtoneCustomiserDialog = ringtoneCustomiserBuilder.setView(dialogView).create() ringtoneDialog = ringtoneCustomiserBuilder.setView(dialogView).create()
ringtoneCustomiserDialog.show() ringtoneDialog.show()
recycler.postDelayed({ // recycler.postDelayed({
val ringtones = getRingtones().toList() // recycler.
recycler.adapter = RingtoneAdapter(ringtones, this) // }, 100)
}, 100)
}
}
private fun getRingtones(): ArrayList<Ringtone> {
lateinit var ringtoneCursor: Cursor
val ringtoneManager = RingtoneManager(activity).apply {
setType(RingtoneManager.TYPE_NOTIFICATION)
ringtoneCursor = cursor
}
val alarms = ArrayList<Ringtone>()
while (!ringtoneCursor.isAfterLast && ringtoneCursor.moveToNext()) {
val position = ringtoneCursor.position
alarms.add(
Ringtone(
ringtoneManager.getRingtone(position).getTitle(mContext),
ringtoneManager.getRingtoneUri(position).toString()
)
)
}
return alarms
}
private fun setRingtoneText() {
currentRingtone.text = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mContext.getString(R.string.pick_ringtone_desc_o)
} else {
val tone = if ((prefs.getString("ringtoneName", "") ?: "").isNotEmpty()) {
prefs.getString("ringtoneName", "")
} else {
mContext.getString(R.string.default_ringtone)
}
mContext.getString(R.string.pick_ringtone_desc, tone)
} }
} }
@@ -357,10 +394,10 @@ internal class SettingsFragment : Fragment(R.layout.content_settings), View.OnCl
val dialogButton = dialogView.findViewById<Button>(R.id.dialog_button) val dialogButton = dialogView.findViewById<Button>(R.id.dialog_button)
dialogView.findViewById<TextView>(R.id.textviewtitle).text = getString( dialogView.findViewById<TextView>(R.id.textviewtitle).text = getString(
R.string.experimental_menu_dialog_title R.string.experimental_menu_dialog_title
) )
dialogView.findViewById<TextView>(R.id.dialogtext).text = getString( dialogView.findViewById<TextView>(R.id.dialogtext).text = getString(
R.string.experimental_menu_dialog_text R.string.experimental_menu_dialog_text
) )
dialogButton.setOnClickListener { dialogButton.setOnClickListener {
when (dialogEditText.text.toString()) { when (dialogEditText.text.toString()) {
@@ -387,15 +424,6 @@ internal class SettingsFragment : Fragment(R.layout.content_settings), View.OnCl
alertDialogDev.setView(devDialogView) alertDialogDev.setView(devDialogView)
alertDialogDev.show() alertDialogDev.show()
} }
"2019-06-06" -> {
try {
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" -> { "_LOGIN" -> {
prefs.edit().putBoolean("successful_login", false).apply() prefs.edit().putBoolean("successful_login", false).apply()
makeToast("Login flag cleared") makeToast("Login flag cleared")
@@ -441,6 +469,112 @@ internal class SettingsFragment : Fragment(R.layout.content_settings), View.OnCl
return true return true
} }
// Functions for retrieving data
private fun getColourList(): ArrayList<Colour> {
val colours = ArrayList<Colour>()
val coursesNoLang = HelperFunctions.languageIndependentCourses
val courses = arrayOf(
getString(R.string.course_deu),
getString(R.string.course_eng),
getString(R.string.course_fra),
getString(R.string.course_spa),
getString(R.string.course_lat),
getString(R.string.course_tue),
getString(R.string.course_chi),
getString(R.string.course_kun),
getString(R.string.course_mus),
getString(R.string.course_dar),
getString(R.string.course_geg),
getString(R.string.course_ges),
getString(R.string.course_pol),
getString(R.string.course_phi),
getString(R.string.course_rel),
getString(R.string.course_mat),
getString(R.string.course_bio),
getString(R.string.course_che),
getString(R.string.course_phy),
getString(R.string.course_inf),
getString(R.string.course_spo),
getString(R.string.course_gll),
getString(R.string.course_wat),
getString(R.string.course_foer),
getString(R.string.course_wp)
)
val coursesIcons = intArrayOf(
R.drawable.ic_german,
R.drawable.ic_english,
R.drawable.ic_french,
R.drawable.ic_spanish,
R.drawable.ic_latin,
R.drawable.ic_turkish,
R.drawable.ic_chinese,
R.drawable.ic_arts,
R.drawable.ic_music,
R.drawable.ic_drama,
R.drawable.ic_geography,
R.drawable.ic_history,
R.drawable.ic_politics,
R.drawable.ic_philosophy,
R.drawable.ic_religion,
R.drawable.ic_maths,
R.drawable.ic_biology,
R.drawable.ic_chemistry,
R.drawable.ic_physics,
R.drawable.ic_compsci,
R.drawable.ic_pe,
R.drawable.ic_gll,
R.drawable.ic_wat,
R.drawable.ic_help,
R.drawable.ic_pencil
)
for (i in coursesNoLang.indices) {
colours.add(
Colour(
courses[i],
coursesNoLang[i],
coursesIcons[i],
HelperFunctions.getColourForString(prefs.getString("card${coursesNoLang[i]}", "") ?: "")
)
)
}
return colours
}
private fun getRingtones(): ArrayList<Ringtone> {
lateinit var ringtoneCursor: Cursor
val ringtoneManager = RingtoneManager(activity).apply {
setType(RingtoneManager.TYPE_NOTIFICATION)
ringtoneCursor = cursor
}
val alarms = ArrayList<Ringtone>()
while (!ringtoneCursor.isAfterLast && ringtoneCursor.moveToNext()) {
val position = ringtoneCursor.position
alarms.add(
Ringtone(
ringtoneManager.getRingtone(position).getTitle(mContext),
ringtoneManager.getRingtoneUri(position).toString()
)
)
}
return alarms
}
// Functions for handling other things
private fun setRingtoneText() {
binding.textCustomiseRingtoneDesc.text = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mContext.getString(R.string.pick_ringtone_desc_o)
} else {
val tone = if ((prefs.getString("ringtoneName", "") ?: "").isNotEmpty()) {
prefs.getString("ringtoneName", "")
} else {
mContext.getString(R.string.default_ringtone)
}
mContext.getString(R.string.pick_ringtone_desc, tone)
}
}
private fun makeToast(text: String) { private fun makeToast(text: String) {
Toast.makeText(mContext, text, Toast.LENGTH_LONG).show() Toast.makeText(mContext, text, Toast.LENGTH_LONG).show()
} }
@@ -460,111 +594,7 @@ 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?) { // Below this point follow string literals that I didn't bother putting in /res/values/strings
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.chip_help_ordering -> createDialog(getString(R.string.ordering_systems_dialog_title), getString(R.string.ordering_systems_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.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()
}
}
}
}
/// Below this point follow string literals that I didn't bother putting in /res/values
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" +
@@ -1,5 +1,6 @@
package com.denizd.substitutionplan.services package com.denizd.substitutionplan.services
import android.annotation.SuppressLint
import com.denizd.substitutionplan.data.DataFetcher import com.denizd.substitutionplan.data.DataFetcher
import com.google.firebase.messaging.FirebaseMessagingService import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage import com.google.firebase.messaging.RemoteMessage
@@ -8,6 +9,7 @@ import com.google.firebase.messaging.RemoteMessage
* This class handles Firebase data notifications and triggers a refresh of the substitution plan * This class handles Firebase data notifications and triggers a refresh of the substitution plan
* as well as the food menu upon arrival * as well as the food menu upon arrival
*/ */
@SuppressLint("MissingFirebaseInstanceTokenRefresh")
internal class FBNotificationService : FirebaseMessagingService() { internal class FBNotificationService : FirebaseMessagingService() {
override fun onMessageReceived(p0: RemoteMessage) { override fun onMessageReceived(p0: RemoteMessage) {
@@ -17,8 +19,7 @@ internal class FBNotificationService : FirebaseMessagingService() {
isJobService = true, isJobService = true,
context = applicationContext, context = applicationContext,
application = application, application = application,
parentView = null, parentView = null
forced = false
).execute() ).execute()
} }
} }
@@ -2,7 +2,7 @@ package com.denizd.substitutionplan.services
import android.app.job.JobParameters import android.app.job.JobParameters
import android.app.job.JobService import android.app.job.JobService
import android.preference.PreferenceManager import androidx.preference.PreferenceManager
import com.denizd.substitutionplan.data.Topic import com.denizd.substitutionplan.data.Topic
import com.google.firebase.FirebaseApp import com.google.firebase.FirebaseApp
import com.google.firebase.messaging.FirebaseMessaging import com.google.firebase.messaging.FirebaseMessaging
+19 -19
View File
@@ -59,7 +59,7 @@
app:layout_constraintTop_toBottomOf="@+id/txtsetupthings" /> app:layout_constraintTop_toBottomOf="@+id/txtsetupthings" />
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/txtLayoutClasses" android:id="@+id/textinputlayout_group"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox" style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
app:boxStrokeColor="@color/colorAccent" app:boxStrokeColor="@color/colorAccent"
app:boxStrokeWidth="1dp" app:boxStrokeWidth="1dp"
@@ -75,7 +75,7 @@
android:importantForAutofill="no"> android:importantForAutofill="no">
<com.google.android.material.textfield.TextInputEditText <com.google.android.material.textfield.TextInputEditText
android:id="@+id/txtName" android:id="@+id/edittext_name"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
@@ -100,9 +100,9 @@
android:text="@string/grade_text" android:text="@string/grade_text"
android:textColor="@color/colorText" android:textColor="@color/colorText"
android:textSize="14sp" android:textSize="14sp"
app:layout_constraintEnd_toEndOf="@+id/txtLayoutClasses" app:layout_constraintEnd_toEndOf="@+id/textinputlayout_group"
app:layout_constraintStart_toStartOf="@+id/txtLayoutClasses" app:layout_constraintStart_toStartOf="@+id/textinputlayout_group"
app:layout_constraintTop_toBottomOf="@+id/txtLayoutClasses" /> app:layout_constraintTop_toBottomOf="@+id/textinputlayout_group" />
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/txtLayoutClass" android:id="@+id/txtLayoutClass"
@@ -114,13 +114,13 @@
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:hint="@string/your_grade" android:hint="@string/your_grade"
android:textColorHint="@color/colorHint" android:textColorHint="@color/colorHint"
app:layout_constraintEnd_toStartOf="@+id/chipHelpClasses" app:layout_constraintEnd_toStartOf="@+id/button_group_help"
app:layout_constraintStart_toStartOf="@+id/txtNextClass" app:layout_constraintStart_toStartOf="@+id/txtNextClass"
app:layout_constraintTop_toBottomOf="@+id/txtNextClass" app:layout_constraintTop_toBottomOf="@+id/txtNextClass"
android:importantForAutofill="no"> android:importantForAutofill="no">
<com.google.android.material.textfield.TextInputEditText <com.google.android.material.textfield.TextInputEditText
android:id="@+id/txtClasses" android:id="@+id/edittext_group"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
@@ -137,7 +137,7 @@
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<ImageButton <ImageButton
android:id="@+id/chipHelpClasses" android:id="@+id/button_group_help"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
@@ -156,12 +156,12 @@
android:gravity="start" android:gravity="start"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:textColor="@color/colorText" android:textColor="@color/colorText"
app:layout_constraintEnd_toEndOf="@+id/txtLayoutClasses" app:layout_constraintEnd_toEndOf="@+id/textinputlayout_group"
app:layout_constraintStart_toStartOf="@+id/txtLayoutClasses" app:layout_constraintStart_toStartOf="@+id/textinputlayout_group"
app:layout_constraintTop_toBottomOf="@+id/txtLayoutClass" /> app:layout_constraintTop_toBottomOf="@+id/txtLayoutClass" />
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/txtLayoutCourses" android:id="@+id/textinputlayout_courses"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox" style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
app:boxStrokeColor="@color/colorAccent" app:boxStrokeColor="@color/colorAccent"
app:boxStrokeWidth="1dp" app:boxStrokeWidth="1dp"
@@ -170,12 +170,12 @@
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:hint="@string/your_courses" android:hint="@string/your_courses"
android:textColorHint="@color/colorHint" android:textColorHint="@color/colorHint"
app:layout_constraintEnd_toStartOf="@+id/chipHelpCourses" app:layout_constraintEnd_toStartOf="@+id/button_courses_help"
app:layout_constraintStart_toStartOf="@+id/txtSenior" app:layout_constraintStart_toStartOf="@+id/txtSenior"
app:layout_constraintTop_toBottomOf="@+id/txtSenior"> app:layout_constraintTop_toBottomOf="@+id/txtSenior">
<com.google.android.material.textfield.TextInputEditText <com.google.android.material.textfield.TextInputEditText
android:id="@+id/txtCourses" android:id="@+id/edittext_courses"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
@@ -193,16 +193,16 @@
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<ImageButton <ImageButton
android:id="@+id/chipHelpCourses" android:id="@+id/button_courses_help"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
android:backgroundTint="@android:color/transparent" android:backgroundTint="@android:color/transparent"
android:src="@drawable/ic_qmark" android:src="@drawable/ic_qmark"
android:tint="@color/colorText" android:tint="@color/colorText"
app:layout_constraintBottom_toBottomOf="@+id/txtLayoutCourses" app:layout_constraintBottom_toBottomOf="@+id/textinputlayout_courses"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/txtLayoutCourses" /> app:layout_constraintTop_toTopOf="@+id/textinputlayout_courses" />
<TextView <TextView
android:id="@+id/txtMore" android:id="@+id/txtMore"
@@ -211,9 +211,9 @@
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:text="@string/more_settings_text" android:text="@string/more_settings_text"
android:textColor="@color/colorText" android:textColor="@color/colorText"
app:layout_constraintEnd_toEndOf="@+id/txtLayoutClasses" app:layout_constraintEnd_toEndOf="@+id/textinputlayout_group"
app:layout_constraintStart_toStartOf="@+id/txtLayoutClasses" app:layout_constraintStart_toStartOf="@+id/textinputlayout_group"
app:layout_constraintTop_toBottomOf="@+id/txtLayoutCourses" /> app:layout_constraintTop_toBottomOf="@+id/textinputlayout_courses" />
<LinearLayout <LinearLayout
android:layout_width="0dp" android:layout_width="0dp"
+139 -137
View File
@@ -7,7 +7,7 @@
tools:context=".fragments.SettingsFragment"> tools:context=".fragments.SettingsFragment">
<androidx.core.widget.NestedScrollView <androidx.core.widget.NestedScrollView
android:id="@+id/nsvsettings" android:id="@+id/settings_scroll_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:fillViewport="true" android:fillViewport="true"
@@ -36,7 +36,7 @@
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<TextView <TextView
android:id="@+id/txtPersonalise" android:id="@+id/header_personalise"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
@@ -47,7 +47,7 @@
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/txtLayoutName" android:id="@+id/textinputlayout_name"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox" style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -61,10 +61,10 @@
app:boxStrokeWidth="1dp" app:boxStrokeWidth="1dp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/txtPersonalise"> app:layout_constraintTop_toBottomOf="@+id/header_personalise">
<com.google.android.material.textfield.TextInputEditText <com.google.android.material.textfield.TextInputEditText
android:id="@+id/txtName" android:id="@+id/edittext_name"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:animateLayoutChanges="true" android:animateLayoutChanges="true"
@@ -79,38 +79,39 @@
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<TextView <TextView
android:id="@+id/txtGreeting" android:id="@+id/text_greeting_title"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:text="@string/greeting_title" android:text="@string/greeting_title"
android:textColor="@color/colorText" android:textColor="@color/colorText"
android:textSize="14sp" android:textSize="14sp"
app:layout_constraintStart_toStartOf="@+id/txtPersonalise" app:layout_constraintStart_toStartOf="@+id/header_personalise"
app:layout_constraintTop_toBottomOf="@+id/txtLayoutName" /> app:layout_constraintTop_toBottomOf="@+id/textinputlayout_name" />
<TextView <TextView
android:id="@+id/txtJustnice" android:id="@+id/text_greeting_desc"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/greeting_desc" android:text="@string/greeting_desc"
android:textColor="@color/colorHint" android:textColor="@color/colorHint"
android:textSize="12sp" android:textSize="12sp"
app:layout_constraintStart_toStartOf="@+id/txtGreeting" app:layout_constraintStart_toStartOf="@+id/text_greeting_title"
app:layout_constraintTop_toBottomOf="@+id/txtGreeting" /> app:layout_constraintTop_toBottomOf="@+id/text_greeting_title" />
<Switch <Switch
android:id="@+id/switchDisableGreeting" android:id="@+id/switch_greeting"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:gravity="end|center" android:gravity="end|center"
app:layout_constraintBottom_toBottomOf="@+id/txtJustnice" app:layout_constraintBottom_toBottomOf="@+id/text_greeting_desc"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/txtGreeting" app:layout_constraintStart_toStartOf="@+id/text_greeting_title"
app:layout_constraintTop_toTopOf="@+id/txtGreeting" /> app:layout_constraintTop_toTopOf="@+id/text_greeting_title" />
<com.google.android.material.textfield.TextInputLayout android:id="@+id/darkModeDropDown" <com.google.android.material.textfield.TextInputLayout
android:id="@+id/textinputlayout_dark_mode"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu" style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -119,10 +120,10 @@
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/switchDisableGreeting"> app:layout_constraintTop_toBottomOf="@+id/switch_greeting">
<AutoCompleteTextView <AutoCompleteTextView
android:id="@+id/darkModeDropDownText" android:id="@+id/autocomplete_dark_mode"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:editable="false" android:editable="false"
@@ -133,30 +134,30 @@
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<TextView <TextView
android:id="@+id/txtCustomiseColours1" android:id="@+id/text_customise_colours_title"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:text="@string/customise_colours_title" android:text="@string/customise_colours_title"
android:textColor="@color/colorText" android:textColor="@color/colorText"
android:textSize="14sp" android:textSize="14sp"
app:layout_constraintStart_toStartOf="@+id/txtJustnice" app:layout_constraintStart_toStartOf="@+id/text_greeting_desc"
app:layout_constraintTop_toBottomOf="@+id/darkModeDropDown" /> app:layout_constraintTop_toBottomOf="@+id/textinputlayout_dark_mode" />
<TextView <TextView
android:id="@+id/txtCustomiseColours2" android:id="@+id/text_customise_colours_desc"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="16dp" android:layout_marginBottom="16dp"
android:text="@string/customise_colours_desc" android:text="@string/customise_colours_desc"
android:textColor="@color/colorHint" android:textColor="@color/colorHint"
android:textSize="12sp" android:textSize="12sp"
app:layout_constraintBottom_toTopOf="@+id/txtNotifications" app:layout_constraintBottom_toTopOf="@+id/text_notifications_title"
app:layout_constraintStart_toStartOf="@+id/txtCustomiseColours1" app:layout_constraintStart_toStartOf="@+id/text_customise_colours_title"
app:layout_constraintTop_toBottomOf="@+id/txtCustomiseColours1" /> app:layout_constraintTop_toBottomOf="@+id/text_customise_colours_title" />
<LinearLayout <LinearLayout
android:id="@+id/btnCustomiseColours" android:id="@+id/button_customise_colours"
style="@style/SelectableItemBackground" style="@style/SelectableItemBackground"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
@@ -165,24 +166,24 @@
android:clickable="true" android:clickable="true"
android:focusable="true" android:focusable="true"
android:orientation="vertical" android:orientation="vertical"
app:layout_constraintBottom_toTopOf="@+id/txtNotifications" app:layout_constraintBottom_toTopOf="@+id/text_notifications_title"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/darkModeDropDown" /> app:layout_constraintTop_toBottomOf="@+id/textinputlayout_dark_mode" />
<TextView <TextView
android:id="@+id/txtNotifications" android:id="@+id/text_notifications_title"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:text="@string/enable_course_notifications_title" android:text="@string/enable_course_notifications_title"
android:textColor="@color/colorText" android:textColor="@color/colorText"
android:textSize="14sp" android:textSize="14sp"
app:layout_constraintStart_toStartOf="@+id/txtCustomiseColours2" app:layout_constraintStart_toStartOf="@+id/text_customise_colours_desc"
app:layout_constraintTop_toBottomOf="@+id/txtCustomiseColours2" /> app:layout_constraintTop_toBottomOf="@+id/text_customise_colours_desc" />
<TextView <TextView
android:id="@+id/txtNotifiedAbout" android:id="@+id/text_notifications_desc"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="16dp" android:layout_marginBottom="16dp"
@@ -190,47 +191,47 @@
android:textAlignment="textStart" android:textAlignment="textStart"
android:textColor="@color/colorHint" android:textColor="@color/colorHint"
android:textSize="12sp" android:textSize="12sp"
app:layout_constraintBottom_toTopOf="@+id/txtNoNotif1" app:layout_constraintBottom_toTopOf="@+id/text_notifications_help_title"
app:layout_constraintStart_toStartOf="@+id/txtNotifications" app:layout_constraintStart_toStartOf="@+id/text_notifications_title"
app:layout_constraintTop_toBottomOf="@+id/txtNotifications" /> app:layout_constraintTop_toBottomOf="@+id/text_notifications_title" />
<Switch <Switch
android:id="@+id/switchNotifications" android:id="@+id/switch_notifications"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp" android:layout_marginBottom="16dp"
android:gravity="end|center" android:gravity="end|center"
app:layout_constraintBottom_toTopOf="@+id/txtNoNotif1" app:layout_constraintBottom_toTopOf="@+id/text_notifications_help_title"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/txtNotifications" app:layout_constraintStart_toStartOf="@+id/text_notifications_title"
app:layout_constraintTop_toTopOf="@+id/txtNotifications" /> app:layout_constraintTop_toTopOf="@+id/text_notifications_title" />
<TextView <TextView
android:id="@+id/txtNoNotif1" android:id="@+id/text_notifications_help_title"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:text="@string/no_notifications_title" android:text="@string/no_notifications_title"
android:textColor="@color/colorText" android:textColor="@color/colorText"
android:textSize="14sp" android:textSize="14sp"
app:layout_constraintStart_toStartOf="@+id/txtNotifiedAbout" app:layout_constraintStart_toStartOf="@+id/text_notifications_desc"
app:layout_constraintTop_toBottomOf="@+id/txtNotifiedAbout" /> app:layout_constraintTop_toBottomOf="@+id/text_notifications_desc" />
<TextView <TextView
android:id="@+id/txtNoNotif2" android:id="@+id/text_notifications_help_desc"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="16dp" android:layout_marginBottom="16dp"
android:text="@string/no_notifications_desc" android:text="@string/no_notifications_desc"
android:textColor="@color/colorHint" android:textColor="@color/colorHint"
android:textSize="12sp" android:textSize="12sp"
app:layout_constraintBottom_toTopOf="@+id/txtCustomiseRingtone" app:layout_constraintBottom_toTopOf="@+id/text_customise_ringtone_title"
app:layout_constraintStart_toStartOf="@+id/txtNoNotif1" app:layout_constraintStart_toStartOf="@+id/text_notifications_help_title"
app:layout_constraintTop_toBottomOf="@+id/txtNoNotif1" /> app:layout_constraintTop_toBottomOf="@+id/text_notifications_help_title" />
<LinearLayout <LinearLayout
android:id="@+id/btnNoNotif" android:id="@+id/button_notifications_help"
style="@style/SelectableItemBackground" style="@style/SelectableItemBackground"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
@@ -239,24 +240,24 @@
android:clickable="true" android:clickable="true"
android:focusable="true" android:focusable="true"
android:orientation="vertical" android:orientation="vertical"
app:layout_constraintBottom_toTopOf="@+id/txtCustomiseRingtone" app:layout_constraintBottom_toTopOf="@+id/text_customise_ringtone_title"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/txtNotifiedAbout" /> app:layout_constraintTop_toBottomOf="@+id/text_notifications_desc" />
<TextView <TextView
android:id="@+id/txtCustomiseRingtone" android:id="@+id/text_customise_ringtone_title"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:text="@string/pick_ringtone_title" android:text="@string/pick_ringtone_title"
android:textColor="@color/colorText" android:textColor="@color/colorText"
android:textSize="14sp" android:textSize="14sp"
app:layout_constraintStart_toStartOf="@+id/txtNotifiedAbout" app:layout_constraintStart_toStartOf="@+id/text_notifications_desc"
app:layout_constraintTop_toBottomOf="@+id/txtNoNotif2" /> app:layout_constraintTop_toBottomOf="@+id/text_notifications_help_desc" />
<TextView <TextView
android:id="@+id/txtCustomiseRingtone2" android:id="@+id/text_customise_ringtone_desc"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="16dp" android:layout_marginBottom="16dp"
@@ -264,11 +265,11 @@
android:textColor="@color/colorHint" android:textColor="@color/colorHint"
android:textSize="12sp" android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="@+id/txtCustomiseRingtone" app:layout_constraintStart_toStartOf="@+id/text_customise_ringtone_title"
app:layout_constraintTop_toBottomOf="@+id/txtCustomiseRingtone" /> app:layout_constraintTop_toBottomOf="@+id/text_customise_ringtone_title" />
<LinearLayout <LinearLayout
android:id="@+id/btnCustomiseRingtone" android:id="@+id/button_customise_ringtone"
style="@style/SelectableItemBackground" style="@style/SelectableItemBackground"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
@@ -280,7 +281,7 @@
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/txtNoNotif2" /> app:layout_constraintTop_toBottomOf="@+id/text_notifications_help_desc" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
@@ -302,7 +303,7 @@
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<TextView <TextView
android:id="@+id/txtFilter" android:id="@+id/header_filter"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
@@ -313,7 +314,7 @@
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/txtLayoutClasses" android:id="@+id/textinputlayout_group"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox" style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
app:boxStrokeColor="@color/colorAccent" app:boxStrokeColor="@color/colorAccent"
app:boxStrokeWidth="1dp" app:boxStrokeWidth="1dp"
@@ -324,13 +325,13 @@
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
android:hint="@string/grade" android:hint="@string/grade"
android:textColorHint="@color/colorHint" android:textColorHint="@color/colorHint"
app:layout_constraintEnd_toStartOf="@+id/chipHelpClasses" app:layout_constraintEnd_toStartOf="@+id/button_group_help"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/txtFilter" app:layout_constraintTop_toBottomOf="@+id/header_filter"
android:importantForAutofill="no"> android:importantForAutofill="no">
<com.google.android.material.textfield.TextInputEditText <com.google.android.material.textfield.TextInputEditText
android:id="@+id/txtClasses" android:id="@+id/edittext_group"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:animateLayoutChanges="true" android:animateLayoutChanges="true"
@@ -345,19 +346,19 @@
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<ImageButton <ImageButton
android:id="@+id/chipHelpClasses" android:id="@+id/button_group_help"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:src="@drawable/ic_qmark" android:src="@drawable/ic_qmark"
android:tint="@color/colorText" android:tint="@color/colorText"
android:backgroundTint="@android:color/transparent" android:backgroundTint="@android:color/transparent"
app:layout_constraintBottom_toBottomOf="@+id/txtLayoutClasses" app:layout_constraintBottom_toBottomOf="@+id/textinputlayout_group"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/txtLayoutClasses" /> app:layout_constraintTop_toTopOf="@+id/textinputlayout_group" />
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/txtLayoutCourses" android:id="@+id/textinputlayout_courses"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox" style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -368,12 +369,12 @@
android:textColorHint="@color/colorHint" android:textColorHint="@color/colorHint"
app:boxStrokeColor="@color/colorAccent" app:boxStrokeColor="@color/colorAccent"
app:boxStrokeWidth="1dp" app:boxStrokeWidth="1dp"
app:layout_constraintStart_toStartOf="@+id/txtLayoutClasses" app:layout_constraintStart_toStartOf="@+id/textinputlayout_group"
app:layout_constraintTop_toBottomOf="@+id/txtLayoutClasses" app:layout_constraintTop_toBottomOf="@+id/textinputlayout_group"
app:layout_constraintEnd_toStartOf="@+id/chipHelpCourses"> app:layout_constraintEnd_toStartOf="@+id/button_courses_help">
<com.google.android.material.textfield.TextInputEditText <com.google.android.material.textfield.TextInputEditText
android:id="@+id/txtCourses" android:id="@+id/edittext_courses"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:animateLayoutChanges="true" android:animateLayoutChanges="true"
@@ -388,18 +389,19 @@
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<ImageButton <ImageButton
android:id="@+id/chipHelpCourses" android:id="@+id/button_courses_help"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:src="@drawable/ic_qmark" android:src="@drawable/ic_qmark"
android:tint="@color/colorText" android:tint="@color/colorText"
android:backgroundTint="@android:color/transparent" android:backgroundTint="@android:color/transparent"
app:layout_constraintBottom_toBottomOf="@+id/txtLayoutCourses" app:layout_constraintBottom_toBottomOf="@+id/textinputlayout_courses"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/txtLayoutCourses" /> app:layout_constraintTop_toTopOf="@+id/textinputlayout_courses" />
<com.google.android.material.textfield.TextInputLayout android:id="@+id/order_drop_down" <com.google.android.material.textfield.TextInputLayout
android:id="@+id/textinputlayout_order"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu" style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -409,11 +411,11 @@
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/chip_help_ordering" app:layout_constraintEnd_toStartOf="@+id/button_order_help"
app:layout_constraintTop_toBottomOf="@+id/txtLayoutCourses"> app:layout_constraintTop_toBottomOf="@+id/textinputlayout_courses">
<AutoCompleteTextView <AutoCompleteTextView
android:id="@+id/order_drop_down_text" android:id="@+id/autocomplete_order"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:editable="false" android:editable="false"
@@ -424,16 +426,16 @@
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<ImageButton <ImageButton
android:id="@+id/chip_help_ordering" android:id="@+id/button_order_help"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:src="@drawable/ic_qmark" android:src="@drawable/ic_qmark"
android:tint="@color/colorText" android:tint="@color/colorText"
android:backgroundTint="@android:color/transparent" android:backgroundTint="@android:color/transparent"
app:layout_constraintBottom_toBottomOf="@+id/order_drop_down" app:layout_constraintBottom_toBottomOf="@+id/textinputlayout_order"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/order_drop_down" /> app:layout_constraintTop_toTopOf="@+id/textinputlayout_order" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
@@ -455,7 +457,7 @@
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<TextView <TextView
android:id="@+id/txtMisc" android:id="@+id/header_miscellaneous"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
@@ -466,94 +468,94 @@
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<TextView <TextView
android:id="@+id/txtPersonalised" android:id="@+id/text_personalised_plan_title"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:text="@string/default_plan_title" android:text="@string/default_plan_title"
android:textColor="@color/colorText" android:textColor="@color/colorText"
android:textSize="14sp" android:textSize="14sp"
app:layout_constraintStart_toStartOf="@+id/txtMisc" app:layout_constraintStart_toStartOf="@+id/header_miscellaneous"
app:layout_constraintTop_toBottomOf="@+id/txtMisc" /> app:layout_constraintTop_toBottomOf="@+id/header_miscellaneous" />
<TextView <TextView
android:id="@+id/txtDefaultsTo" android:id="@+id/text_personalised_plan_desc"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/default_plan_desc" android:text="@string/default_plan_desc"
android:textColor="@color/colorHint" android:textColor="@color/colorHint"
android:textSize="12sp" android:textSize="12sp"
app:layout_constraintStart_toStartOf="@+id/txtPersonalised" app:layout_constraintStart_toStartOf="@+id/text_personalised_plan_title"
app:layout_constraintTop_toBottomOf="@+id/txtPersonalised" /> app:layout_constraintTop_toBottomOf="@+id/text_personalised_plan_title" />
<Switch <Switch
android:id="@+id/switchDefaultPlan" android:id="@+id/switch_personalised_plan"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:gravity="end|center" android:gravity="end|center"
app:layout_constraintBottom_toBottomOf="@+id/txtDefaultsTo" app:layout_constraintBottom_toBottomOf="@+id/text_personalised_plan_desc"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/txtPersonalised" app:layout_constraintStart_toStartOf="@+id/text_personalised_plan_title"
app:layout_constraintTop_toTopOf="@+id/txtPersonalised"/> app:layout_constraintTop_toTopOf="@+id/text_personalised_plan_title"/>
<TextView <TextView
android:id="@+id/txtAutoRefresh" android:id="@+id/text_auto_refresh_title"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:text="@string/auto_refresh_title" android:text="@string/auto_refresh_title"
android:textColor="@color/colorText" android:textColor="@color/colorText"
android:textSize="14sp" android:textSize="14sp"
app:layout_constraintStart_toStartOf="@+id/txtDefaultsTo" app:layout_constraintStart_toStartOf="@+id/text_personalised_plan_desc"
app:layout_constraintTop_toBottomOf="@+id/txtDefaultsTo" /> app:layout_constraintTop_toBottomOf="@+id/text_personalised_plan_desc" />
<TextView <TextView
android:id="@+id/txtAutoRefreshTwo" android:id="@+id/text_auto_refresh_desc"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/auto_refresh_desc" android:text="@string/auto_refresh_desc"
android:textColor="@color/colorHint" android:textColor="@color/colorHint"
android:textSize="12sp" android:textSize="12sp"
app:layout_constraintStart_toStartOf="@+id/txtAutoRefresh" app:layout_constraintStart_toStartOf="@+id/text_auto_refresh_title"
app:layout_constraintTop_toBottomOf="@+id/txtAutoRefresh" /> app:layout_constraintTop_toBottomOf="@+id/text_auto_refresh_title" />
<Switch <Switch
android:id="@+id/switchAutoRefresh" android:id="@+id/switch_auto_refresh"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:gravity="end|center" android:gravity="end|center"
app:layout_constraintBottom_toBottomOf="@+id/txtAutoRefreshTwo" app:layout_constraintBottom_toBottomOf="@+id/text_auto_refresh_desc"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/txtAutoRefresh" app:layout_constraintStart_toStartOf="@+id/text_auto_refresh_title"
app:layout_constraintTop_toTopOf="@+id/txtAutoRefresh"/> app:layout_constraintTop_toTopOf="@+id/text_auto_refresh_title"/>
<TextView <TextView
android:id="@+id/txtForceRefresh" android:id="@+id/text_forced_refresh_title"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:text="@string/force_refresh_title" android:text="@string/force_refresh_title"
android:textColor="@color/colorText" android:textColor="@color/colorText"
android:textSize="14sp" android:textSize="14sp"
app:layout_constraintStart_toStartOf="@+id/txtAutoRefreshTwo" app:layout_constraintStart_toStartOf="@+id/text_auto_refresh_desc"
app:layout_constraintTop_toBottomOf="@+id/txtAutoRefreshTwo" /> app:layout_constraintTop_toBottomOf="@+id/text_auto_refresh_desc" />
<TextView <TextView
android:id="@+id/txtForceRefresh2" android:id="@+id/text_forced_refresh_desc"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/force_refresh_desc" android:text="@string/force_refresh_desc"
android:textColor="@color/colorHint" android:textColor="@color/colorHint"
android:textSize="12sp" android:textSize="12sp"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
app:layout_constraintStart_toStartOf="@+id/txtForceRefresh" app:layout_constraintStart_toStartOf="@+id/text_forced_refresh_title"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/txtForceRefresh" /> app:layout_constraintTop_toBottomOf="@+id/text_forced_refresh_title" />
<LinearLayout <LinearLayout
android:id="@+id/btnForceRefresh" android:id="@+id/button_forced_refresh"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
@@ -562,34 +564,34 @@
android:focusable="true" android:focusable="true"
style="@style/SelectableItemBackground" style="@style/SelectableItemBackground"
android:orientation="vertical" android:orientation="vertical"
app:layout_constraintBottom_toTopOf="@+id/txtVisitWeb" app:layout_constraintBottom_toTopOf="@+id/text_visit_website_title"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/txtAutoRefreshTwo" /> app:layout_constraintTop_toBottomOf="@+id/text_auto_refresh_desc" />
<TextView <TextView
android:id="@+id/txtVisitWeb" android:id="@+id/text_visit_website_title"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:text="@string/visit_website_title" android:text="@string/visit_website_title"
android:textColor="@color/colorText" android:textColor="@color/colorText"
android:textSize="14sp" android:textSize="14sp"
app:layout_constraintStart_toStartOf="@+id/txtForceRefresh2" app:layout_constraintStart_toStartOf="@+id/text_forced_refresh_desc"
app:layout_constraintTop_toBottomOf="@+id/txtForceRefresh2" /> app:layout_constraintTop_toBottomOf="@+id/text_forced_refresh_desc" />
<TextView <TextView
android:id="@+id/txtWeb" android:id="@+id/text_visit_website_desc"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/visit_website_desc" android:text="@string/visit_website_desc"
android:textColor="@color/colorHint" android:textColor="@color/colorHint"
android:textSize="12sp" android:textSize="12sp"
app:layout_constraintStart_toStartOf="@+id/txtForceRefresh" app:layout_constraintStart_toStartOf="@+id/text_forced_refresh_title"
app:layout_constraintTop_toBottomOf="@+id/txtVisitWeb" /> app:layout_constraintTop_toBottomOf="@+id/text_visit_website_title" />
<LinearLayout <LinearLayout
android:id="@+id/btnWebsite" android:id="@+id/button_visit_website"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
@@ -598,35 +600,35 @@
android:focusable="true" android:focusable="true"
style="@style/SelectableItemBackground" style="@style/SelectableItemBackground"
android:orientation="vertical" android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="@+id/txtWeb" app:layout_constraintBottom_toBottomOf="@+id/text_visit_website_desc"
app:layout_constraintBottom_toTopOf="@+id/txtLicences" app:layout_constraintBottom_toTopOf="@+id/text_licences_title"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/txtForceRefresh2" /> app:layout_constraintTop_toBottomOf="@+id/text_forced_refresh_desc" />
<TextView <TextView
android:id="@+id/txtLicences" android:id="@+id/text_licences_title"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:text="@string/licences_title" android:text="@string/licences_title"
android:textColor="@color/colorText" android:textColor="@color/colorText"
android:textSize="14sp" android:textSize="14sp"
app:layout_constraintStart_toStartOf="@+id/txtWeb" app:layout_constraintStart_toStartOf="@+id/text_visit_website_desc"
app:layout_constraintTop_toBottomOf="@+id/txtWeb" /> app:layout_constraintTop_toBottomOf="@+id/text_visit_website_desc" />
<TextView <TextView
android:id="@+id/txtWhatittook" android:id="@+id/text_licences_desc"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/licences_desc" android:text="@string/licences_desc"
android:textColor="@color/colorHint" android:textColor="@color/colorHint"
android:textSize="12sp" android:textSize="12sp"
app:layout_constraintStart_toStartOf="@+id/txtLicences" app:layout_constraintStart_toStartOf="@+id/text_licences_title"
app:layout_constraintTop_toBottomOf="@+id/txtLicences" /> app:layout_constraintTop_toBottomOf="@+id/text_licences_title" />
<LinearLayout <LinearLayout
android:id="@+id/btnLicences" android:id="@+id/button_licences"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
@@ -635,36 +637,36 @@
android:focusable="true" android:focusable="true"
style="@style/SelectableItemBackground" style="@style/SelectableItemBackground"
android:orientation="vertical" android:orientation="vertical"
app:layout_constraintBottom_toTopOf="@+id/txtVersion" app:layout_constraintBottom_toTopOf="@+id/text_app_version_title"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/txtWeb" /> app:layout_constraintTop_toBottomOf="@+id/text_visit_website_desc" />
<TextView <TextView
android:id="@+id/txtVersion" android:id="@+id/text_app_version_title"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:text="@string/version" android:text="@string/version"
android:textColor="@color/colorText" android:textColor="@color/colorText"
android:textSize="14sp" android:textSize="14sp"
app:layout_constraintStart_toStartOf="@+id/txtWhatittook" app:layout_constraintStart_toStartOf="@+id/text_licences_desc"
app:layout_constraintTop_toBottomOf="@+id/txtWhatittook" /> app:layout_constraintTop_toBottomOf="@+id/text_licences_desc" />
<TextView <TextView
android:id="@+id/txtVersionTwo" android:id="@+id/text_app_version_desc"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="16dp" android:layout_marginBottom="16dp"
android:textColor="@color/colorHint" android:textColor="@color/colorHint"
android:textSize="12sp" android:textSize="12sp"
android:fontFeatureSettings="tnum" android:fontFeatureSettings="tnum"
app:layout_constraintStart_toStartOf="@+id/txtVersion" app:layout_constraintStart_toStartOf="@+id/text_app_version_title"
app:layout_constraintTop_toBottomOf="@+id/txtVersion" app:layout_constraintTop_toBottomOf="@+id/text_app_version_title"
app:layout_constraintBottom_toBottomOf="parent"/> app:layout_constraintBottom_toBottomOf="parent"/>
<LinearLayout <LinearLayout
android:id="@+id/btnVersion" android:id="@+id/button_version"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
@@ -677,7 +679,7 @@
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/txtWhatittook" /> app:layout_constraintTop_toBottomOf="@+id/text_licences_desc" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
+5 -13
View File
@@ -17,14 +17,13 @@
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content"
android:layout_margin="16dp">
<TextView <TextView
android:id="@+id/group" android:id="@+id/group"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
app:layout_constraintEnd_toStartOf="@+id/date" app:layout_constraintEnd_toStartOf="@+id/date"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
@@ -36,8 +35,8 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal" android:orientation="horizontal"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:gravity="start|center_vertical" android:gravity="start|center_vertical"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/group" app:layout_constraintTop_toBottomOf="@+id/group"
@@ -70,8 +69,7 @@
android:id="@+id/teacher" android:id="@+id/teacher"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textColor="@color/colorText" android:textColor="@color/colorText"/>
android:layout_marginEnd="8dp"/>
</LinearLayout> </LinearLayout>
@@ -79,10 +77,8 @@
android:id="@+id/additional" android:id="@+id/additional"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
android:layout_marginBottom="16dp"
android:textColor="@color/colorText" android:textColor="@color/colorText"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/room" app:layout_constraintEnd_toStartOf="@+id/room"
@@ -93,8 +89,6 @@
android:id="@+id/date" android:id="@+id/date"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:textAlignment="textEnd" android:textAlignment="textEnd"
android:textColor="@color/colorText" android:textColor="@color/colorText"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
@@ -106,7 +100,6 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:textAlignment="textEnd" android:textAlignment="textEnd"
android:textColor="@color/colorText" android:textColor="@color/colorText"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
@@ -118,11 +111,10 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginBottom="16dp"
android:textAlignment="textEnd" android:textAlignment="textEnd"
android:textColor="@color/colorText" android:textColor="@color/colorText"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/time" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/time" app:layout_constraintTop_toBottomOf="@+id/time"
app:layout_constraintWidth_max="200dp" /> app:layout_constraintWidth_max="200dp" />
+2 -2
View File
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/pullToRefresh" android:id="@+id/swipe_refresh_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android"> xmlns:android="http://schemas.android.com/apk/res/android">
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/linear_food" android:id="@+id/recycler_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layoutAnimation="@anim/layout_animation_fall_down" android:layoutAnimation="@anim/layout_animation_fall_down"
+9 -24
View File
@@ -15,16 +15,17 @@
android:layout_marginBottom="3dp" android:layout_marginBottom="3dp"
app:cardElevation="2dp"> app:cardElevation="2dp">
<androidx.constraintlayout.widget.ConstraintLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_margin="16dp">
<ImageView <ImageView
android:id="@+id/item_image" android:id="@+id/item_image"
android:layout_width="24dp" android:layout_width="24dp"
android:layout_height="24dp" android:layout_height="24dp"
android:layout_margin="16dp" android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:tint="@color/colorText" android:tint="@color/colorText"
app:layout_constraintBottom_toBottomOf="@+id/item_text" app:layout_constraintBottom_toBottomOf="@+id/item_text"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
@@ -32,27 +33,11 @@
<TextView <TextView
android:id="@+id/item_text" android:id="@+id/item_text"
android:layout_width="0dp" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="8dp" android:layout_gravity="center_vertical"
android:layout_marginTop="16dp" android:textColor="@color/colorText"/>
android:layout_marginEnd="8dp"
android:layout_marginBottom="16dp"
android:textAlignment="viewStart"
android:textColor="@color/colorText"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/item_image"
app:layout_constraintTop_toTopOf="parent" />
<TextView </LinearLayout>
android:id="@+id/item_text_no_lang"
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="gone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView> </com.google.android.material.card.MaterialCardView>
+5 -5
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout xmlns:tools="http://schemas.android.com/tools" <androidx.swiperefreshlayout.widget.SwipeRefreshLayout xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/pullToRefresh" android:id="@+id/swipe_refresh_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
@@ -13,13 +13,13 @@
<LinearLayout <LinearLayout
android:orientation="vertical" android:orientation="vertical"
android:id="@+id/linearsmiley" android:id="@+id/empty_plan_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layoutAnimation="@anim/layout_animation_fall_down"> android:layoutAnimation="@anim/layout_animation_fall_down">
<TextView <TextView
android:id="@+id/smileydown" android:id="@+id/empty_plan_emoticon"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text=":(" android:text=":("
@@ -30,7 +30,7 @@
tools:ignore="HardcodedText,SpUsage" /> tools:ignore="HardcodedText,SpUsage" />
<TextView <TextView
android:id="@+id/smileydowntext" android:id="@+id/empty_plan_text"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/no_personal_substitutions" android:text="@string/no_personal_substitutions"
@@ -43,7 +43,7 @@
</LinearLayout> </LinearLayout>
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/linearRecycler" android:id="@+id/recycler_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layoutAnimation="@anim/layout_animation_fall_down" android:layoutAnimation="@anim/layout_animation_fall_down"
+1 -1
View File
@@ -10,7 +10,7 @@ buildscript {
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.5.0' classpath 'com.android.tools.build:gradle:3.6.0-beta01'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.google.gms:google-services:4.3.2' classpath 'com.google.gms:google-services:4.3.2'
classpath 'io.fabric.tools:gradle:1.31.0' classpath 'io.fabric.tools:gradle:1.31.0'
+1 -1
View File
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.1-all.zip