Archived
User can now add, edit, and delete timetables without crashing (hopefully)
This commit is contained in:
@@ -164,6 +164,12 @@ class AppRepository(app: Application) {
|
||||
|
||||
fun insertTimetable(timetable: Timetable) {
|
||||
dao.insertTimetable(timetable)
|
||||
|
||||
/*
|
||||
* require-non-null can be done here as we're adding an entry to this table beforehand,
|
||||
* which guarantees that the element will not be null
|
||||
*/
|
||||
setPreferenceSelectedTimetable(dao.getLargestTimetableId()!!)
|
||||
}
|
||||
|
||||
fun updateTimetable(timetable: Timetable) { dao.updateTimetable(timetable) }
|
||||
@@ -174,7 +180,10 @@ class AppRepository(app: Application) {
|
||||
|
||||
fun getTimetableForId(id: Int): Timetable = dao.getTimetableForId(id)
|
||||
|
||||
fun deleteTimetable(id: Int) { dao.deleteTimetable(id) }
|
||||
fun deleteTimetable(id: Int) {
|
||||
dao.deleteTimetable(id)
|
||||
setPreferenceSelectedTimetable(dao.getLargestTimetableId() ?: 0)
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all canteen offer date objects.
|
||||
|
||||
@@ -56,6 +56,9 @@ class EventFragment : AppFragment<FragmentEventBinding>() {
|
||||
}
|
||||
}
|
||||
|
||||
// Set the title to be selected so it scrolls (marquee)
|
||||
binding.appTitleBar.isSelected = true
|
||||
|
||||
// Get localised weekday names
|
||||
weekdays = context.resources?.getStringArray(R.array.weekdays) ?: arrayOf()
|
||||
|
||||
@@ -113,6 +116,12 @@ class EventFragment : AppFragment<FragmentEventBinding>() {
|
||||
|
||||
// Set visibility of the fetch button depending on whether any events have been stored
|
||||
viewModel.getEventCount().observe(viewLifecycleOwner) { eventCount ->
|
||||
|
||||
val timetableName = viewModel.getSelectedTimetableName()
|
||||
if (timetableName.isNotBlank()) {
|
||||
binding.appTitleBar.text = timetableName
|
||||
}
|
||||
|
||||
binding.buttonFetchSchedule.visibility = if (eventCount == 0) {
|
||||
View.VISIBLE
|
||||
} else {
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.denizk0461.weserplaner.databinding.FragmentSettingsBinding
|
||||
import com.denizk0461.weserplaner.model.FormattedDate
|
||||
import com.denizk0461.weserplaner.model.Timetable
|
||||
import com.denizk0461.weserplaner.sheet.AllergenConfigSheet
|
||||
import com.denizk0461.weserplaner.sheet.TimetableAddSheet
|
||||
import com.denizk0461.weserplaner.sheet.TimetableEditSheet
|
||||
import com.denizk0461.weserplaner.values.AppLayout
|
||||
import com.denizk0461.weserplaner.viewmodel.SettingsViewModel
|
||||
@@ -112,6 +113,10 @@ class SettingsFragment : AppFragment<FragmentSettingsBinding>() {
|
||||
binding.autoCompleteTimetable.setText(timetableAdapter.getItem(position), false)
|
||||
}
|
||||
|
||||
binding.buttonAddTimetable.setOnClickListener {
|
||||
openBottomSheet(TimetableAddSheet())
|
||||
}
|
||||
|
||||
binding.buttonEditTimetable.setOnClickListener {
|
||||
if (binding.autoCompleteTimetable.text.isBlank()) {
|
||||
context.theme.showErrorSnackBar(
|
||||
|
||||
@@ -12,6 +12,6 @@ import androidx.room.PrimaryKey
|
||||
*/
|
||||
@Entity(tableName = "timetables")
|
||||
data class Timetable(
|
||||
@PrimaryKey(autoGenerate = true) val id: Int,
|
||||
@PrimaryKey(autoGenerate = true) val id: Int = 0,
|
||||
val name: String,
|
||||
)
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.denizk0461.weserplaner.sheet
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.navigation.fragment.NavHostFragment
|
||||
import com.denizk0461.weserplaner.R
|
||||
import com.denizk0461.weserplaner.data.viewBinding
|
||||
import com.denizk0461.weserplaner.databinding.SheetTimetableAddBinding
|
||||
import com.denizk0461.weserplaner.fragment.SettingsFragment
|
||||
import com.denizk0461.weserplaner.model.Timetable
|
||||
import com.denizk0461.weserplaner.viewmodel.SheetTimetableAddViewModel
|
||||
|
||||
class TimetableAddSheet : AppSheet(R.layout.sheet_timetable_add) {
|
||||
|
||||
// View binding
|
||||
private val binding: SheetTimetableAddBinding by viewBinding(SheetTimetableAddBinding::bind)
|
||||
|
||||
// View model
|
||||
private val viewModel: SheetTimetableAddViewModel by viewModels()
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
// Set up FAB behaviour for parent fragment's FAB if activity is not null
|
||||
val parentFragment = activity?.let { activity ->
|
||||
// Retrieve parent fragment to access its functions
|
||||
val navHostFragment = activity
|
||||
.supportFragmentManager
|
||||
.fragments[0] as NavHostFragment
|
||||
navHostFragment
|
||||
.childFragmentManager
|
||||
.primaryNavigationFragment as SettingsFragment
|
||||
}
|
||||
|
||||
binding.buttonCancel.setOnClickListener {
|
||||
dismiss()
|
||||
}
|
||||
|
||||
binding.buttonSave.setOnClickListener {
|
||||
viewModel.insertTimetable(Timetable(name = binding.editTextTitle.text.toString().trim()))
|
||||
|
||||
// Tell the user that the event has been updated
|
||||
parentFragment?.showSnackBar(
|
||||
getString(R.string.settings_timetable_sheet_confirm_add)
|
||||
)
|
||||
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import com.denizk0461.weserplaner.values.AppLayout
|
||||
*
|
||||
* @param app reference to the app
|
||||
*/
|
||||
class EventViewModel(app: Application) : AppViewModel(app) {
|
||||
class EventViewModel(private val app: Application) : AppViewModel(app) {
|
||||
|
||||
/**
|
||||
* Retrieves the number of Stud.IP events available in the database.
|
||||
@@ -18,6 +18,14 @@ class EventViewModel(app: Application) : AppViewModel(app) {
|
||||
*/
|
||||
fun getEventCount(): LiveData<Int> = repo.getEventCount()
|
||||
|
||||
fun getSelectedTimetableName(): String = returnBlocking {
|
||||
try {
|
||||
repo.getTimetableForId(repo.getPreferenceSelectedTimetable()).name
|
||||
} catch (e: NullPointerException) {
|
||||
""
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This value determines whether the user wants their timetable to launch with the current day.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.denizk0461.weserplaner.viewmodel
|
||||
|
||||
import android.app.Application
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.denizk0461.weserplaner.model.Timetable
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class SheetTimetableAddViewModel(application: Application) : AppViewModel(application) {
|
||||
|
||||
fun insertTimetable(timetable: Timetable) { viewModelScope.launch(Dispatchers.IO) { repo.insertTimetable(timetable) }}
|
||||
}
|
||||
@@ -144,45 +144,55 @@
|
||||
android:text="@string/settings_selected_timetable_header"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/text_layout_timetable"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
android:hint="@string/settings_selected_timetable_hint"
|
||||
app:boxStrokeColor="@color/selector_text_input"
|
||||
app:hintTextColor="@color/selector_text_input">
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/text_layout_timetable"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
|
||||
android:layout_width="0dp"
|
||||
<com.google.android.material.textfield.MaterialAutoCompleteTextView
|
||||
android:id="@+id/auto_complete_timetable"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:hint="@string/settings_selected_timetable_hint"
|
||||
app:boxStrokeColor="@color/selector_text_input"
|
||||
app:hintTextColor="@color/selector_text_input">
|
||||
android:textColor="?attr/colorOnSurfaceVariant"
|
||||
android:lines="1"
|
||||
android:maxLines="1"
|
||||
tools:text="asdf asdf asdf asdf asdf ??? asdf asdf asdf asdf asdf asdf asdf asdf asdf"
|
||||
android:inputType="text"
|
||||
android:clickable="false"
|
||||
android:focusable="false"/>
|
||||
|
||||
<com.google.android.material.textfield.MaterialAutoCompleteTextView
|
||||
android:id="@+id/auto_complete_timetable"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="?attr/colorOnSurfaceVariant"
|
||||
android:inputType="none"/>
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
style="@style/Widget.Material3.Button.IconButton.Outlined"
|
||||
android:id="@+id/button_edit_timetable"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:minWidth="0dp"
|
||||
app:icon="@drawable/edit"
|
||||
app:iconPadding="0dp"
|
||||
app:strokeColor="?attr/colorOutlineVariant"
|
||||
app:iconTint="?attr/colorOnSurfaceVariant"
|
||||
tools:ignore="UnusedAttribute"
|
||||
android:tooltipText="@string/settings_selected_timetable_edit_button_hint"/>
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:paddingHorizontal="16dp">
|
||||
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
<com.google.android.material.button.MaterialButton
|
||||
style="@style/Widget.Material3.Button.OutlinedButton"
|
||||
android:id="@+id/button_add_timetable"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/settings_timetable_button_add"
|
||||
app:strokeColor="?attr/colorOutlineVariant"
|
||||
android:layout_marginEnd="8dp"/>
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
style="@style/Widget.Material3.Button.OutlinedButton"
|
||||
android:id="@+id/button_edit_timetable"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/settings_timetable_button_edit"
|
||||
app:strokeColor="?attr/colorOutlineVariant"/>
|
||||
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/sheet"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.google.android.material.bottomsheet.BottomSheetDragHandleView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
style="@style/SheetCloseButton"
|
||||
android:id="@+id/button_cancel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/sheet_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="22sp"
|
||||
android:paddingHorizontal="24dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
app:fontFamily="@font/lato_blackitalic"
|
||||
android:text="@string/settings_timetable_sheet_header_add"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/button_cancel"/>
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:scrollbars="vertical">
|
||||
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="16dp"
|
||||
android:paddingHorizontal="24dp">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/settings_timetable_add_hint"/>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||
android:id="@+id/text_layout_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:hint="@string/settings_selected_timetable_hint"
|
||||
app:boxStrokeColor="@color/selector_text_input"
|
||||
app:hintTextColor="@color/selector_text_input">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
style="@style/ThemeOverlay.Material3.TextInputEditText.OutlinedBox"
|
||||
android:textColor="?attr/colorOnSurfaceVariant"
|
||||
android:id="@+id/edit_text_title"
|
||||
android:inputType="text"
|
||||
android:maxLines="1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:id="@+id/button_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="end"
|
||||
android:layout_marginVertical="8dp"
|
||||
android:animateLayoutChanges="true">
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/button_save"
|
||||
style="@style/Widget.Material3.Button.TonalButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/save"
|
||||
app:icon="@drawable/save"/>
|
||||
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
@@ -70,6 +70,8 @@
|
||||
style="@style/ThemeOverlay.Material3.TextInputEditText.OutlinedBox"
|
||||
android:textColor="?attr/colorOnSurfaceVariant"
|
||||
android:id="@+id/edit_text_title"
|
||||
android:inputType="text"
|
||||
android:maxLines="1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
|
||||
@@ -249,11 +249,17 @@
|
||||
<string name="settings_selected_timetable_header">Wähle, welchen Stundenplan einzusehen</string>
|
||||
<string name="settings_selected_timetable_hint">Stundenplan</string>
|
||||
<string name="settings_selected_timetable_edit_button_hint">Stundenplan bearbeiten</string>
|
||||
<string name="settings_selected_timetable_edit_text_title">Name des Stundenplans</string>
|
||||
<string name="settings_timetable_button_add">Hinzufügen</string>
|
||||
<string name="settings_timetable_button_edit">Bearbeiten</string>
|
||||
<string name="settings_timetable_sheet_header">Diesen Stundenplan bearbeiten</string>
|
||||
<string name="settings_timetable_sheet_header_add">Neuen Stundenplan hinzufügen</string>
|
||||
<string name="settings_timetable_edit_fail">Es gibt keinen Stundenplan zum bearbeiten!</string>
|
||||
<string name="settings_timetable_sheet_confirm_save">Stundenplan wurde aktualisiert.</string>
|
||||
<string name="settings_timetable_sheet_confirm_add">Stundenplan wurde hinzugefügt.</string>
|
||||
<string name="settings_timetable_sheet_confirm_delete">Stundenplan wurde gelöscht.</string>
|
||||
<string name="settings_timetable_sheet_delete_confirm">Sicher?</string>
|
||||
<string name="settings_timetable_add_hint">Hinweis: wenn du einen Stundenplan von Stud.IP herunterlädst, wird dieser automatisch als neuer Stundenplan hinzugefügt, also musst du in diesem Fall hier nichts machen!</string>
|
||||
|
||||
<string name="settings_current_day_title">Starte Stundenplan am heutigen Tag</string>
|
||||
<string name="settings_current_day_subtitle">Ansonsten wird Montag beim Start angezeigt</string>
|
||||
|
||||
@@ -254,11 +254,17 @@
|
||||
<string name="settings_selected_timetable_header">Select which timetable to display</string>
|
||||
<string name="settings_selected_timetable_hint">Timetable</string>
|
||||
<string name="settings_selected_timetable_edit_button_hint">Edit timetable</string>
|
||||
<string name="settings_selected_timetable_edit_text_title">Timetable name</string>
|
||||
<string name="settings_timetable_button_add">Add</string>
|
||||
<string name="settings_timetable_button_edit">Edit</string>
|
||||
<string name="settings_timetable_sheet_header">Edit this timetable</string>
|
||||
<string name="settings_timetable_sheet_header_add">Add a new timetable</string>
|
||||
<string name="settings_timetable_edit_fail">There is no timetable to edit!</string>
|
||||
<string name="settings_timetable_sheet_confirm_save">Timetable has been updated.</string>
|
||||
<string name="settings_timetable_sheet_confirm_add">Timetable has been added.</string>
|
||||
<string name="settings_timetable_sheet_confirm_delete">Timetable has been deleted.</string>
|
||||
<string name="settings_timetable_sheet_delete_confirm">Sure?</string>
|
||||
<string name="settings_timetable_add_hint">Hint: if you download a timetable from Stud.IP, it automatically gets added as a new timetable, so you won\'t need to do anything here!</string>
|
||||
|
||||
<string name="settings_current_day_title">Launch timetable on current day</string>
|
||||
<string name="settings_current_day_subtitle">If unselected, Monday will be shown on launch instead</string>
|
||||
|
||||
Reference in New Issue
Block a user