From 5543eb4e324db371d6a9cc4f0387d50e05c9a7a9 Mon Sep 17 00:00:00 2001 From: denizk0461 Date: Sun, 16 Apr 2023 18:19:06 +0200 Subject: [PATCH] Implemented canteen scraper/parser functionality --- .../studip/activity/MainActivity.kt | 4 +- .../studip/adapter/StudIPEventAdapter.kt | 4 +- .../com/denizk0461/studip/data/StwParser.kt | 144 ++++++++++++++++++ .../java/com/denizk0461/studip/db/EventDAO.kt | 10 ++ .../com/denizk0461/studip/db/EventDatabase.kt | 3 +- .../denizk0461/studip/db/EventRepository.kt | 8 +- .../studip/fragment/CanteenFragment.kt | 46 ++++++ .../studip/fragment/EventFragment.kt | 21 +-- .../studip/fragment/FoodFragment.kt | 32 ---- .../studip/fragment/SettingsFragment.kt | 29 ++-- .../denizk0461/studip/model/CanteenOffer.kt | 23 +++ .../denizk0461/studip/model/StudIPEvent.kt | 2 +- .../studip/viewmodel/CanteenViewModel.kt | 18 +++ app/src/main/res/layout/fragment_event.xml | 11 -- app/src/main/res/values/colors.xml | 4 +- 15 files changed, 270 insertions(+), 89 deletions(-) create mode 100644 app/src/main/java/com/denizk0461/studip/data/StwParser.kt create mode 100644 app/src/main/java/com/denizk0461/studip/fragment/CanteenFragment.kt delete mode 100644 app/src/main/java/com/denizk0461/studip/fragment/FoodFragment.kt create mode 100644 app/src/main/java/com/denizk0461/studip/model/CanteenOffer.kt create mode 100644 app/src/main/java/com/denizk0461/studip/viewmodel/CanteenViewModel.kt diff --git a/app/src/main/java/com/denizk0461/studip/activity/MainActivity.kt b/app/src/main/java/com/denizk0461/studip/activity/MainActivity.kt index c9e1e32..614a04a 100644 --- a/app/src/main/java/com/denizk0461/studip/activity/MainActivity.kt +++ b/app/src/main/java/com/denizk0461/studip/activity/MainActivity.kt @@ -13,7 +13,7 @@ import com.denizk0461.studip.data.Dependencies import com.denizk0461.studip.databinding.ActivityMainBinding import com.denizk0461.studip.db.EventRepository import com.denizk0461.studip.fragment.EventFragment -import com.denizk0461.studip.fragment.FoodFragment +import com.denizk0461.studip.fragment.CanteenFragment import com.denizk0461.studip.fragment.SettingsFragment class MainActivity : AppCompatActivity() { @@ -21,7 +21,7 @@ class MainActivity : AppCompatActivity() { private lateinit var appBarConfiguration: AppBarConfiguration private lateinit var binding: ActivityMainBinding private var currentFragment = FragmentType.SCHEDULE - private val fragments = listOf(EventFragment(), FoodFragment(), SettingsFragment()) + private val fragments = listOf(EventFragment(), CanteenFragment(), SettingsFragment()) override fun onCreate(savedInstanceState: Bundle?) { WindowCompat.setDecorFitsSystemWindows(window, false) diff --git a/app/src/main/java/com/denizk0461/studip/adapter/StudIPEventAdapter.kt b/app/src/main/java/com/denizk0461/studip/adapter/StudIPEventAdapter.kt index 9772888..adecfb6 100644 --- a/app/src/main/java/com/denizk0461/studip/adapter/StudIPEventAdapter.kt +++ b/app/src/main/java/com/denizk0461/studip/adapter/StudIPEventAdapter.kt @@ -48,11 +48,11 @@ class StudIPEventAdapter( if (!isAnyCourseHighlighted && currentItem.isCurrentCourse(currentCalendar)) { // highlight isAnyCourseHighlighted = true holder.binding.cardBackground.strokeColor = colorPrimary.data - holder.binding.cardBackground.strokeWidth = 6 + holder.binding.cardBackground.strokeWidth = 6 // TODO replace this with proper float -> dp conversion // R.color.list_card_selected) } else { // un-highlight holder.binding.cardBackground.strokeColor = colorTextHint.data - holder.binding.cardBackground.strokeWidth = 3 + holder.binding.cardBackground.strokeWidth = 3 // this should (?) be 1dp } holder.binding.cardBackground.setOnClickListener { diff --git a/app/src/main/java/com/denizk0461/studip/data/StwParser.kt b/app/src/main/java/com/denizk0461/studip/data/StwParser.kt new file mode 100644 index 0000000..f05a8ed --- /dev/null +++ b/app/src/main/java/com/denizk0461/studip/data/StwParser.kt @@ -0,0 +1,144 @@ +package com.denizk0461.studip.data + +import android.util.Log +import com.denizk0461.studip.model.CanteenOffer +import org.jsoup.Jsoup +import org.jsoup.nodes.Element +import org.jsoup.select.Elements + +// Parser class for the Studierendenwerk cafeteria plans +class StwParser { + + private var id = 0 + + fun parse(onFinish: () -> Unit) { + id = 0 + val links = mutableListOf() + if (true) { links.add(urlUniMensa) } +// if (true) { links.add(urlCafeCentral) } +// if (true) { links.add(urlNW1) } +// if (true) { links.add(urlGW2) } +// if (true) { links.add(urlHSBNeustadt) } +// if (true) { links.add(urlHSBAirport) } +// if (true) { links.add(urlHSBWerder) } +// if (true) { links.add(urlHfK) } +// if (true) { links.add(urlMensaBHV) } +// if (true) { links.add(urlCafeBHV) } + + Dependencies.repo.nukeOffers() + + links.forEach { link -> + Dependencies.repo.insertOffers(parseFromPage(link)) + } + } + + private fun parseFromPage(url: String): List { + val items = mutableListOf() + var date = "" + var day = 0 + + val doc = Jsoup.connect(url).get() + doc.getElementsByClass("food-plan").forEach { dayPlan -> + + val rawDate = doc.getElementsByClass("tabs")[0] + .getElementsByClass("tab-date")[day].text().split(" ") + + date = "${rawDate[0]}${rawDate[1].monthToNumber()}." + day += 1 + + dayPlan.getElementsByClass("food-category").forEach { category -> + val categoryTitle = category.getElementsByClass("category-name")[0].text() + category + .getElementsByTag("tbody")[0] + .getElementsByTag("tr").forEach { element -> + val tableRows = element.getElementsByTag("td") + + val prefs = + element.getElementsByClass("field field-name-field-food-types")[0] + + val newItem = CanteenOffer( + id = id, + date = date, + category = categoryTitle, + title = tableRows[1].getFilteredText(), + price = tableRows.getTextOrEmpty(2), + isFair = prefs.isDietaryPreferenceMet(PREFERENCE_FAIR), + isFish = prefs.isDietaryPreferenceMet(PREFERENCE_FISH), + isPoultry = prefs.isDietaryPreferenceMet(PREFERENCE_POULTRY), + isLamb = prefs.isDietaryPreferenceMet(PREFERENCE_LAMB), + isVital = prefs.isDietaryPreferenceMet(PREFERENCE_VITAL), + isBeef = prefs.isDietaryPreferenceMet(PREFERENCE_BEEF), + isPork = prefs.isDietaryPreferenceMet(PREFERENCE_PORK), + isVegan = prefs.isDietaryPreferenceMet(PREFERENCE_VEGAN), + isVegetarian = prefs.isDietaryPreferenceMet(PREFERENCE_VEGETARIAN), + isGame = prefs.isDietaryPreferenceMet(PREFERENCE_GAME), + ) + items.add(newItem) + id += 1 + + Log.d("eek!", newItem.toString()) + } + } + } + + return items + } + + private fun Element.isDietaryPreferenceMet(preference: String): Boolean = + getElementsByAttributeValue("src", preference).isNotEmpty() + + private fun Element.getFilteredText(): String { + var text = html() + + while (text.contains("")) { + text = text.substring(0 until text.indexOf("")) + text.substring(text.indexOf("")+6 until text.length) + } + + return text + } + + private fun Elements.getTextOrEmpty(index: Int): String = try { + get(index).text() + } catch (e: java.lang.IndexOutOfBoundsException) { + "" + } + + private fun String.monthToNumber(): String = when (this) { + "Jan" -> "01" + "Feb" -> "02" + "Mar" -> "03" + "Apr" -> "04" + "Mai" -> "05" + "Jun" -> "06" + "Jul" -> "07" + "Aug" -> "08" + "Sep" -> "09" + "Okt" -> "10" + "Nov" -> "11" + "Dez" -> "12" + else -> "00" // shouldn't occur + } + + private val PREFERENCE_FAIR = "https://www.stw-bremen.de/sites/default/files/images/pictograms/at_small.png" + private val PREFERENCE_FISH = "https://www.stw-bremen.de/sites/default/files/images/pictograms/fisch.png" + private val PREFERENCE_POULTRY = "https://www.stw-bremen.de/sites/default/files/images/pictograms/geflugel.png" + private val PREFERENCE_LAMB = "https://www.stw-bremen.de/sites/default/files/images/pictograms/lamm.png" + private val PREFERENCE_VITAL = "https://www.stw-bremen.de/sites/default/files/images/pictograms/mensa_vital.png" + private val PREFERENCE_BEEF = "https://www.stw-bremen.de/sites/default/files/images/pictograms/rindfleisch.png" + private val PREFERENCE_PORK = "https://www.stw-bremen.de/sites/default/files/images/pictograms/schwein.png" + private val PREFERENCE_VEGAN = "https://www.stw-bremen.de/sites/default/files/images/pictograms/mensa_vegan.png" + private val PREFERENCE_VEGETARIAN = "https://www.stw-bremen.de/sites/default/files/images/pictograms/vegetarisch.png" + private val PREFERENCE_GAME = "https://www.stw-bremen.de/sites/default/files/images/pictograms/wild.png" + + private val urlUniMensa = "https://www.stw-bremen.de/de/mensa/uni-mensa" + private val urlCafeCentral = "https://www.stw-bremen.de/de/mensa/cafe-central" + private val urlNW1 = "https://www.stw-bremen.de/de/mensa/nw-1" + private val urlGW2 = "https://www.stw-bremen.de/de/cafeteria/gw2" +// private val urlGraz = "" + private val urlHSBNeustadt = "https://www.stw-bremen.de/de/mensa/neustadtswall" + private val urlHSBWerder = "https://www.stw-bremen.de/de/mensa/werderstra%C3%9Fe" + private val urlHSBAirport = "https://www.stw-bremen.de/de/mensa/airport" + private val urlHfK = "https://www.stw-bremen.de/de/mensa/interimsmensa-hfk" + private val urlMensaBHV = "https://www.stw-bremen.de/de/mensa/bremerhaven" + private val urlCafeBHV = "https://www.stw-bremen.de/de/cafeteria/bremerhaven" +} \ No newline at end of file diff --git a/app/src/main/java/com/denizk0461/studip/db/EventDAO.kt b/app/src/main/java/com/denizk0461/studip/db/EventDAO.kt index 7921ae3..4791011 100644 --- a/app/src/main/java/com/denizk0461/studip/db/EventDAO.kt +++ b/app/src/main/java/com/denizk0461/studip/db/EventDAO.kt @@ -4,6 +4,7 @@ import androidx.lifecycle.LiveData import androidx.room.Dao import androidx.room.Insert import androidx.room.Query +import com.denizk0461.studip.model.CanteenOffer import com.denizk0461.studip.model.StudIPEvent @Dao @@ -20,4 +21,13 @@ interface EventDAO { @Query("DELETE FROM events") fun nukeEvents() + + @get:Query("SELECT * FROM offers ORDER BY id") + val allOffers: LiveData> + + @Insert + fun insertOffers(offers: List) + + @Query("DELETE from offers") + fun nukeOffers() } \ No newline at end of file diff --git a/app/src/main/java/com/denizk0461/studip/db/EventDatabase.kt b/app/src/main/java/com/denizk0461/studip/db/EventDatabase.kt index d61bede..b4ffca6 100644 --- a/app/src/main/java/com/denizk0461/studip/db/EventDatabase.kt +++ b/app/src/main/java/com/denizk0461/studip/db/EventDatabase.kt @@ -4,9 +4,10 @@ import android.content.Context import androidx.room.Database import androidx.room.Room import androidx.room.RoomDatabase +import com.denizk0461.studip.model.CanteenOffer import com.denizk0461.studip.model.StudIPEvent -@Database(entities = [StudIPEvent::class], version = 3) +@Database(entities = [StudIPEvent::class, CanteenOffer::class], version = 6) abstract class EventDatabase : RoomDatabase() { abstract fun dao(): EventDAO diff --git a/app/src/main/java/com/denizk0461/studip/db/EventRepository.kt b/app/src/main/java/com/denizk0461/studip/db/EventRepository.kt index 1b70cd5..0e8ddf1 100644 --- a/app/src/main/java/com/denizk0461/studip/db/EventRepository.kt +++ b/app/src/main/java/com/denizk0461/studip/db/EventRepository.kt @@ -2,6 +2,7 @@ package com.denizk0461.studip.db import android.app.Application import androidx.lifecycle.LiveData +import com.denizk0461.studip.model.CanteenOffer import com.denizk0461.studip.model.StudIPEvent class EventRepository(app: Application) { @@ -10,7 +11,12 @@ class EventRepository(app: Application) { val allEvents: LiveData> = dao.allEvents - fun nukeEvents() { dao.nukeEvents() } fun insertEvent(event: StudIPEvent) { dao.insertEvent(event) } fun insertEvents(events: List) { dao.insertEvents(events) } + fun nukeEvents() { dao.nukeEvents() } + + val allOffers: LiveData> = dao.allOffers + + fun insertOffers(offers: List) { dao.insertOffers(offers) } + fun nukeOffers() { dao.nukeOffers() } } \ No newline at end of file diff --git a/app/src/main/java/com/denizk0461/studip/fragment/CanteenFragment.kt b/app/src/main/java/com/denizk0461/studip/fragment/CanteenFragment.kt new file mode 100644 index 0000000..162af04 --- /dev/null +++ b/app/src/main/java/com/denizk0461/studip/fragment/CanteenFragment.kt @@ -0,0 +1,46 @@ +package com.denizk0461.studip.fragment + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import androidx.fragment.app.viewModels +import com.denizk0461.studip.databinding.FragmentCanteenBinding +import com.denizk0461.studip.viewmodel.CanteenViewModel + +class CanteenFragment : Fragment() { + + private var _binding: FragmentCanteenBinding? = null + + // This property is only valid between onCreateView and + // onDestroyView. + private val binding get() = _binding!! + + private val viewModel: CanteenViewModel by viewModels() + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { + _binding = FragmentCanteenBinding.inflate(inflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + viewModel.allOffers.observe(viewLifecycleOwner) { offers -> + // TODO this must be changed. if an exception is raised, then this will not fire + binding.swipeRefreshLayout.isRefreshing = false + } + + binding.swipeRefreshLayout.setOnRefreshListener { + viewModel.fetchOffers { +// binding.swipeRefreshLayout.isRefreshing = false + } + } + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } +} \ No newline at end of file diff --git a/app/src/main/java/com/denizk0461/studip/fragment/EventFragment.kt b/app/src/main/java/com/denizk0461/studip/fragment/EventFragment.kt index c4499a1..c2face9 100644 --- a/app/src/main/java/com/denizk0461/studip/fragment/EventFragment.kt +++ b/app/src/main/java/com/denizk0461/studip/fragment/EventFragment.kt @@ -1,15 +1,12 @@ package com.denizk0461.studip.fragment -import android.content.Intent import android.os.Bundle import androidx.fragment.app.Fragment import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.viewModels -import androidx.navigation.fragment.NavHostFragment.Companion.findNavController import com.denizk0461.studip.R -import com.denizk0461.studip.activity.FetcherActivity import com.denizk0461.studip.adapter.StudIPEventAdapter import com.denizk0461.studip.adapter.StudIPEventPageAdapter import com.denizk0461.studip.databinding.FragmentEventBinding @@ -59,7 +56,7 @@ class EventFragment : Fragment() { viewPagerAdapter = StudIPEventPageAdapter(listOf(), object : StudIPEventAdapter.OnClickListener { override fun onClick(event: StudIPEvent) { - // do nothing + } override fun onLongClick(event: StudIPEvent) { @@ -76,10 +73,6 @@ class EventFragment : Fragment() { switchToCurrentDayView() } - binding.fab.setOnClickListener { view -> - launchWebview() - } - // binding.buttonFirst.setOnClickListener { // findNavController().navigate(R.id.action_FirstFragment_to_SecondFragment) // } @@ -99,16 +92,4 @@ class EventFragment : Fragment() { binding.viewPager.currentItem = dayOfWeek // binding.dayTabLayout.getTabAt(dayOfWeek)?.select() } - - private fun launchWebview() { -// findNavController(this).navigate(R.id.action_FirstFragment_to_SecondFragment) - startActivity(Intent(context, FetcherActivity::class.java)) - } - - /** - * Highlights the current or next course. - */ - private fun highlightCurrentCourse() { - - } } \ No newline at end of file diff --git a/app/src/main/java/com/denizk0461/studip/fragment/FoodFragment.kt b/app/src/main/java/com/denizk0461/studip/fragment/FoodFragment.kt deleted file mode 100644 index af44559..0000000 --- a/app/src/main/java/com/denizk0461/studip/fragment/FoodFragment.kt +++ /dev/null @@ -1,32 +0,0 @@ -package com.denizk0461.studip.fragment - -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import androidx.fragment.app.Fragment -import com.denizk0461.studip.databinding.FragmentFoodBinding - -class FoodFragment : Fragment() { - - private var _binding: FragmentFoodBinding? = null - - // This property is only valid between onCreateView and - // onDestroyView. - private val binding get() = _binding!! - - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { - _binding = FragmentFoodBinding.inflate(inflater, container, false) - return binding.root - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - } - - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } -} \ No newline at end of file diff --git a/app/src/main/java/com/denizk0461/studip/fragment/SettingsFragment.kt b/app/src/main/java/com/denizk0461/studip/fragment/SettingsFragment.kt index 2d189a3..e7a0453 100644 --- a/app/src/main/java/com/denizk0461/studip/fragment/SettingsFragment.kt +++ b/app/src/main/java/com/denizk0461/studip/fragment/SettingsFragment.kt @@ -1,8 +1,8 @@ package com.denizk0461.studip.fragment +import android.annotation.SuppressLint import android.content.Intent import android.net.Uri -import android.os.Build import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -10,6 +10,7 @@ import android.view.ViewGroup import android.widget.Toast import androidx.fragment.app.Fragment import com.denizk0461.studip.BuildConfig +import com.denizk0461.studip.activity.FetcherActivity import com.denizk0461.studip.data.Misc import com.denizk0461.studip.databinding.FragmentSettingsBinding @@ -31,15 +32,15 @@ class SettingsFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - var toast2 = makeToast("2") - var toast22 = makeToast("22") - var toast222 = makeToast("222") - // binding.layoutQuarter.setOnClickListener { // isQuarterChecked = !isQuarterChecked // binding.switchQuarter.isChecked = isQuarterChecked // } + binding.buttonRefreshSchedule.setOnClickListener { + launchWebView() + } + binding.switchQuarter.setOnClickListener { isQuarterChecked = !isQuarterChecked } @@ -47,24 +48,15 @@ class SettingsFragment : Fragment() { binding.buttonAppVersion.setOnClickListener { when (appVersionClick) { 19 -> { - toast2.show() appVersionClick += 1 } 20 -> { - toast2.cancel() - toast22.show() appVersionClick += 1 } 21 -> { - toast22.cancel() - toast222.show() appVersionClick += 1 } 22 -> { - toast222.cancel() - toast2 = makeToast("2") - toast22 = makeToast("22") - toast222 = makeToast("222") startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(Misc.mysteryLink))) appVersionClick = 0 } @@ -72,13 +64,16 @@ class SettingsFragment : Fragment() { } } - binding.appVersionText.text = BuildConfig.VERSION_NAME + @SuppressLint("SetTextI18n") + binding.appVersionText.text = "${BuildConfig.VERSION_NAME}-${if (BuildConfig.DEBUG) "debug" else "release"}" } - private fun makeToast(text: String): Toast = Toast.makeText(context, text, Toast.LENGTH_SHORT) - override fun onDestroyView() { super.onDestroyView() _binding = null } + + private fun launchWebView() { + startActivity(Intent(context, FetcherActivity::class.java)) + } } \ No newline at end of file diff --git a/app/src/main/java/com/denizk0461/studip/model/CanteenOffer.kt b/app/src/main/java/com/denizk0461/studip/model/CanteenOffer.kt new file mode 100644 index 0000000..4fdc7ae --- /dev/null +++ b/app/src/main/java/com/denizk0461/studip/model/CanteenOffer.kt @@ -0,0 +1,23 @@ +package com.denizk0461.studip.model + +import androidx.room.Entity +import androidx.room.PrimaryKey + +@Entity(tableName = "offers") +data class CanteenOffer( + @PrimaryKey val id: Int, + val date: String, + val category: String, + val title: String, + val price: String, // price for students + val isFair: Boolean, // artgerechte Tierhaltung + val isFish: Boolean, // Fisch + val isPoultry: Boolean, // Geflügel + val isLamb: Boolean, // Lamm + val isVital: Boolean, // mensaVital + val isBeef: Boolean, // Rindfleisch + val isPork: Boolean, // Schweinefleisch + val isVegan: Boolean, // plant-based (vegan) + val isVegetarian: Boolean, // vegetarisch + val isGame: Boolean, // Wild +) diff --git a/app/src/main/java/com/denizk0461/studip/model/StudIPEvent.kt b/app/src/main/java/com/denizk0461/studip/model/StudIPEvent.kt index 856ae0f..d6e8eb3 100644 --- a/app/src/main/java/com/denizk0461/studip/model/StudIPEvent.kt +++ b/app/src/main/java/com/denizk0461/studip/model/StudIPEvent.kt @@ -1,7 +1,6 @@ package com.denizk0461.studip.model import androidx.room.Entity -import androidx.room.Ignore import androidx.room.PrimaryKey @Entity(tableName = "events") @@ -13,6 +12,7 @@ data class StudIPEvent( val day: Int, // 0 = Monday, 1 = Tuesday, 2 = Wednesday, 3 = Thursday, 4 = Friday val timeslotStart: String, // the time the course starts val timeslotEnd: String, // the time the course ends + val colour: String = "000000", // user-defined colour, TODO implement this ) { // @Ignore private val timeSlotStartTimes: List = listOf("06:15", "08:15", "10:15", "12:15", "14:15", "16:15", "18:15", "20:15") diff --git a/app/src/main/java/com/denizk0461/studip/viewmodel/CanteenViewModel.kt b/app/src/main/java/com/denizk0461/studip/viewmodel/CanteenViewModel.kt new file mode 100644 index 0000000..18efe83 --- /dev/null +++ b/app/src/main/java/com/denizk0461/studip/viewmodel/CanteenViewModel.kt @@ -0,0 +1,18 @@ +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 + +class CanteenViewModel(app: Application) : TemplateViewModel(app) { + + private val parser = StwParser() + + val allOffers: LiveData> = repo.allOffers + + fun insertOffers(offers: List) { doAsync { repo.insertOffers(offers) }} + fun nukeOffers() { doAsync { repo.nukeOffers() }} + + fun fetchOffers(onFinish: () -> Unit) { doAsync { parser.parse(onFinish) }} +} \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_event.xml b/app/src/main/res/layout/fragment_event.xml index 95d450f..f593563 100644 --- a/app/src/main/res/layout/fragment_event.xml +++ b/app/src/main/res/layout/fragment_event.xml @@ -27,15 +27,4 @@ app:layout_constraintBottom_toBottomOf="parent"/> - - \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 1dd810e..d32aa58 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -17,8 +17,8 @@ #2A2828 #B9B6B6 - #3E3C3C - #918D8D + #AFACAC + #5E5A5A #EBEBEB #151414