Archived
Started implementation of event update sheet
This commit is contained in:
@@ -3,6 +3,7 @@ package com.denizk0461.studip.adapter
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.denizk0461.studip.data.parseToMinutes
|
||||
import com.denizk0461.studip.model.StudIPEvent
|
||||
import com.denizk0461.studip.databinding.ItemEventBinding
|
||||
import java.util.*
|
||||
@@ -150,17 +151,6 @@ class StudIPEventItemAdapter(
|
||||
else -> Calendar.MONDAY
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a time stamp string to its numeric value in minutes.
|
||||
* Example: 13:20. (20 minutes) + (13 hours * 60 minutes) = 800 minutes.
|
||||
*
|
||||
* @return minute value of the string
|
||||
*/
|
||||
private fun String.parseToMinutes(): Int {
|
||||
val parts = split(":")
|
||||
return (parts[0].toInt() * 60) + parts[1].toInt()
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface used to evaluate clicks and long presses on a given item.
|
||||
*/
|
||||
|
||||
@@ -3,6 +3,18 @@ package com.denizk0461.studip.data
|
||||
/**
|
||||
* Miscellaneous functions and variables that don't belong into any specific class.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Converts a time stamp string to its numeric value in minutes.
|
||||
* Example: 13:20. (20 minutes) + (13 hours * 60 minutes) = 800 minutes.
|
||||
*
|
||||
* @return minute value of the string
|
||||
*/
|
||||
fun String.parseToMinutes(): Int {
|
||||
val parts = split(":")
|
||||
return (parts[0].toInt() * 60) + parts[1].toInt()
|
||||
}
|
||||
|
||||
object Misc {
|
||||
|
||||
// private val timeslotAcademicQuarter = mapOf(
|
||||
|
||||
@@ -76,6 +76,9 @@ class StudIPParser {
|
||||
// Retrieve the time slot and split it into start and end time stamps
|
||||
val timeSlot = entryInfo[0].split(" - ")
|
||||
|
||||
// Time the event starts at
|
||||
val eventStart = timeSlot[0]
|
||||
|
||||
// Construct the newly scraped Stud.IP event
|
||||
val event = StudIPEvent(
|
||||
id = id,
|
||||
@@ -83,8 +86,9 @@ class StudIPParser {
|
||||
lecturer = parsedLecturers,
|
||||
room = entryInfo[1],
|
||||
day = index,
|
||||
timeslotStart = timeSlot[0],
|
||||
timeslotStart = eventStart,
|
||||
timeslotEnd = timeSlot[1],
|
||||
timeslotId = eventStart.parseToMinutes(),
|
||||
)
|
||||
|
||||
// Add the new element to the temporary list
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
package com.denizk0461.studip.db
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.Query
|
||||
import androidx.room.*
|
||||
import com.denizk0461.studip.model.*
|
||||
|
||||
/**
|
||||
@@ -16,13 +14,29 @@ interface AppDAO {
|
||||
/* --- Stud.IP schedule events --- */
|
||||
|
||||
/**
|
||||
* Retrieves all Stud.IP events.
|
||||
* Retrieves all Stud.IP events, ordered by their timeslots, then their IDs.
|
||||
*
|
||||
* @return all Stud.IP events exposed through a LiveData object
|
||||
*/
|
||||
@get:Query("SELECT * FROM events ORDER BY id")
|
||||
@get:Query("SELECT * FROM events ORDER BY timeslotId, id")
|
||||
val allEvents: LiveData<List<StudIPEvent>>
|
||||
|
||||
/**
|
||||
* Updates a given Stud.IP element.
|
||||
*
|
||||
* @param event object to be updated
|
||||
*/
|
||||
@Update
|
||||
fun update(event: StudIPEvent)
|
||||
|
||||
/**
|
||||
* Updates a given Stud.IP element.
|
||||
*
|
||||
* @param event object to be updated
|
||||
*/
|
||||
@Delete
|
||||
fun delete(event: StudIPEvent)
|
||||
|
||||
/**
|
||||
* Inserts a Stud.IP event into the database.
|
||||
*
|
||||
|
||||
@@ -17,7 +17,7 @@ import com.denizk0461.studip.model.*
|
||||
OfferCategory::class,
|
||||
OfferItem::class
|
||||
],
|
||||
version = 12,
|
||||
version = 13,
|
||||
)
|
||||
abstract class AppDatabase : RoomDatabase() {
|
||||
|
||||
|
||||
@@ -51,6 +51,24 @@ class AppRepository(app: Application) {
|
||||
*/
|
||||
val allOffers: LiveData<List<CanteenOffer>> = dao.allOffers
|
||||
|
||||
/**
|
||||
* Updates a schedule element.
|
||||
*
|
||||
* @param event the event to update
|
||||
*/
|
||||
fun update(event: StudIPEvent) {
|
||||
dao.update(event)
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a schedule element.
|
||||
*
|
||||
* @param event the event to delete
|
||||
*/
|
||||
fun delete(event: StudIPEvent) {
|
||||
dao.delete(event)
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all canteen offer date objects.
|
||||
*
|
||||
@@ -147,18 +165,20 @@ class AppRepository(app: Application) {
|
||||
// --- settings preferences --- //
|
||||
|
||||
/**
|
||||
* Retrieves the user's preference on displaying allergens.
|
||||
* Retrieves ta user-set boolean preference.
|
||||
*
|
||||
* @return whether the user set this preference
|
||||
* @param pref preference to retrieve
|
||||
* @return whether the user set this preference
|
||||
*/
|
||||
fun getPreferenceAllergen(): Boolean = prefs.getBoolean("setting_allergen", false)
|
||||
fun getPreference(pref: SettingsPreferences): Boolean = prefs.getBoolean(pref.key, false)
|
||||
|
||||
/**
|
||||
* Updates the user's preference on displaying allergens.
|
||||
* Updates a user-set boolean preference.
|
||||
*
|
||||
* @param value new value to set the preference to
|
||||
* @param pref preference to set
|
||||
* @param newValue new value to set the preference to
|
||||
*/
|
||||
fun setPreferenceAllergen(value: Boolean) {
|
||||
prefs.edit().putBoolean("setting_allergen", value).apply()
|
||||
fun setPreference(pref: SettingsPreferences, newValue: Boolean) {
|
||||
prefs.edit().putBoolean(pref.key, newValue).apply()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.denizk0461.studip.dialog
|
||||
|
||||
import android.app.Dialog
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import android.app.TimePickerDialog
|
||||
import android.os.Bundle
|
||||
import android.widget.TimePicker
|
||||
|
||||
class TimePickerFragment(
|
||||
private val timestamp: String,
|
||||
private val listener: OnTimeSetListener,
|
||||
private val isEventStart: Boolean,
|
||||
) : DialogFragment(), TimePickerDialog.OnTimeSetListener {
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val timestampSplit = timestamp.split(":")
|
||||
return TimePickerDialog(activity, this, timestampSplit[0].toInt(), timestampSplit[1].toInt(), true)
|
||||
}
|
||||
|
||||
interface OnTimeSetListener {
|
||||
fun onTimeSet(hours: Int, minutes: Int, isEventStart: Boolean)
|
||||
}
|
||||
|
||||
override fun onTimeSet(picker: TimePicker?, hours: Int, minutes: Int) {
|
||||
listener.onTimeSet(hours, minutes, isEventStart)
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,8 @@ import com.denizk0461.studip.adapter.StudIPEventItemAdapter
|
||||
import com.denizk0461.studip.adapter.StudIPEventPageAdapter
|
||||
import com.denizk0461.studip.databinding.FragmentEventBinding
|
||||
import com.denizk0461.studip.model.StudIPEvent
|
||||
import com.denizk0461.studip.sheet.ScheduleUpdateSheet
|
||||
import com.denizk0461.studip.sheet.TextSheet
|
||||
import com.denizk0461.studip.viewmodel.EventViewModel
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
import java.util.*
|
||||
@@ -73,8 +75,13 @@ class EventFragment : AppFragment() {
|
||||
// TODO implement functionality or delete
|
||||
}
|
||||
override fun onLongClick(event: StudIPEvent): Boolean {
|
||||
// TODO implement functionality or delete
|
||||
return false
|
||||
// Open a bottom sheet to edit the event
|
||||
openBottomSheet(ScheduleUpdateSheet(event, onUpdate = { eventToUpdate ->
|
||||
viewModel.update(eventToUpdate)
|
||||
}, onDelete = { eventToDelete ->
|
||||
viewModel.delete(eventToDelete)
|
||||
}))
|
||||
return true
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -52,13 +52,31 @@ class SettingsFragment : AppFragment() {
|
||||
launchWebView()
|
||||
}
|
||||
|
||||
binding.switchAllergens.apply {
|
||||
isChecked = viewModel.preferenceAllergen
|
||||
setOnCheckedChangeListener { _, b ->
|
||||
viewModel.preferenceAllergen = b
|
||||
// Set up switch for highlighting the next course in the schedule
|
||||
binding.switchHighlight.apply {
|
||||
isChecked = viewModel.preferenceCourseHighlighting
|
||||
setOnCheckedChangeListener { _, newValue ->
|
||||
viewModel.preferenceCourseHighlighting = newValue
|
||||
}
|
||||
}
|
||||
|
||||
// Set up switch for displaying allergens
|
||||
binding.switchAllergens.apply {
|
||||
isChecked = viewModel.preferenceAllergen
|
||||
setOnCheckedChangeListener { _, newValue ->
|
||||
viewModel.preferenceAllergen = newValue
|
||||
}
|
||||
}
|
||||
|
||||
// Set up switch for crash report opt-in
|
||||
binding.switchCrashlytics.apply {
|
||||
isChecked = viewModel.preferenceDataHandling
|
||||
setOnCheckedChangeListener { _, newValue ->
|
||||
viewModel.preferenceDataHandling = newValue
|
||||
}
|
||||
}
|
||||
|
||||
// Set click listener for the data handling dialogue
|
||||
binding.buttonDataHandling.setOnClickListener {
|
||||
openBottomSheet(TextSheet(
|
||||
R.string.settings_data_sheet_header,
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.denizk0461.studip.model
|
||||
|
||||
/**
|
||||
* Enumeration class for user-set preferences that will be saved in persistent storage via
|
||||
* SharedPreferences.
|
||||
*
|
||||
* @param key key for the SharedPreferences transaction
|
||||
*/
|
||||
enum class SettingsPreferences(val key: String) {
|
||||
// Whether the user wants to have allergens displayed in the canteen overview
|
||||
ALLERGEN("setting_allergen"),
|
||||
// Whether the user wants the next course in his schedule to be highlighted
|
||||
COURSE_HIGHLIGHTING("setting_highlight"),
|
||||
// Whether the user opts into sending crash report
|
||||
DATA_HANDLING("setting_data_handling"),
|
||||
;
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import androidx.room.PrimaryKey
|
||||
* @param day day the event takes place on; 0 = Monday, 4 = Friday
|
||||
* @param timeslotStart time the event starts at
|
||||
* @param timeslotEnd time the event ends at
|
||||
* @param timeslotId minute the event starts at - used for ordering
|
||||
* @param colour user-defined colour the event will be shown in - UNIMPLEMENTED
|
||||
*/
|
||||
@Entity(tableName = "events")
|
||||
@@ -24,6 +25,7 @@ data class StudIPEvent(
|
||||
val day: Int,
|
||||
val timeslotStart: String,
|
||||
val timeslotEnd: String,
|
||||
val timeslotId: Int,
|
||||
val colour: Int = 0,
|
||||
) {
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ class AllergenSheet(
|
||||
private val category: String,
|
||||
) : AppSheet(R.layout.sheet_allergen) {
|
||||
|
||||
// View binding
|
||||
private val binding: SheetAllergenBinding by viewBinding(SheetAllergenBinding::bind)
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.denizk0461.studip.sheet
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import com.denizk0461.studip.R
|
||||
import com.denizk0461.studip.data.parseToMinutes
|
||||
import com.denizk0461.studip.data.viewBinding
|
||||
import com.denizk0461.studip.databinding.SheetScheduleUpdateBinding
|
||||
import com.denizk0461.studip.dialog.TimePickerFragment
|
||||
import com.denizk0461.studip.model.StudIPEvent
|
||||
|
||||
class ScheduleUpdateSheet(
|
||||
private val event: StudIPEvent,
|
||||
private val onUpdate: (event: StudIPEvent) -> Unit,
|
||||
private val onDelete: (event: StudIPEvent) -> Unit,
|
||||
) : AppSheet(R.layout.sheet_schedule_update), TimePickerFragment.OnTimeSetListener {
|
||||
|
||||
// Editable fields
|
||||
private var timeslotStart = event.timeslotStart
|
||||
private var timeslotEnd = event.timeslotEnd
|
||||
private var colour = event.colour
|
||||
|
||||
// View binding
|
||||
private val binding: SheetScheduleUpdateBinding by viewBinding(SheetScheduleUpdateBinding::bind)
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
binding.apply {
|
||||
editTextTitle.setText(event.title)
|
||||
editTextLecturers.setText(event.lecturer)
|
||||
editTextRoom.setText(event.room)
|
||||
}
|
||||
|
||||
binding.buttonDelete.setOnClickListener {
|
||||
onDelete(event)
|
||||
dismiss()
|
||||
}
|
||||
|
||||
binding.buttonSave.setOnClickListener {
|
||||
onUpdate(
|
||||
StudIPEvent(
|
||||
id = event.id,
|
||||
title = binding.editTextTitle.text.toString(),
|
||||
lecturer = binding.editTextLecturers.text.toString(),
|
||||
room = binding.editTextRoom.text.toString(),
|
||||
day = event.day,
|
||||
timeslotStart = timeslotStart,
|
||||
timeslotEnd = timeslotEnd,
|
||||
timeslotId = timeslotStart.parseToMinutes(),
|
||||
colour = colour,
|
||||
)
|
||||
)
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
override fun onTimeSet(hours: Int, minutes: Int, isEventStart: Boolean) {
|
||||
if (isEventStart) {
|
||||
timeslotStart = "$hours:$minutes"
|
||||
} else {
|
||||
timeslotEnd = "$hours:$minutes"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,11 +18,13 @@ class TextSheet(
|
||||
@StringRes private val content: Int
|
||||
) : AppSheet(R.layout.sheet_text) {
|
||||
|
||||
// View binding
|
||||
private val binding: SheetTextBinding by viewBinding(SheetTextBinding::bind)
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
// Set text values
|
||||
binding.apply {
|
||||
textHeader.text = getString(header)
|
||||
textContent.text = getString(content)
|
||||
|
||||
@@ -3,10 +3,7 @@ package com.denizk0461.studip.viewmodel
|
||||
import android.app.Application
|
||||
import androidx.lifecycle.LiveData
|
||||
import com.denizk0461.studip.data.StwParser
|
||||
import com.denizk0461.studip.model.CanteenOffer
|
||||
import com.denizk0461.studip.model.DietaryPrefObject
|
||||
import com.denizk0461.studip.model.DietaryPreferences
|
||||
import com.denizk0461.studip.model.OfferDate
|
||||
import com.denizk0461.studip.model.*
|
||||
|
||||
/**
|
||||
* View model for [com.denizk0461.studip.fragment.CanteenFragment]
|
||||
@@ -66,5 +63,5 @@ class CanteenViewModel(app: Application) : AppViewModel(app) {
|
||||
* This value determines whether the user wants to have allergens marked.
|
||||
*/
|
||||
val preferenceAllergen: Boolean
|
||||
get() = repo.getPreferenceAllergen()
|
||||
get() = repo.getPreference(SettingsPreferences.ALLERGEN)
|
||||
}
|
||||
@@ -17,4 +17,18 @@ class EventViewModel(app: Application) : AppViewModel(app) {
|
||||
* @return all Stud.IP events exposed through a LiveData object
|
||||
*/
|
||||
val allEvents: LiveData<List<StudIPEvent>> = repo.allEvents
|
||||
|
||||
/**
|
||||
* Updates a schedule element.
|
||||
*
|
||||
* @param event the event to update
|
||||
*/
|
||||
fun update(event: StudIPEvent) { doAsync { repo.update(event) } }
|
||||
|
||||
/**
|
||||
* Deletes a schedule element.
|
||||
*
|
||||
* @param event the event to delete
|
||||
*/
|
||||
fun delete(event: StudIPEvent) { doAsync { repo.delete(event) } }
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.denizk0461.studip.viewmodel
|
||||
|
||||
import android.app.Application
|
||||
import com.denizk0461.studip.model.SettingsPreferences
|
||||
|
||||
/**
|
||||
* View model for [com.denizk0461.studip.fragment.SettingsFragment]
|
||||
@@ -9,10 +10,24 @@ import android.app.Application
|
||||
*/
|
||||
class SettingsViewModel(app: Application) : AppViewModel(app) {
|
||||
|
||||
/**
|
||||
* This value determines whether the user opts into submitting crash reports.
|
||||
*/
|
||||
var preferenceCourseHighlighting: Boolean
|
||||
get() = repo.getPreference(SettingsPreferences.DATA_HANDLING)
|
||||
set(newValue) { repo.setPreference(SettingsPreferences.DATA_HANDLING, newValue) }
|
||||
|
||||
/**
|
||||
* This value determines whether the user wants to have allergens marked.
|
||||
*/
|
||||
var preferenceAllergen: Boolean
|
||||
get() = repo.getPreferenceAllergen()
|
||||
set(value) { repo.setPreferenceAllergen(value) }
|
||||
get() = repo.getPreference(SettingsPreferences.ALLERGEN)
|
||||
set(newValue) { repo.setPreference(SettingsPreferences.ALLERGEN, newValue) }
|
||||
|
||||
/**
|
||||
* This value determines whether the user opts into submitting crash reports.
|
||||
*/
|
||||
var preferenceDataHandling: Boolean
|
||||
get() = repo.getPreference(SettingsPreferences.DATA_HANDLING)
|
||||
set(newValue) { repo.setPreference(SettingsPreferences.DATA_HANDLING, newValue) }
|
||||
}
|
||||
Reference in New Issue
Block a user