Archived
Added opening hours and a button for the user to view them, but the formatting sucks
This commit is contained in:
@@ -94,8 +94,23 @@ class StwParser {
|
|||||||
// Parse the HTML using Jsoup to traverse the document
|
// Parse the HTML using Jsoup to traverse the document
|
||||||
val doc = Jsoup.connect(url).get()
|
val doc = Jsoup.connect(url).get()
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Retrieve the opening hours for the canteen.
|
||||||
|
* TODO this formatting sucks
|
||||||
|
*/
|
||||||
|
var openingHours = ""
|
||||||
|
doc.getElementsByClass("details-wrapper")[0].getElementsByTag("p").forEach { p ->
|
||||||
|
openingHours += "${p.text()}\n"
|
||||||
|
}
|
||||||
|
|
||||||
// Save the canteen to persistent storage
|
// Save the canteen to persistent storage
|
||||||
repo.insert(OfferCanteen(canteenId, doc.getElementsByClass("pane-title")[1].text()))
|
repo.insert(
|
||||||
|
OfferCanteen(
|
||||||
|
canteenId,
|
||||||
|
doc.getElementsByClass("pane-title")[1].text(),
|
||||||
|
openingHours,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
// Iterate through each day for which offers are available
|
// Iterate through each day for which offers are available
|
||||||
doc.getElementsByClass("food-plan").forEach { dayPlan ->
|
doc.getElementsByClass("food-plan").forEach { dayPlan ->
|
||||||
|
|||||||
@@ -148,4 +148,12 @@ interface AppDAO {
|
|||||||
* @param item object to be saved to the database
|
* @param item object to be saved to the database
|
||||||
*/
|
*/
|
||||||
@Insert fun insert(item: OfferItem)
|
@Insert fun insert(item: OfferItem)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the opening hours of the canteen as a string.
|
||||||
|
*
|
||||||
|
* @return opening hours
|
||||||
|
*/
|
||||||
|
@Query("SELECT openingHours FROM offer_canteen LIMIT 1")
|
||||||
|
fun getCanteenOpeningHours(): String
|
||||||
}
|
}
|
||||||
@@ -17,7 +17,7 @@ import com.denizk0461.studip.model.*
|
|||||||
OfferCategory::class,
|
OfferCategory::class,
|
||||||
OfferItem::class
|
OfferItem::class
|
||||||
],
|
],
|
||||||
version = 13,
|
version = 14,
|
||||||
)
|
)
|
||||||
abstract class AppDatabase : RoomDatabase() {
|
abstract class AppDatabase : RoomDatabase() {
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,13 @@ class AppRepository(app: Application) {
|
|||||||
*/
|
*/
|
||||||
fun nukeEvents() { dao.nukeEvents() }
|
fun nukeEvents() { dao.nukeEvents() }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the opening hours of the canteen as a string.
|
||||||
|
*
|
||||||
|
* @return opening hours
|
||||||
|
*/
|
||||||
|
fun getCanteenOpeningHours() = dao.getCanteenOpeningHours()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves all canteen offers.
|
* Retrieves all canteen offers.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import com.denizk0461.studip.adapter.CanteenOfferPageAdapter
|
|||||||
import com.denizk0461.studip.databinding.FragmentCanteenBinding
|
import com.denizk0461.studip.databinding.FragmentCanteenBinding
|
||||||
import com.denizk0461.studip.model.*
|
import com.denizk0461.studip.model.*
|
||||||
import com.denizk0461.studip.sheet.AllergenSheet
|
import com.denizk0461.studip.sheet.AllergenSheet
|
||||||
|
import com.denizk0461.studip.sheet.TextSheet
|
||||||
import com.denizk0461.studip.viewmodel.CanteenViewModel
|
import com.denizk0461.studip.viewmodel.CanteenViewModel
|
||||||
import com.google.android.material.tabs.TabLayoutMediator
|
import com.google.android.material.tabs.TabLayoutMediator
|
||||||
|
|
||||||
@@ -47,6 +48,8 @@ class CanteenFragment : AppFragment(), CanteenOfferItemAdapter.OnClickListener {
|
|||||||
// Used if no preference has been set or none can be found
|
// Used if no preference has been set or none can be found
|
||||||
private val emptyPreferenceRegex: String = ".........."
|
private val emptyPreferenceRegex: String = ".........."
|
||||||
|
|
||||||
|
private var openingHours = ""
|
||||||
|
|
||||||
// Instantiate the view binding
|
// Instantiate the view binding
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||||
_binding = FragmentCanteenBinding.inflate(inflater, container, false)
|
_binding = FragmentCanteenBinding.inflate(inflater, container, false)
|
||||||
@@ -73,6 +76,9 @@ class CanteenFragment : AppFragment(), CanteenOfferItemAdapter.OnClickListener {
|
|||||||
R.id.mensa_hfk -> 9
|
R.id.mensa_hfk -> 9
|
||||||
else -> 0
|
else -> 0
|
||||||
}
|
}
|
||||||
|
// Set currently selected canteen to the button
|
||||||
|
binding.buttonCanteenPicker.text = getCurrentlySelectedCanteenName()
|
||||||
|
refresh()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
inflate(R.menu.menu_canteens)
|
inflate(R.menu.menu_canteens)
|
||||||
@@ -80,6 +86,18 @@ class CanteenFragment : AppFragment(), CanteenOfferItemAdapter.OnClickListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
binding.buttonInfo.setOnClickListener {
|
||||||
|
openBottomSheet(
|
||||||
|
TextSheet(
|
||||||
|
getString(
|
||||||
|
R.string.canteen_opening_hours,
|
||||||
|
getCurrentlySelectedCanteenName()
|
||||||
|
),
|
||||||
|
openingHours
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Assign a preference value to every button to filter for dietary preferences
|
// Assign a preference value to every button to filter for dietary preferences
|
||||||
val chipMap = mapOf(
|
val chipMap = mapOf(
|
||||||
@@ -146,6 +164,9 @@ class CanteenFragment : AppFragment(), CanteenOfferItemAdapter.OnClickListener {
|
|||||||
// Update the item list in the view pager's adapter
|
// Update the item list in the view pager's adapter
|
||||||
viewPagerAdapter.setNewItems(groupedElements, dateSize)
|
viewPagerAdapter.setNewItems(groupedElements, dateSize)
|
||||||
|
|
||||||
|
// Set the text for the opening hours dialogue
|
||||||
|
openingHours = viewModel.getCanteenOpeningHours()
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tell the swipe refresh layout to stop refreshing.
|
* Tell the swipe refresh layout to stop refreshing.
|
||||||
* TODO if an exception is raised, this will not be fired. This must be changed
|
* TODO if an exception is raised, this will not be fired. This must be changed
|
||||||
@@ -155,14 +176,7 @@ class CanteenFragment : AppFragment(), CanteenOfferItemAdapter.OnClickListener {
|
|||||||
|
|
||||||
// Set up functions for when the user swipes to refresh the view
|
// Set up functions for when the user swipes to refresh the view
|
||||||
binding.swipeRefreshLayout.setOnRefreshListener {
|
binding.swipeRefreshLayout.setOnRefreshListener {
|
||||||
// Retrieve new offers from the website(s)
|
refresh()
|
||||||
viewModel.fetchOffers(viewModel.preferenceCanteen, onRefreshUpdate = { status ->
|
|
||||||
// TODO refresh updates
|
|
||||||
}, onFinish = {
|
|
||||||
// createTabLayoutMediator()
|
|
||||||
// binding.swipeRefreshLayout.isRefreshing = false
|
|
||||||
// createTabLayoutMediator()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,7 +193,6 @@ class CanteenFragment : AppFragment(), CanteenOfferItemAdapter.OnClickListener {
|
|||||||
TabLayoutMediator(binding.dayTabLayout, binding.viewPager) { tab, position ->
|
TabLayoutMediator(binding.dayTabLayout, binding.viewPager) { tab, position ->
|
||||||
tab.text = dates[position].date
|
tab.text = dates[position].date
|
||||||
}.attach()
|
}.attach()
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -303,6 +316,41 @@ class CanteenFragment : AppFragment(), CanteenOfferItemAdapter.OnClickListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the localised string for the canteen selected by the user.
|
||||||
|
*
|
||||||
|
* @return the localised canteen name
|
||||||
|
*/
|
||||||
|
private fun getCurrentlySelectedCanteenName(): String = getString(
|
||||||
|
when (viewModel.preferenceCanteen) {
|
||||||
|
0 -> R.string.mensa_uni
|
||||||
|
1 -> R.string.cafe_central
|
||||||
|
2 -> R.string.mensa_nw1
|
||||||
|
3 -> R.string.cafeteria_gw2
|
||||||
|
4 -> R.string.mensa_neustadt
|
||||||
|
5 -> R.string.mensa_werder
|
||||||
|
6 -> R.string.mensa_airport
|
||||||
|
7 -> R.string.mensa_bhv
|
||||||
|
8 -> R.string.cafeteria_bhv
|
||||||
|
9 -> R.string.mensa_hfk
|
||||||
|
else -> R.string.mensa_uni
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Downloads the canteen offers and refreshes them in the app.
|
||||||
|
*/
|
||||||
|
private fun refresh() {
|
||||||
|
// Retrieve new offers from the website(s)
|
||||||
|
viewModel.fetchOffers(viewModel.preferenceCanteen, onRefreshUpdate = { status ->
|
||||||
|
// TODO refresh updates
|
||||||
|
}, onFinish = {
|
||||||
|
// createTabLayoutMediator()
|
||||||
|
// binding.swipeRefreshLayout.isRefreshing = false
|
||||||
|
// createTabLayoutMediator()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executed when an item has been clicked.
|
* Executed when an item has been clicked.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -87,8 +87,8 @@ class SettingsFragment : AppFragment() {
|
|||||||
// Set click listener for the data handling dialogue
|
// Set click listener for the data handling dialogue
|
||||||
binding.buttonDataHandling.setOnClickListener {
|
binding.buttonDataHandling.setOnClickListener {
|
||||||
openBottomSheet(TextSheet(
|
openBottomSheet(TextSheet(
|
||||||
R.string.settings_data_sheet_header,
|
getString(R.string.settings_data_sheet_header),
|
||||||
R.string.settings_data_sheet_content
|
getString(R.string.settings_data_sheet_content),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,9 @@ import androidx.room.PrimaryKey
|
|||||||
/**
|
/**
|
||||||
* Entity for binding several canteen items to a specific date. Registered in the app database.
|
* Entity for binding several canteen items to a specific date. Registered in the app database.
|
||||||
*
|
*
|
||||||
* @param id primary key that uniquely identifies the item
|
* @param id primary key that uniquely identifies the item
|
||||||
* @param canteen name of the canteen
|
* @param canteen name of the canteen
|
||||||
|
* @param openingHours opening hours of the canteen
|
||||||
*/
|
*/
|
||||||
@Entity(
|
@Entity(
|
||||||
tableName = "offer_canteen",
|
tableName = "offer_canteen",
|
||||||
@@ -15,4 +16,5 @@ import androidx.room.PrimaryKey
|
|||||||
data class OfferCanteen(
|
data class OfferCanteen(
|
||||||
@PrimaryKey val id: Int,
|
@PrimaryKey val id: Int,
|
||||||
val canteen: String,
|
val canteen: String,
|
||||||
|
val openingHours: String,
|
||||||
)
|
)
|
||||||
@@ -14,8 +14,8 @@ import com.denizk0461.studip.databinding.SheetTextBinding
|
|||||||
* @param content content text for the window
|
* @param content content text for the window
|
||||||
*/
|
*/
|
||||||
class TextSheet(
|
class TextSheet(
|
||||||
@StringRes private val header: Int,
|
private val header: String,
|
||||||
@StringRes private val content: Int
|
private val content: String,
|
||||||
) : AppSheet(R.layout.sheet_text) {
|
) : AppSheet(R.layout.sheet_text) {
|
||||||
|
|
||||||
// View binding
|
// View binding
|
||||||
@@ -26,8 +26,8 @@ class TextSheet(
|
|||||||
|
|
||||||
// Set text values
|
// Set text values
|
||||||
binding.apply {
|
binding.apply {
|
||||||
textHeader.text = getString(header)
|
textHeader.text = header
|
||||||
textContent.text = getString(content)
|
textContent.text = content
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -36,6 +36,13 @@ class CanteenViewModel(app: Application) : AppViewModel(app) {
|
|||||||
*/
|
*/
|
||||||
fun getDates(): List<OfferDate> = returnBlocking { repo.getDates() }
|
fun getDates(): List<OfferDate> = returnBlocking { repo.getDates() }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the opening hours of the canteen as a string.
|
||||||
|
*
|
||||||
|
* @return opening hours
|
||||||
|
*/
|
||||||
|
fun getCanteenOpeningHours(): String = returnBlocking { repo.getCanteenOpeningHours() }
|
||||||
|
|
||||||
// Fetch the canteen offers asynchronously. Updates will be provided through a LiveData object.
|
// Fetch the canteen offers asynchronously. Updates will be provided through a LiveData object.
|
||||||
fun fetchOffers(canteen: Int, onRefreshUpdate: (status: Int) -> Unit, onFinish: () -> Unit) {
|
fun fetchOffers(canteen: Int, onRefreshUpdate: (status: Int) -> Unit, onFinish: () -> Unit) {
|
||||||
doAsync { parser.parse(canteen, onRefreshUpdate, onFinish) }
|
doAsync { parser.parse(canteen, onRefreshUpdate, onFinish) }
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<vector android:height="24dp" android:tint="#000000"
|
||||||
|
android:viewportHeight="24" android:viewportWidth="24"
|
||||||
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,17h-2v-6h2v6zM13,9h-2L11,7h2v2z"/>
|
||||||
|
</vector>
|
||||||
@@ -42,6 +42,18 @@
|
|||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"/>
|
app:layout_constraintStart_toStartOf="parent"/>
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
style="@style/Widget.Material3.Button.TextButton"
|
||||||
|
android:id="@+id/button_info"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:minWidth="0dp"
|
||||||
|
app:icon="@drawable/info"
|
||||||
|
app:iconPadding="0dp"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:iconTint="?attr/colorOnSurfaceVariant"/>
|
||||||
|
|
||||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
android:id="@+id/swipe_refresh_layout"
|
android:id="@+id/swipe_refresh_layout"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
|
|||||||
@@ -23,6 +23,8 @@
|
|||||||
<string name="title_food">Mensenangebote</string>
|
<string name="title_food">Mensenangebote</string>
|
||||||
<string name="title_settings">App-Einstellungen</string>
|
<string name="title_settings">App-Einstellungen</string>
|
||||||
|
|
||||||
|
<string name="canteen_opening_hours">%s – Öffnungszeiten</string>
|
||||||
|
|
||||||
<string name="mensa_uni">Uni-Mensa</string>
|
<string name="mensa_uni">Uni-Mensa</string>
|
||||||
<string name="cafe_central">Café Central</string>
|
<string name="cafe_central">Café Central</string>
|
||||||
<string name="mensa_nw1">Mensa NW1</string>
|
<string name="mensa_nw1">Mensa NW1</string>
|
||||||
|
|||||||
@@ -24,6 +24,8 @@
|
|||||||
<string name="title_food">Canteen Offers</string>
|
<string name="title_food">Canteen Offers</string>
|
||||||
<string name="title_settings">App Settings</string>
|
<string name="title_settings">App Settings</string>
|
||||||
|
|
||||||
|
<string name="canteen_opening_hours">%s – Opening Hours</string>
|
||||||
|
|
||||||
<string name="mensa_uni">Uni-Mensa</string>
|
<string name="mensa_uni">Uni-Mensa</string>
|
||||||
<string name="cafe_central">Café Central</string>
|
<string name="cafe_central">Café Central</string>
|
||||||
<string name="mensa_nw1">Mensa NW1</string>
|
<string name="mensa_nw1">Mensa NW1</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user