From 87d4f11cba9043fb90de7f2733fa5d7fe5ec05c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Deniz=20D=C3=BCzg=C3=B6ren?= Date: Tue, 24 Sep 2019 09:32:25 +0200 Subject: [PATCH] Added drop down menu in the settings to switch between app-specific and website original sorting procedures --- .../substitutionplan/data/DataFetcher.kt | 5 ++- .../substitutionplan/database/SubstDao.kt | 7 +++- .../database/SubstDatabase.kt | 9 ++++- .../database/SubstRepository.kt | 6 ++- .../database/SubstViewModel.kt | 6 ++- .../fragments/GeneralPlanFragment.kt | 2 +- .../fragments/PersonalPlanFragment.kt | 2 +- .../fragments/PlanFragment.kt | 27 ++++++++----- .../fragments/SettingsFragment.kt | 19 ++++++++++ .../substitutionplan/models/Substitution.kt | 3 +- app/src/main/res/layout/content_settings.xml | 38 ++++++++++++++++++- app/src/main/res/values-de/strings.xml | 7 ++++ app/src/main/res/values/strings.xml | 7 ++++ 13 files changed, 114 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/com/denizd/substitutionplan/data/DataFetcher.kt b/app/src/main/java/com/denizd/substitutionplan/data/DataFetcher.kt index c7f1fac..8f08368 100644 --- a/app/src/main/java/com/denizd/substitutionplan/data/DataFetcher.kt +++ b/app/src/main/java/com/denizd/substitutionplan/data/DataFetcher.kt @@ -58,6 +58,7 @@ internal class DataFetcher(isPlan: Boolean, isMenu: Boolean, isJobService: Boole private var currentFoodTime = "" private var substUrl = "https://djd4rkn355.github.io/avh_substitutions.html" private var foodUrl = "https://djd4rkn355.github.io/food.html" + private var websitePriority = 0 override fun doInBackground(vararg params: Void?): Void? { try { @@ -181,10 +182,12 @@ internal class DataFetcher(isPlan: Boolean, isMenu: Boolean, isJobService: Boole teacher = cols[6].text(), type = cols[7].text(), priority = HelperFunctions.assignRanking(group, date.substring(0, 3) == "psa"), - date_priority = HelperFunctions.assignDatePriority(date) + date_priority = HelperFunctions.assignDatePriority(date), + website_priority = websitePriority ) substArray.add(subst) substRepo.insert(subst) + websitePriority += 1 } var countOfNotificationItems = 0 var countOfMoreNotificationItems = 0 diff --git a/app/src/main/java/com/denizd/substitutionplan/database/SubstDao.kt b/app/src/main/java/com/denizd/substitutionplan/database/SubstDao.kt index 054d36c..00d4048 100644 --- a/app/src/main/java/com/denizd/substitutionplan/database/SubstDao.kt +++ b/app/src/main/java/com/denizd/substitutionplan/database/SubstDao.kt @@ -8,8 +8,11 @@ import com.denizd.substitutionplan.models.Substitution @Dao internal interface SubstDao { - @get:Query("SELECT * FROM subst_table ORDER BY date_priority ASC, priority ASC, `group` ASC, time ASC") - val allSubstitutions: LiveData> + @get:Query("SELECT * FROM subst_table ORDER BY date_priority ASC, date ASC, priority ASC, `group` ASC, time ASC") + val allSubstitutionsSorted: LiveData> + + @get:Query("SELECT * FROM subst_table ORDER BY website_priority ASC") + val allSubstitutionsOriginal: LiveData> @Insert fun insertSubst(substitution: Substitution) diff --git a/app/src/main/java/com/denizd/substitutionplan/database/SubstDatabase.kt b/app/src/main/java/com/denizd/substitutionplan/database/SubstDatabase.kt index 0387bec..e59b6d8 100644 --- a/app/src/main/java/com/denizd/substitutionplan/database/SubstDatabase.kt +++ b/app/src/main/java/com/denizd/substitutionplan/database/SubstDatabase.kt @@ -9,7 +9,7 @@ import androidx.sqlite.db.SupportSQLiteDatabase import com.denizd.substitutionplan.models.Food import com.denizd.substitutionplan.models.Substitution -@Database(entities = [Substitution::class, Food::class], version = 8, exportSchema = false) +@Database(entities = [Substitution::class, Food::class], version = 9, exportSchema = false) internal abstract class SubstDatabase : RoomDatabase() { abstract fun substDao(): SubstDao @@ -32,6 +32,11 @@ internal abstract class SubstDatabase : RoomDatabase() { database.execSQL("ALTER TABLE subst_table ADD COLUMN date_priority INTEGER NOT NULL DEFAULT 0") } } + private val addWebsitePriorityColumn = object : Migration(8, 9) { + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL("ALTER TABLE subst_table ADD COLUMN website_priority INTEGER NOT NULL DEFAULT 0") + } + } fun getInstance(context: Context): SubstDatabase? { if (instance == null) { @@ -39,7 +44,7 @@ internal abstract class SubstDatabase : RoomDatabase() { instance = Room.databaseBuilder(context.applicationContext, SubstDatabase::class.java, "subst_database") - .addMigrations(addTeacherColumn, addTypeColumn, addDatePriorityColumn) + .addMigrations(addTeacherColumn, addTypeColumn, addDatePriorityColumn, addWebsitePriorityColumn) .fallbackToDestructiveMigration() .build() } diff --git a/app/src/main/java/com/denizd/substitutionplan/database/SubstRepository.kt b/app/src/main/java/com/denizd/substitutionplan/database/SubstRepository.kt index 4c43a80..dd8e2ec 100644 --- a/app/src/main/java/com/denizd/substitutionplan/database/SubstRepository.kt +++ b/app/src/main/java/com/denizd/substitutionplan/database/SubstRepository.kt @@ -9,13 +9,15 @@ import com.denizd.substitutionplan.models.Substitution internal class SubstRepository(application: Application) { private val substDao: SubstDao? - val allSubstitutions: LiveData>? + val allSubstitutionsSorted: LiveData>? + val allSubstitutionsOriginal: LiveData>? init { val database = SubstDatabase.getInstance(application) substDao = database?.substDao() - allSubstitutions = substDao?.allSubstitutions + allSubstitutionsSorted = substDao?.allSubstitutionsSorted + allSubstitutionsOriginal = substDao?.allSubstitutionsOriginal } fun insert(substitution: Substitution) { diff --git a/app/src/main/java/com/denizd/substitutionplan/database/SubstViewModel.kt b/app/src/main/java/com/denizd/substitutionplan/database/SubstViewModel.kt index 78078ef..7f57994 100644 --- a/app/src/main/java/com/denizd/substitutionplan/database/SubstViewModel.kt +++ b/app/src/main/java/com/denizd/substitutionplan/database/SubstViewModel.kt @@ -11,11 +11,13 @@ import com.denizd.substitutionplan.models.Substitution internal class SubstViewModel(application: Application) : AndroidViewModel(application) { private val repository: SubstRepository = SubstRepository(application) - val allSubstitutions: LiveData>? + val allSubstitutionsSorted: LiveData>? + val allSubstitutionsOriginal: LiveData>? private val app = application init { - allSubstitutions = repository.allSubstitutions + allSubstitutionsSorted = repository.allSubstitutionsSorted + allSubstitutionsOriginal = repository.allSubstitutionsOriginal } fun refresh(swipeRefreshLayout: SwipeRefreshLayout, rootView: View, refreshMenu: Boolean) { diff --git a/app/src/main/java/com/denizd/substitutionplan/fragments/GeneralPlanFragment.kt b/app/src/main/java/com/denizd/substitutionplan/fragments/GeneralPlanFragment.kt index 9222410..38bc0ed 100644 --- a/app/src/main/java/com/denizd/substitutionplan/fragments/GeneralPlanFragment.kt +++ b/app/src/main/java/com/denizd/substitutionplan/fragments/GeneralPlanFragment.kt @@ -10,7 +10,7 @@ internal class GeneralPlanFragment : PlanFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - substViewModel.allSubstitutions?.observe(this, Observer> { substitutions -> + substitutionPlan?.observe(this, Observer> { substitutions -> mAdapter.setSubst(substitutions) recyclerView.scheduleLayoutAnimation() }) diff --git a/app/src/main/java/com/denizd/substitutionplan/fragments/PersonalPlanFragment.kt b/app/src/main/java/com/denizd/substitutionplan/fragments/PersonalPlanFragment.kt index 60e3fd8..fa0cf4b 100644 --- a/app/src/main/java/com/denizd/substitutionplan/fragments/PersonalPlanFragment.kt +++ b/app/src/main/java/com/denizd/substitutionplan/fragments/PersonalPlanFragment.kt @@ -19,7 +19,7 @@ internal class PersonalPlanFragment : PlanFragment() { val coursePreference = prefs.getString("courses", "") ?: "" val classPreference = prefs.getString("classes", "") ?: "" - substViewModel.allSubstitutions?.observe(this, Observer> { substitutions -> + substitutionPlan?.observe(this, Observer> { substitutions -> planCardList.clear() personalPlanEmptyEmoticon.visibility = View.GONE personalPlanEmptyText.visibility = View.GONE diff --git a/app/src/main/java/com/denizd/substitutionplan/fragments/PlanFragment.kt b/app/src/main/java/com/denizd/substitutionplan/fragments/PlanFragment.kt index 9c4f8d0..2a76c15 100644 --- a/app/src/main/java/com/denizd/substitutionplan/fragments/PlanFragment.kt +++ b/app/src/main/java/com/denizd/substitutionplan/fragments/PlanFragment.kt @@ -10,6 +10,7 @@ import android.view.View import android.widget.LinearLayout import android.widget.TextView import androidx.fragment.app.Fragment +import androidx.lifecycle.LiveData import androidx.lifecycle.ViewModelProviders import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.RecyclerView @@ -21,18 +22,19 @@ import com.denizd.substitutionplan.models.Substitution import kotlin.collections.ArrayList internal open class PlanFragment : Fragment(R.layout.plan) { - lateinit var recyclerView: RecyclerView - lateinit var mAdapter: SubstitutionAdapter - var planCardList = ArrayList() - lateinit var substViewModel: SubstViewModel + internal lateinit var recyclerView: RecyclerView + internal lateinit var mAdapter: SubstitutionAdapter + internal var planCardList = ArrayList() + private lateinit var substViewModel: SubstViewModel private lateinit var mContext: Context - lateinit var prefs: SharedPreferences + internal lateinit var prefs: SharedPreferences - lateinit var personalPlanEmptyEmoticon: TextView - lateinit var personalPlanEmptyText: TextView - lateinit var personalPlanEmptyLayout: LinearLayout - var isPersonalPlanEmpty: Boolean = true - val handler = Handler() + internal lateinit var personalPlanEmptyEmoticon: TextView + internal lateinit var personalPlanEmptyText: TextView + internal lateinit var personalPlanEmptyLayout: LinearLayout + internal var isPersonalPlanEmpty: Boolean = true + internal val handler = Handler() + internal var substitutionPlan: LiveData>? = null override fun onAttach(context: Context) { super.onAttach(context) @@ -48,6 +50,11 @@ internal open class PlanFragment : Fragment(R.layout.plan) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) substViewModel = ViewModelProviders.of(this).get(SubstViewModel::class.java) + substitutionPlan = if (prefs.getBoolean("app_specific_sorting", true)) { + substViewModel.allSubstitutionsSorted + } else { + substViewModel.allSubstitutionsOriginal + } val pullToRefresh = view.findViewById(R.id.pullToRefresh) recyclerView = view.findViewById(R.id.linearRecycler) diff --git a/app/src/main/java/com/denizd/substitutionplan/fragments/SettingsFragment.kt b/app/src/main/java/com/denizd/substitutionplan/fragments/SettingsFragment.kt index 3d6912f..e079cab 100644 --- a/app/src/main/java/com/denizd/substitutionplan/fragments/SettingsFragment.kt +++ b/app/src/main/java/com/denizd/substitutionplan/fragments/SettingsFragment.kt @@ -86,6 +86,7 @@ internal class SettingsFragment : Fragment(R.layout.content_settings), View.OnCl autoRefreshSwitch.setOnCheckedChangeListener(this) helpCoursesButton.setOnClickListener(this) helpGradeButton.setOnClickListener(this) + view.findViewById(R.id.chip_help_ordering).setOnClickListener(this) colourCustomisationButton.setOnClickListener(this) view.findViewById(R.id.btnNoNotif).setOnClickListener(this) view.findViewById(R.id.btnCustomiseRingtone).setOnClickListener(this) @@ -148,6 +149,23 @@ internal class SettingsFragment : Fragment(R.layout.content_settings), View.OnCl } } + val orderingDropDownText = view.findViewById(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) @@ -437,6 +455,7 @@ internal class SettingsFragment : Fragment(R.layout.content_settings), View.OnCl 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() diff --git a/app/src/main/java/com/denizd/substitutionplan/models/Substitution.kt b/app/src/main/java/com/denizd/substitutionplan/models/Substitution.kt index 530cf27..305c875 100644 --- a/app/src/main/java/com/denizd/substitutionplan/models/Substitution.kt +++ b/app/src/main/java/com/denizd/substitutionplan/models/Substitution.kt @@ -14,7 +14,8 @@ internal data class Substitution( val teacher: String, val type: String, val priority: Int, - val date_priority: Int + val date_priority: Int, + val website_priority: Int ) { @PrimaryKey(autoGenerate = true) diff --git a/app/src/main/res/layout/content_settings.xml b/app/src/main/res/layout/content_settings.xml index c0cba9c..9869521 100644 --- a/app/src/main/res/layout/content_settings.xml +++ b/app/src/main/res/layout/content_settings.xml @@ -363,7 +363,6 @@ android:layout_height="wrap_content" android:layout_marginTop="8dp" android:layout_marginEnd="8dp" - android:layout_marginBottom="8dp" android:hint="@string/courses" android:importantForAutofill="no" android:textColorHint="@color/colorHint" @@ -371,7 +370,6 @@ app:boxStrokeWidth="1dp" app:layout_constraintStart_toStartOf="@+id/txtLayoutClasses" app:layout_constraintTop_toBottomOf="@+id/txtLayoutClasses" - app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toStartOf="@+id/chipHelpCourses"> + + + + + + + + diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index f11ec86..49c993d 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -157,4 +157,11 @@ Einloggen… Lade Login-Seite erneut Du bist eingeloggt! + + App-spezifisch + Website-Original + + Sortierweise + Informationen über Sortierweisen + Du kannst zwischen zwei Sortierweisen auswählen, welche die Reihenfolge der Einträge auf dem Vertretungsplan bestimmen.\n\nStandardmäßig ist \'App-spezifisch\' ausgewählt; dies bietet einen konsistenten Plan sortiert nach Klassen, dann nach Stunden.\n\n\'Website-Original\' bietet die Original-Reihenfolge der Website. Diese ist jedoch nicht konsistent, weswegen \'App-spezifisch\' standardmäßig ausgewählt ist. \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index bf4667e..c7d0d18 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -169,4 +169,11 @@ Logging in… Load login page again Login successful! + + App-specific + Website original + + Ordering system + Information on ordering systems + You may pick between two ordering systems that dictate the order in which the items on the substitution plan will appear in.\n\nThe default \'app-specific\' is an algorithm implemented in this app that provides a consistently-sorted substitution plan ordered just like the substitution plan on the website used to; sorted by classes, then by time.\n\n\'Website original\' offers the items on the substitution plan just like they\'re presented on the school website, but since these are not guaranteed to be consistent, \'app-specific\' is picked by default.