AllergenConfigSheet.kt now updates SettingsFragment.kt to display the count of allergens the user has set; made changes to several strings and minor UI tweaks

This commit is contained in:
denizk0461
2023-05-10 18:43:06 +02:00
parent 4bd2919510
commit 9ada2ca462
16 changed files with 158 additions and 102 deletions
@@ -188,12 +188,12 @@ interface AppDAO {
@Insert fun insertItems(items: List<OfferItem>)
/**
* Retrieves the opening hours of the canteen as a string.
* Retrieves the canteen stored in the database. Should always be 0 or 1.
*
* @return opening hours
* @return canteen
*/
@Query("SELECT openingHours, news FROM offer_canteen LIMIT 1")
fun getCanteenInfo(): CanteenOfferTuple
@Query("SELECT * FROM offer_canteen LIMIT 1")
fun getCanteen(): LiveData<OfferCanteen>
/**
* Retrieve opening hours for the fetched canteen.
@@ -72,11 +72,11 @@ class AppRepository(app: Application) {
fun nukeEvents() { dao.nukeEvents() }
/**
* Retrieves the opening hours as well as notifications for the canteen as strings.
* Retrieves the canteen stored in the database. Should always be 0 or 1.
*
* @return opening hours and notifications
* @return canteen
*/
fun getCanteenInfo(): CanteenOfferTuple = dao.getCanteenInfo()
fun getCanteen(): LiveData<OfferCanteen> = dao.getCanteen()
/**
* Retrieve opening hours for the fetched canteen.
@@ -2,5 +2,4 @@ package com.denizk0461.weserplaner.exception
import java.io.IOException
class InvalidContentIdException : IOException() {
}
class InvalidContentIdException : IOException()
@@ -14,6 +14,8 @@ import com.denizk0461.weserplaner.data.showErrorSnackBar
import com.denizk0461.weserplaner.databinding.FragmentCanteenBinding
import com.denizk0461.weserplaner.model.*
import com.denizk0461.weserplaner.viewmodel.CanteenViewModel
import com.google.android.material.badge.BadgeDrawable
import com.google.android.material.badge.BadgeUtils
import com.google.android.material.tabs.TabLayoutMediator
/**
@@ -37,18 +39,6 @@ class CanteenFragment : AppFragment() {
// View model reference for providing access to the database
private val viewModel: CanteenViewModel by viewModels()
/**
* Locally saved opening hours to quickly access them without querying the database on every
* opening of the bottom sheet.
*/
// private var openingHours: String = ""
/**
* Locally saved news to quickly access them without querying the database on every opening of
* the corresponding bottom sheet.
*/
// private var news: String = ""
/**
* Locally stored dates to populate the TabLayout with.
*/
@@ -60,6 +50,7 @@ class CanteenFragment : AppFragment() {
return binding.root
}
@androidx.annotation.OptIn(com.google.android.material.badge.ExperimentalBadgeUtils::class)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
@@ -80,6 +71,12 @@ class CanteenFragment : AppFragment() {
))
}
// Create badge
val badge = BadgeDrawable.create(context)
badge.isVisible = true
// Attach badge to button
BadgeUtils.attachBadgeDrawable(badge, binding.buttonNotifications)
// Assign a preference value to every button to filter for dietary preferences
val chipMap = mapOf(
binding.chipPrefFair to DietaryPreferences.WELFARE,
@@ -170,7 +167,7 @@ class CanteenFragment : AppFragment() {
lifecycle,
)
// Date count is observed to correctly set the amount of pages and the corresponding tabs
// Date count is observed to correctly set multiple elements that depend on up-to-date data
viewModel.getDates().observe(viewLifecycleOwner) { newDates ->
// Retrieve the dates individually and store them for the tab mediator to use
@@ -180,17 +177,10 @@ class CanteenFragment : AppFragment() {
viewPagerAdapter.itemCount = dates.size
// Retrieve further information about this canteen from the database
viewModel.getCanteenInfo().also { info ->
/*
* Set visibility of the notifications icon depending on whether news are available.
* TODO change this to a BadgeDrawable later
*/
binding.buttonNotifications.visibility = if (info.news.isBlank()) {
View.GONE
} else {
View.VISIBLE
}
}
// viewModel.getCanteen().also { canteen ->
// Set visibility of the notifications icon depending on whether news are available
// badge.isVisible = info.news.isNotBlank()
// }
}
// Assign the adapter to the view pager
@@ -7,6 +7,7 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.setFragmentResultListener
import androidx.fragment.app.viewModels
import com.denizk0461.weserplaner.BuildConfig
import com.denizk0461.weserplaner.R
@@ -80,10 +81,22 @@ class SettingsFragment : AppFragment() {
// Set up button to set allergens
binding.buttonAllergensConfig.setOnClickListener {
openBottomSheet(
AllergenConfigSheet()
AllergenConfigSheet().also {
/*
* Receive fragment result to update the text view.
* TODO doesn't work after configuration change (change into or out of multi
* window)
*/
setFragmentResultListener("allergenConfig") { _, _ ->
// Update how many allergens the user set
binding.allergensConfigSubtitle.text = getAllergensConfigCountText()
}
}
)
}
binding.allergensConfigSubtitle.text = getAllergensConfigCountText()
// Set up switch for displaying allergens
binding.switchAllergens.apply {
isChecked = viewModel.preferenceAllergen
@@ -108,7 +121,10 @@ class SettingsFragment : AppFragment() {
}
}
// Set up switch for crash report opt-in
/*
* Set up switch for crash report opt-in, NOTE: currently not shown as Crashlytics is not
* implemented!
*/
binding.switchCrashlytics.apply {
isChecked = viewModel.preferenceDataHandling
setOnCheckedChangeListener { _, newValue ->
@@ -140,7 +156,6 @@ class SettingsFragment : AppFragment() {
binding.buttonLicences.setOnLongClickListener {
if (licencesLongClick > 3) {
openBottomSheet(DevCodeSheet())
licencesLongClick = 1
} else {
licencesLongClick += 1
}
@@ -166,14 +181,10 @@ class SettingsFragment : AppFragment() {
20 -> showToast(context, getString(R.string.settings_app_version_15))
35 -> showToast(context, getString(R.string.settings_app_version_20))
50 -> showToast(context, getString(R.string.settings_app_version_30))
90 -> showToast(context, getString(R.string.settings_app_version_90))
// 121 -> showToast(context, getString(R.string.settings_app_version_121))
165 -> showToast(context, getString(R.string.settings_app_version_165))
200 -> showToast(context, getString(R.string.settings_app_version_200))
222 -> {
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(mysteryLink)))
}
238 -> { // after 222 has been reached, this loops every 16 clicks
254 -> { // after 222 has been reached, this loops every 32 clicks
// Show the next cheesy wisdom
showToast(context, cheesyWisdoms[0])
@@ -228,4 +239,15 @@ class SettingsFragment : AppFragment() {
private fun launchWebView() {
startActivity(Intent(context, FetcherActivity::class.java))
}
/**
* Retrieves the text displayed in the allergen config setting to show the user how many
* allergens they have checked.
*
* @return localised string with the count of checked allergens inserted
*/
private fun getAllergensConfigCountText(): String = getString(
R.string.allergens_config_subtitle,
viewModel.preferenceAllergenConfigCount
)
}
@@ -2,6 +2,7 @@ package com.denizk0461.weserplaner.sheet
import android.os.Bundle
import android.view.View
import androidx.fragment.app.setFragmentResult
import androidx.fragment.app.viewModels
import com.denizk0461.weserplaner.R
import com.denizk0461.weserplaner.data.showToast
@@ -62,7 +63,20 @@ class AllergenConfigSheet : AppSheet(R.layout.sheet_allergen_config) {
// Set save button
binding.buttonSave.setOnClickListener {
// Save newly set preferences
saveAllergenPrefs()
/*
* Send an empty bundle to tell the parent fragment that it should update its view
* according to the changes made here.
*/
parentFragment?.setFragmentResult("allergenConfig", Bundle())
// Tell the user that saving was successful
showToast(context, getString(R.string.allergens_config_confirmation))
// Close the sheet
dismiss()
}
// Set up close button
@@ -73,7 +87,7 @@ class AllergenConfigSheet : AppSheet(R.layout.sheet_allergen_config) {
}
/**
* Saves the newly set preferences and closes the sheet.
* Saves the newly set preferences.
*/
private fun saveAllergenPrefs() {
@@ -108,11 +122,5 @@ class AllergenConfigSheet : AppSheet(R.layout.sheet_allergen_config) {
hasMolluscs = checkMolluscs.isChecked,
).deconstruct()
}
// Tell the user that saving was successful
showToast(context, getString(R.string.allergens_config_confirmation))
// Close the sheet
dismiss()
}
}
@@ -52,7 +52,7 @@ class DevCodeSheet : AppSheet(R.layout.sheet_dev_code) {
"QkJVT0s/".d64 -> launchLink("aHR0cHM6Ly95b3V0dS5iZS90Rm1PMm1TY0tHNA==".d64)
"SUhUU0Mq".d64 -> launchLink("aHR0cHM6Ly95b3V0dS5iZS85bXZ4SVdhWHZuWQ==".d64)
"SU5TQU5F".d64 -> launchLink("aHR0cHM6Ly95b3V0dS5iZS90NE9kYTlUZFYwbw==".d64)
"X0RSV05f".d64 -> launchLink("aHR0cHM6Ly95b3V0dS5iZS9SUVpUUy1CWjhtcw==".d64)
"SE9SSVpO".d64 -> launchLink("aHR0cHM6Ly95b3V0dS5iZS9SUVpUUy1CWjhtcw==".d64)
"TUFSR0Uh".d64 -> launchLink("aHR0cHM6Ly95b3V0dS5iZS8tbHFxRHZXRjQ1dw==".d64)
"UE9XRUxM".d64 -> launchLink("aHR0cHM6Ly95b3V0dS5iZS9XUGMtVkVxQlBISQ==".d64)
"Q0FMTE1F".d64 -> launchLink("aHR0cHM6Ly95b3V0dS5iZS8xbTV1WnJNMnktMA==".d64)
@@ -63,14 +63,14 @@ class DevCodeSheet : AppSheet(R.layout.sheet_dev_code) {
"Qk9KQUNL".d64 -> {
startActivity(Intent(context, ImageActivity::class.java).also { intent ->
val bundle = Bundle()
bundle.putString("img", "bojack")
bundle.putString("img", "Qk9KQUNL".d64.lowercase())
intent.putExtras(bundle)
})
}
"QkNFTExT".d64 -> {
startActivity(Intent(context, ImageActivity::class.java).also { intent ->
val bundle = Bundle()
bundle.putString("img", "bcells")
bundle.putString("img", "QkNFTExT".d64.lowercase())
intent.putExtras(bundle)
})
}
@@ -6,7 +6,6 @@ import androidx.fragment.app.viewModels
import com.denizk0461.weserplaner.R
import com.denizk0461.weserplaner.data.viewBinding
import com.denizk0461.weserplaner.databinding.SheetTextBinding
import com.denizk0461.weserplaner.exception.InvalidContentIdException
import com.denizk0461.weserplaner.model.TextSheetContentId
import com.denizk0461.weserplaner.viewmodel.TextSheetViewModel
@@ -42,25 +41,43 @@ class TextSheet : AppSheet(R.layout.sheet_text) {
// Set whether the sheet should be cancellable by actions such as swiping
val isSheetCancellable = arguments?.getBoolean("isCancellable") == true
/*
* Set text header.
* TODO update this when contentId is set and canteen could change while the sheet is open!
*/
binding.textHeader.text = header
// Set content to raw string passed if ID says so
// Set text views to raw string passed if ID says so
if (contentId == -1) {
binding.textHeader.text = header
binding.textContent.text = content
} else (when (contentId) {
// Observe LiveData if corresponding ID has been passed
TextSheetContentId.OPENING_HOURS -> viewModel.getCanteenOpeningHours()
TextSheetContentId.NEWS -> viewModel.getCanteenNews()
else -> throw InvalidContentIdException()
}).observe(viewLifecycleOwner) { observedContent ->
// Show the content
binding.textContent.text = (observedContent ?: "")
// If the content is empty, tell the user
.ifBlank { emptyContentStringFor(contentId) }
// } else (when (contentId) {
// // Observe LiveData if corresponding ID has been passed
// TextSheetContentId.OPENING_HOURS -> viewModel.getCanteen()
// TextSheetContentId.NEWS -> viewModel.getCanteen()
// else -> throw InvalidContentIdException()
// }).observe(viewLifecycleOwner) { observedContent ->
// // Show the content
// binding.textContent.text = (observedContent ?: "")
// // If the content is empty, tell the user
// .ifBlank { emptyContentStringFor(contentId) }
// }
} else {
viewModel.getCanteen().observe(viewLifecycleOwner) { canteen ->
when (contentId) {
TextSheetContentId.OPENING_HOURS -> {
binding.textHeader.text = getString(
R.string.text_sheet_opening_hours_title, canteen.canteen
)
binding.textContent.text = canteen.openingHours.ifBlank {
getString(R.string.text_sheet_opening_hours_empty)
}
}
TextSheetContentId.NEWS -> {
binding.textHeader.text = getString(
R.string.text_sheet_news_title, canteen.canteen
)
binding.textContent.text = canteen.news.ifBlank {
getString(R.string.text_sheet_news_empty)
}
}
else -> {} // should not occur
}
}
}
// Set up an appropriate close button depending on whether the sheet is cancellable
@@ -84,8 +101,8 @@ class TextSheet : AppSheet(R.layout.sheet_text) {
* @return localised string to show the user
*/
private fun emptyContentStringFor(contentId: Int) = getString(when (contentId) {
TextSheetContentId.OPENING_HOURS -> R.string.text_sheet_empty_opening_hours
TextSheetContentId.NEWS -> R.string.text_sheet_empty_news
TextSheetContentId.OPENING_HOURS -> R.string.text_sheet_opening_hours_empty
TextSheetContentId.NEWS -> R.string.text_sheet_news_empty
else -> R.string.error_generic
})
}
@@ -25,13 +25,6 @@ class CanteenViewModel(app: Application) : AppViewModel(app) {
*/
fun getDates(): LiveData<List<OfferDate>> = repo.getDates()
/**
* Retrieves the opening hours as well as notifications for the canteen as strings.
*
* @return opening hours and notifications
*/
fun getCanteenInfo(): CanteenOfferTuple = returnBlocking { repo.getCanteenInfo() }
/**
* Fetch the canteen offers asynchronously. Updates will be provided through a LiveData object.
*
@@ -1,6 +1,7 @@
package com.denizk0461.weserplaner.viewmodel
import android.app.Application
import com.denizk0461.weserplaner.model.AllergenPreferences
import com.denizk0461.weserplaner.model.SettingsPreferences
/**
@@ -38,6 +39,16 @@ class SettingsViewModel(app: Application) : AppViewModel(app) {
get() = repo.getBooleanPreference(SettingsPreferences.ALLERGEN, defaultValue = true)
set(newValue) { repo.setPreference(SettingsPreferences.ALLERGEN, newValue) }
/**
* This value determines how many allergens the user wants to have displayed or hidden.
*/
val preferenceAllergenConfigCount: Int
get() = repo.getStringPreference(
SettingsPreferences.ALLERGEN_CONFIG, defaultValue = AllergenPreferences.TEMPLATE
).run {
if (isBlank()) 0 else split(",").count()
}
/**
* This value determines whether the user wants the app to launch with the canteen view.
*/
@@ -2,9 +2,17 @@ package com.denizk0461.weserplaner.viewmodel
import android.app.Application
import androidx.lifecycle.LiveData
import com.denizk0461.weserplaner.model.OfferCanteen
class TextSheetViewModel(application: Application) : AppViewModel(application) {
/**
* Retrieves the canteen stored in the database.
*
* @return canteen
*/
fun getCanteen(): LiveData<OfferCanteen> = repo.getCanteen()
/**
* Retrieve opening hours for the fetched canteen.
* Used when contentId = [com.denizk0461.weserplaner.model.TextSheetContentId.OPENING_HOURS]
+16 -5
View File
@@ -55,8 +55,7 @@
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:iconTint="?attr/colorOnSurfaceVariant"
android:visibility="gone"/>
app:iconTint="?attr/colorOnSurfaceVariant"/>
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -225,10 +224,22 @@
android:layout_gravity="fill_vertical"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/view_pager"
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="match_parent"/>
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TEST TEST TEST TEST ABC 123 !!!"/>
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
+3 -1
View File
@@ -43,11 +43,13 @@
android:id="@+id/fab_add_event"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="@drawable/plus"
android:src="@drawable/plus"
android:contentDescription="@string/sheet_schedule_update_header_add"
android:tooltipText="@string/sheet_schedule_update_header_add"
android:layout_gravity="bottom|end"
android:layout_marginEnd="@dimen/fab_margin"
android:layout_marginBottom="@dimen/fab_margin"
tools:ignore="UnusedAttribute"
app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
@@ -236,9 +236,9 @@
android:textSize="16sp" />
<TextView
android:id="@+id/allergens_config_subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/allergens_config_subtitle"
android:textSize="16sp" />
</androidx.appcompat.widget.LinearLayoutCompat>
+6 -6
View File
@@ -1,7 +1,5 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- <string name="app_name">sixminutes</string>-->
<string name="toast_first_launch">Hey, danke, dass Du meine App ausprobierst! ~Deniz</string>
<string name="error_generic">Ein Fehler ist aufgetreten.</string>
<string name="monday">Montag</string>
@@ -70,8 +68,10 @@
<string name="canteen_fab_refresh_content_desc">Aktualisiere Angebote</string>
<!-- TODO replace 'this canteen' with %s -->
<string name="text_sheet_empty_opening_hours">The Öffnungszeiten für diese Mensa können nicht angezeigt werden.</string>
<string name="text_sheet_empty_news">Es sind keine Neuigkeiten verfügbar.</string>
<string name="text_sheet_opening_hours_title">%s Öffnungszeiten</string>
<string name="text_sheet_opening_hours_empty">The Öffnungszeiten können nicht angezeigt werden.</string>
<string name="text_sheet_news_title">%s Neuigkeiten</string>
<string name="text_sheet_news_empty">Es sind keine Neuigkeiten verfügbar.</string>
<string name="sheet_licences_header">Lizenzen</string>
@@ -173,7 +173,7 @@
<string name="settings_highlight_subtitle">Funktioniert nur, wenn Kurse sich nicht überschneiden!</string>
<string name="allergens_config_title">Verstecke Angebote mit bestimmten Allergenen</string>
<string name="allergens_config_subtitle">Angebote mit ausgeschlossenen Allergenen werden Dir nicht angezeigt</string>
<string name="allergens_config_subtitle">Allergene, die Du ausgeschlossen hast: %d</string>
<string name="allergens_config_header">Wähle, welche Allergene Du vermeiden möchtest</string>
<string name="allergens_config_content">Achtung: bitte verlasse Dich nicht vollständig auf diese Funktion. Stelle immer in der Mensa, die Du besuchst, sicher, dass die Stoffe, auf die Du allergisch reagierst, nicht in deren Angeboten vorhanden sind. Die Allergen-Hinweise einiger Mensen sind online leider unvollständig.</string>
<string name="allergens_config_confirmation">Deine Allergene wurden gespeichert.</string>
@@ -187,6 +187,7 @@
<string name="settings_pref_colour_title">Färbe Diätpreferenzen</string>
<string name="settings_pref_colour_subtitle">Dies färbt die kleinen Symbole ähnlich wie auf der Webseite</string>
<!-- unused - use for possible future implementation of Crashlytics -->
<string name="settings_crashlytics_title">Stimme Sammlung von Absturzreporten zu</string>
<string name="settings_crashlytics_subtitle">Daten werden anonymisiert übertragen</string> <!-- TODO is this true? -->
@@ -204,5 +205,4 @@
<string name="settings_app_version">App-Version</string>
<string name="settings_app_version_15">klick weiter</string>
<string name="settings_app_version_121">Solltest du nicht für deine Klausuren lernen?</string>
</resources>
+6 -11
View File
@@ -1,7 +1,6 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name" translatable="false">WeserPlaner</string>
<string name="toast_first_launch">Hey, thank you for trying out my app! ~Deniz</string>
<string name="error_generic">An error occurred.</string>
<string name="monday">Monday</string>
@@ -70,9 +69,10 @@
<string name="canteen_fab_switch_canteen_content_desc">Switch canteen</string>
<string name="canteen_fab_refresh_content_desc">Refresh offers</string>
<!-- TODO replace 'this canteen' with %s -->
<string name="text_sheet_empty_opening_hours">The opening hours for this canteen could not be downloaded.</string>
<string name="text_sheet_empty_news">No news are available.</string>
<string name="text_sheet_opening_hours_title">%s opening hours</string>
<string name="text_sheet_opening_hours_empty">The opening hours could not be downloaded.</string>
<string name="text_sheet_news_title">%s news</string>
<string name="text_sheet_news_empty">No news are available.</string>
<string name="sheet_licences_header">Licences</string>
<string name="sheet_licences_content" translatable="false">Android developer resources by Google.\nhttps://developer.android.com/\nandroidx.appcompat:appcompat:1.6.1\nandroidx.constraintlayout:constraintlayout:2.1.4\nandroidx.core:core-ktx:1.10.0\nandroidx.fragment:fragment-ktx:1.6.0-beta01\nandroidx.navigation:navigation-fragment-ktx:2.5.3\nandroidx.navigation:navigation-ui-ktx:2.5.3\nandroidx.preference:preference-ktx:1.2.0\nandroidx.room:room-runtime:2.5.1\nandroidx.room:room-compiler:2.5.1\nandroidx.swiperefreshlayout:swiperefreshlayout:1.2.0-alpha01\n\nDesign guidelines, icons, and colour palette by Google.\nhttps://m3.material.io/\ncom.google.android.material:material:1.9.0\n\nAdditional icons by Flaticon.\nhttps://www.flaticon.com/\n\nWeb scraping functionality by Jonathan Hedley.\nhttps://jhy.io/\nhttps://jsoup.org/\norg.jsoup:jsoup:1.15.4\n\nApp developed by Deniz Düzgören.\ndenizk0461@gmail.com\ndeniz7@uni-bremen.de</string>
@@ -177,7 +177,7 @@
<string name="settings_highlight_subtitle">Only works properly if courses don\'t overlap!</string>
<string name="allergens_config_title">Hide offers containing certain allergens</string>
<string name="allergens_config_subtitle">Offers with excluded allergens won\'t be shown to you</string>
<string name="allergens_config_subtitle">Allergens you\'ve excluded: %d</string>
<string name="allergens_config_header">Select which allergens you\'d like to avoid</string>
<string name="allergens_config_content">Note: please don\'t entirely rely on this. Always check the notices displayed at the canteen you\'re visiting to confirm substances you may be allergic against are not present in their offerings. Some canteens unfortunately don\'t provide full allergen information online.</string>
<string name="allergens_config_confirmation">Your allergen settings have been saved.</string>
@@ -191,6 +191,7 @@
<string name="settings_launch_canteen_title">Show canteen plan on app launch</string>
<string name="settings_launch_canteen_subtitle">Otherwise your schedule will be shown at launch</string>
<!-- unused - use for possible future implementation of Crashlytics -->
<string name="settings_crashlytics_title">Opt-in to sharing crash data</string>
<string name="settings_crashlytics_subtitle">Data will be anonymised</string> <!-- TODO is this true? -->
@@ -212,10 +213,6 @@
<string name="settings_app_version_15">keep clicking</string>
<string name="settings_app_version_20" translatable="false">^_^</string>
<string name="settings_app_version_30" translatable="false">^_____^</string>
<string name="settings_app_version_90" translatable="false">(⎌ℕ⎌)</string>
<string name="settings_app_version_121">Shouldn\'t you study for your exams?</string>
<string name="settings_app_version_165" translatable="false">◢◤</string>
<string name="settings_app_version_200" translatable="false">\\__*</string>
<string-array name="cheesy_wisdoms" translatable="false">
<item>can\'t go back in time, every second is a new one</item>
@@ -224,7 +221,5 @@
<item>trans rights are human rights 🏳️‍⚧️</item>
<item>i wouldn\'t risk any more than six minutes</item>
<item>do you remember yesterday?</item>
<item>look at the sky, i\'m still here</item>
<item>sample text</item>
</string-array>
</resources>